diff --git a/.vscodeignore b/.vscodeignore index 9c5710d..e0a13e7 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -3,12 +3,15 @@ out/test/** src/** +wasm/** .gitignore +.gitmodules .yarnrc vsc-extension-quickstart.md **/tsconfig.json **/.eslintrc.json **/*.map **/*.ts +**/*.bat data_converter/ diff --git a/data_converter/Cargo.lock b/data_converter/Cargo.lock index 798c49e..223070d 100644 --- a/data_converter/Cargo.lock +++ b/data_converter/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" version = "0.7.18" @@ -9,15 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi", -] - [[package]] name = "ansi_term" version = "0.12.1" @@ -28,26 +21,12 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.45" +name = "approx" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee10e43ae4a853c0a3591d4e2ada1719e553be18199d9da9d4a83f5927c2f5c7" - -[[package]] -name = "arc-swap" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "num-traits", ] [[package]] @@ -57,27 +36,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] -name = "bitflags" -version = "1.3.2" +name = "bstr" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bugsalot" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e72f9bbbefc608feee4a289367db48d780470138f53586b210ca5e35fafc49a" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ - "js-sys", - "wasm-bindgen", + "lazy_static", + "memchr", + "regex-automata", + "serde", ] -[[package]] -name = "bumpalo" -version = "3.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" - [[package]] name = "cfg-if" version = "1.0.0" @@ -85,65 +54,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "chrono" -version = "0.4.19" +name = "csv" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi", + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", ] [[package]] -name = "clap" -version = "2.33.3" +name = "csv-core" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" dependencies = [ - "ansi_term 0.11.0", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", + "memchr", ] [[package]] name = "data_converter" version = "0.1.0" dependencies = [ - "seedgen", "serde", "serde_json", + "wotw_seedgen", ] [[package]] -name = "derivative" -version = "2.2.0" +name = "decorum" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +checksum = "281759d3c8a14f5c3f0c49363be56810fcd7f910422f97f2db850c2920fde5cf" dependencies = [ - "proc-macro2", - "quote", - "syn", + "approx", + "num-traits", + "serde", + "serde_derive", ] -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "getrandom" version = "0.2.3" @@ -155,70 +107,12 @@ dependencies = [ "wasi", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - [[package]] name = "itoa" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" -[[package]] -name = "js-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" -dependencies = [ - "wasm-bindgen", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -231,21 +125,6 @@ version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "lock_api" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" -dependencies = [ - "scopeguard", -] - [[package]] name = "log" version = "0.4.14" @@ -253,40 +132,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ "cfg-if", - "serde", -] - -[[package]] -name = "log-mdc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" - -[[package]] -name = "log4rs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1572a880d1115ff867396eee7ae2bc924554225e67a0d3c85c745b3e60ca211" -dependencies = [ - "anyhow", - "arc-swap", - "chrono", - "derivative", - "fnv", - "humantime", - "libc", - "log", - "log-mdc", - "parking_lot", - "regex", - "serde", - "serde-value", - "serde_json", - "serde_yaml", - "thiserror", - "thread-id", - "typemap", - "winapi", ] [[package]] @@ -295,16 +140,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.14" @@ -315,55 +150,26 @@ dependencies = [ ] [[package]] -name = "open" -version = "1.7.1" +name = "num_enum" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcea7a30d6b81a2423cc59c43554880feff7b57d12916f231a79f8d6d9470201" +checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" dependencies = [ - "pathdiff", - "winapi", + "num_enum_derive", ] [[package]] -name = "ordered-float" -version = "2.8.0" +name = "num_enum_derive" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97c9d06878b3a851e8026ef94bf7fef9ba93062cd412601da4d9cf369b1cc62d" +checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" dependencies = [ - "num-traits", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.10", - "smallvec", - "winapi", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", ] -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - [[package]] name = "ppv-lite86" version = "0.2.15" @@ -371,27 +177,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" [[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "proc-macro-crate" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "proc-macro2", - "quote", - "version_check", + "thiserror", + "toml", ] [[package]] @@ -461,21 +253,6 @@ dependencies = [ "rand_core", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" version = "1.5.4" @@ -487,6 +264,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + [[package]] name = "regex-syntax" version = "0.6.25" @@ -505,33 +288,6 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "seedgen" -version = "1.0.10" -source = "git+https://github.com/ori-rando/wotw-seedgen?branch=main#10b58c1af9fc2c3623e3ad325c75b1f6c963b9f0" -dependencies = [ - "ansi_term 0.12.1", - "atty", - "bugsalot", - "log", - "log4rs", - "open", - "rand", - "rand_seeder", - "regex", - "rustc-hash", - "serde", - "serde_json", - "smallvec", - "structopt", -] - [[package]] name = "serde" version = "1.0.130" @@ -541,16 +297,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" -dependencies = [ - "ordered-float", - "serde", -] - [[package]] name = "serde_derive" version = "1.0.130" @@ -573,54 +319,12 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_yaml" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af" -dependencies = [ - "dtoa", - "indexmap", - "serde", - "yaml-rust", -] - [[package]] name = "smallvec" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "syn" version = "1.0.81" @@ -632,15 +336,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - [[package]] name = "thiserror" version = "1.0.30" @@ -662,140 +357,26 @@ dependencies = [ ] [[package]] -name = "thread-id" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" -dependencies = [ - "libc", - "redox_syscall 0.1.57", - "winapi", -] - -[[package]] -name = "time" -version = "0.1.43" +name = "toml" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "traitobject" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" - -[[package]] -name = "typemap" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" -dependencies = [ - "unsafe-any", + "serde", ] -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - [[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" -[[package]] -name = "unsafe-any" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" -dependencies = [ - "traitobject", -] - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" -[[package]] -name = "wasm-bindgen" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" - [[package]] name = "winapi" version = "0.3.9" @@ -819,10 +400,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "yaml-rust" -version = "0.4.5" +name = "wotw_seedgen" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf488c222b8db144e0aa47ef34bfd4280442b58eb9d61ec1502d849c0b7e6c8" +dependencies = [ + "ansi_term", + "csv", + "decorum", + "log", + "num_enum", + "rand", + "rand_seeder", + "regex", + "rustc-hash", + "serde", + "serde_json", + "smallvec", + "syn", + "wotw_seedgen_derive", +] + +[[package]] +name = "wotw_seedgen_derive" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +checksum = "e5d034ef0e15a4d6e99b3b02a5c5d94b1e0a6da62b3d9c29638ead1040fd3357" dependencies = [ - "linked-hash-map", + "quote", + "syn", ] diff --git a/data_converter/Cargo.toml b/data_converter/Cargo.toml index 7f45844..74aa645 100644 --- a/data_converter/Cargo.toml +++ b/data_converter/Cargo.toml @@ -9,4 +9,4 @@ edition = "2018" [dependencies] serde = "1" serde_json = "1" -seedgen = { git = "https://github.com/ori-rando/wotw-seedgen", branch = "main" } +wotw_seedgen = "0.1.2" diff --git a/data_converter/src/main.rs b/data_converter/src/main.rs index 8c94103..641a096 100644 --- a/data_converter/src/main.rs +++ b/data_converter/src/main.rs @@ -1,6 +1,6 @@ use std::{fs, path::PathBuf}; use serde::Serialize; -use seedgen::{lexer::parser, util::UberState}; +use wotw_seedgen::{lexer::parser, util::UberState}; #[derive(Serialize)] #[serde(rename_all = "camelCase")] diff --git a/language-configuration.json b/language-configuration.json index 0d834f8..d1ac939 100644 --- a/language-configuration.json +++ b/language-configuration.json @@ -10,6 +10,13 @@ "autoClosingPairs": [ { "open": "{", "close": "}" }, { "open": "[", "close": "]" }, - { "open": "(", "close": ")" } + { "open": "(", "close": ")" }, + { "open": "\"", "close": "\"", "notIn": ["string"] } + ], + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""] ] } diff --git a/package-lock.json b/package-lock.json index 8e84a98..0160c42 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,1432 @@ { "name": "header-language", - "version": "0.0.1", - "lockfileVersion": 1, + "version": "0.5.0", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "header-language", + "version": "0.5.0", + "license": "MIT", + "dependencies": { + "wotw-seedgen": "file:./wasm/pkg" + }, + "devDependencies": { + "@types/glob": "^7.1.3", + "@types/node": "14.x", + "@types/vscode": "^1.60.0", + "@typescript-eslint/eslint-plugin": "^4.26.0", + "@typescript-eslint/parser": "^4.26.0", + "eslint": "^7.27.0", + "glob": "^7.1.7", + "typescript": "^4.3.2" + }, + "engines": { + "vscode": "^1.60.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "node_modules/@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "14.17.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.18.tgz", + "integrity": "sha512-haYyibw4pbteEhkSg0xdDLAI3679L75EJ799ymVrPxOA922bPx3ML59SoDsQ//rHlvqpu+e36kcbR3XRQtFblA==", + "dev": true + }, + "node_modules/@types/vscode": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.60.0.tgz", + "integrity": "sha512-wZt3VTmzYrgZ0l/3QmEbCq4KAJ71K3/hmMQ/nfpv84oH8e81KKwPEoQ5v8dNCxfHFVJ1JabHKmCvqdYOoVm1Ow==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.2.tgz", + "integrity": "sha512-w63SCQ4bIwWN/+3FxzpnWrDjQRXVEGiTt9tJTRptRXeFvdZc/wLiz3FQUwNQ2CVoRGI6KUWMNUj/pk63noUfcA==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.31.2", + "@typescript-eslint/scope-manager": "4.31.2", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.2.tgz", + "integrity": "sha512-3tm2T4nyA970yQ6R3JZV9l0yilE2FedYg8dcXrTar34zC9r6JB7WyBQbpIVongKPlhEMjhQ01qkwrzWy38Bk1Q==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.31.2", + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/typescript-estree": "4.31.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.2.tgz", + "integrity": "sha512-EcdO0E7M/sv23S/rLvenHkb58l3XhuSZzKf6DBvLgHqOYdL6YFMYVtreGFWirxaU2mS1GYDby3Lyxco7X5+Vjw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.31.2", + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/typescript-estree": "4.31.2", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.2.tgz", + "integrity": "sha512-2JGwudpFoR/3Czq6mPpE8zBPYdHWFGL6lUNIGolbKQeSNv4EAiHaR5GVDQaLA0FwgcdcMtRk+SBJbFGL7+La5w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.2.tgz", + "integrity": "sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.2.tgz", + "integrity": "sha512-ieBq8U9at6PvaC7/Z6oe8D3czeW5d//Fo1xkF/s9394VR0bg/UaMYPdARiWyKX+lLEjY3w/FNZJxitMsiWv+wA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.2.tgz", + "integrity": "sha512-PrBId7EQq2Nibns7dd/ch6S6/M4/iwLM9McbgeEbCXfxdwRUNxJ4UNreJ6Gh3fI2GNKNrWnQxKL7oCPmngKBug==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "eslint-visitor-keys": "^2.0.0" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "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.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "node_modules/eslint/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "node_modules/flatted": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + } + }, + "node_modules/globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + } + }, + "node_modules/table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "node_modules/typescript": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "node_modules/wotw-seedgen": { + "resolved": "wasm/pkg", + "link": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "wasm/pkg": { + "name": "wasm", + "version": "0.1.0" + } + }, "dependencies": { "@babel/code-frame": { "version": "7.12.11", @@ -1292,6 +2716,9 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wotw-seedgen": { + "version": "file:wasm/pkg" + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 06a69f9..ce13548 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "header-language", "displayName": "Ori WotW Header Language", "description": "Support for the .wotwrh language", - "version": "0.4.5", + "version": "0.5.0", "publisher": "orirando", "license": "MIT", "repository": { @@ -45,10 +45,14 @@ }, "scripts": { "vscode:prepublish": "npm run compile", - "compile": "tsc -p ./", - "watch": "tsc -watch -p ./", + "compile": "npm run build-wasm && tsc -p ./", + "watch": "npm run build-wasm && tsc -watch -p ./", + "build-wasm": "wasm-pack build --release --target nodejs wasm", "lint": "eslint src --ext ts" }, + "dependencies": { + "wotw-seedgen": "file:./wasm/pkg" + }, "devDependencies": { "@types/vscode": "^1.60.0", "@types/glob": "^7.1.3", diff --git a/src/command.ts b/src/command.ts deleted file mode 100644 index 1500204..0000000 --- a/src/command.ts +++ /dev/null @@ -1,95 +0,0 @@ -import Icon from "./icon"; -import { Item } from "./item"; -import { Parameter } from "./parser"; - -export enum CommandVariant { - include, - exclude, - add, - remove, - name, - display, - description, - price, - icon, - parameter, - pool, - addpool, - flush, - set, - if, - endif, -} - -export interface IncludeCommand { - id: CommandVariant.include, - path: string, -} -export interface ExcludeCommand { - id: CommandVariant.exclude, - path: string, -} -export interface AddCommand { - id: CommandVariant.add, - amount: number, - item: Item, -} -export interface RemoveCommand { - id: CommandVariant.remove, - amount: number, - item: Item, -} -export interface NameCommand { - id: CommandVariant.name, - item: Item, - name: string, -} -export interface DisplayCommand { - id: CommandVariant.display, - item: Item, - display: string, -} -export interface DescriptionCommand { - id: CommandVariant.description, - item: Item, - description: string, -} -export interface PriceCommand { - id: CommandVariant.price, - item: Item, - price: number, -} -export interface IconCommand { - id: CommandVariant.icon, - item: Item, - icon: Icon, -} -export interface ParameterCommand { - id: CommandVariant.parameter, - parameter: Parameter, -} -export interface PoolCommand { - id: CommandVariant.pool, - poolItem: string, -} -export interface AddPoolCommand { - id: CommandVariant.addpool, - amount: number, -} -export interface FlushCommand { - id: CommandVariant.flush, -} -export interface SetCommand { - id: CommandVariant.set, - state: string, -} -export interface IfCommand { - id: CommandVariant.if, - parameterId: string, - value: boolean | number | string, -} -export interface EndIfCommand { - id: CommandVariant.endif, -} - -export type Command = IncludeCommand | ExcludeCommand | AddCommand | RemoveCommand | NameCommand | DisplayCommand | DescriptionCommand | PriceCommand | IconCommand | ParameterCommand | PoolCommand | AddPoolCommand | FlushCommand | SetCommand | IfCommand | EndIfCommand; diff --git a/src/completion.ts b/src/completion.ts index 4dcf2c0..a0fbdb4 100644 --- a/src/completion.ts +++ b/src/completion.ts @@ -1,9 +1,9 @@ +import * as vscode from "vscode"; import { CompletionItem } from "vscode"; import booleanCompletions from "./completion/booleanCompletion"; import iconTypeCompletions from "./completion/iconTypeCompletion"; import keybindCompletions from "./completion/keybindCompletions"; import messageFlagCompletions from "./completion/messageFlagCompletion"; -import slotCompletions from "./completion/slotCompletion"; import { uberIdCompletions, uberStateCompletions } from "./completion/uberStateCompletion"; import uberTypeCompletions from "./completion/uberTypeCompletion"; import waterCompletions from "./completion/waterCompletion"; @@ -19,7 +19,6 @@ import { AbilityVariant } from "./item/ability"; import { BonusItemVariant } from "./item/bonusItem"; import { BonusUpgradeVariant } from "./item/bonusUpgrade"; import { SysCommandVariant } from "./item/sysCommand"; -import { Message } from "./item/message"; import { ProgressVariant } from "./item/progressMessage"; import { ResourceVariant } from "./item/resource"; import { ShardVariant } from "./item/shard"; @@ -33,183 +32,66 @@ import parameterTypeCompletions from "./completion/parameterTypeCompletion"; import { ItemVariant } from "./item"; import { AnnotationVariant } from "./annotation"; import { FlagVariant } from "./flag"; +import { ParseError } from "wotw-seedgen"; +import { Slot } from "./item/slot"; +import { NumericBoolean } from "./item/numericBoolean"; +import { ToggleCommand } from "./item/toggleCommand"; +import { WheelPosition } from "./item/wheelPosition"; +import InterpolationCommand from "./interpolationCommand"; -export enum CompletionVariant { - uberState, - uberId, - boolean, - item, - resource, - ability, - shard, - sysCommand, - slot, - equipment, - keybind, - teleporter, - messageFlag, - uberStateType, - water, - bonusItem, - bonusUpgrade, - zone, - progressMessage, - wheelCommand, - iconType, - shardIconValue, - spellIconValue, - opherIconValue, - lupoIconValue, - gromIconValue, - tuleyIconValue, - wheelItemBind, - shopCommand, - command, - parameterType, - annotation, - flag, -} - -interface UberState { - id: CompletionVariant.uberState, -} -interface UberId { - id: CompletionVariant.uberId, - group: number, -} -interface Boolean { - id: CompletionVariant.boolean, -} -interface Item { - id: CompletionVariant.item, -} -interface Resource { - id: CompletionVariant.resource, -} -interface Ability { - id: CompletionVariant.ability, -} -interface Shard { - id: CompletionVariant.shard, -} -interface SysCommand { - id: CompletionVariant.sysCommand, -} -interface Slot { - id: CompletionVariant.slot, -} -interface Equipment { - id: CompletionVariant.equipment, -} -interface Keybind { - id: CompletionVariant.keybind, -} -interface Teleporter { - id: CompletionVariant.teleporter, -} -interface MessageFlag { - id: CompletionVariant.messageFlag, - message: Message, -} -interface UberStateType { - id: CompletionVariant.uberStateType, -} -interface Water { - id: CompletionVariant.water, -} -interface BonusItem { - id: CompletionVariant.bonusItem, -} -interface BonusUpgrade { - id: CompletionVariant.bonusUpgrade, -} -interface Zone { - id: CompletionVariant.zone, -} -interface ProgressMessage { - id: CompletionVariant.progressMessage, -} -interface WheelCommand { - id: CompletionVariant.wheelCommand, -} -interface IconType { - id: CompletionVariant.iconType, -} -interface ShardIconValue { - id: CompletionVariant.shardIconValue, -} -interface SpellIconValue { - id: CompletionVariant.spellIconValue, -} -interface OpherIconValue { - id: CompletionVariant.opherIconValue, -} -interface LupoIconValue { - id: CompletionVariant.lupoIconValue, -} -interface GromIconValue { - id: CompletionVariant.gromIconValue, -} -interface TuleyIconValue { - id: CompletionVariant.tuleyIconValue, -} -interface WheelItemBind { - id: CompletionVariant.wheelItemBind, -} -interface ShopCommand { - id: CompletionVariant.shopCommand, -} -interface Command { - id: CompletionVariant.command, -} -interface ParameterType { - id: CompletionVariant.parameterType, -} -interface Annotation { - id: CompletionVariant.annotation, -} -interface Flag { - id: CompletionVariant.flag, -} -export type Completion = UberState | UberId | Boolean | Item | Resource | Ability | Shard | SysCommand | Slot | Equipment | Keybind | Teleporter | MessageFlag | UberStateType | Water | BonusItem | BonusUpgrade | Zone | ProgressMessage | WheelCommand | IconType | ShardIconValue | SpellIconValue | OpherIconValue | LupoIconValue | GromIconValue | TuleyIconValue | WheelItemBind | ShopCommand | Command | ParameterType | Annotation | Flag; +export function offerCompletions(error: ParseError, text: string): CompletionItem[] | null { + const completion = error.completion; + if (completion === undefined) { return null; } -export function offerCompletions(completion: Completion): CompletionItem[] { - switch (completion.id) { - case CompletionVariant.uberState: return uberStateCompletions; - case CompletionVariant.uberId: return uberIdCompletions(completion.group); - case CompletionVariant.boolean: return booleanCompletions; - case CompletionVariant.item: return getItemCompletions(ItemVariant); - case CompletionVariant.resource: return getItemCompletions(ResourceVariant); - case CompletionVariant.ability: return getItemCompletions(AbilityVariant); - case CompletionVariant.shard: return getItemCompletions(ShardVariant); - case CompletionVariant.sysCommand: return getItemCompletions(SysCommandVariant); - case CompletionVariant.slot: return slotCompletions; - case CompletionVariant.equipment: return getItemCompletions(EquipmentVariants); - case CompletionVariant.keybind: return keybindCompletions; - case CompletionVariant.teleporter: return getItemCompletions(TeleporterVariant); - case CompletionVariant.messageFlag: return messageFlagCompletions; - case CompletionVariant.uberStateType: return uberTypeCompletions; - case CompletionVariant.water: return waterCompletions; - case CompletionVariant.bonusItem: return getItemCompletions(BonusItemVariant); - case CompletionVariant.bonusUpgrade: return getItemCompletions(BonusUpgradeVariant); - case CompletionVariant.zone: return getItemCompletions(ZoneVariants); - case CompletionVariant.progressMessage: return getItemCompletions(ProgressVariant); - case CompletionVariant.wheelCommand: return getItemCompletions(WheelCommandVariant); - case CompletionVariant.iconType: return iconTypeCompletions; - case CompletionVariant.shardIconValue: return getItemCompletions(ShardIconVariant); - case CompletionVariant.spellIconValue: return getItemCompletions(SpellIconVariant); - case CompletionVariant.opherIconValue: return getItemCompletions(OpherIconVariant); - case CompletionVariant.lupoIconValue: return getItemCompletions(LupoIconVariant); - case CompletionVariant.gromIconValue: return getItemCompletions(GromIconVariant); - case CompletionVariant.tuleyIconValue: return getItemCompletions(TuleyIconVariant); - case CompletionVariant.wheelItemBind: return wheelBindCompletions; - case CompletionVariant.shopCommand: return getItemCompletions(ShopCommandVariant); - case CompletionVariant.command: return commandCompletions; - case CompletionVariant.parameterType: return parameterTypeCompletions; - case CompletionVariant.annotation: return getNameCompletions(AnnotationVariant); - case CompletionVariant.flag: return getNameCompletions(FlagVariant); + switch (completion) { + case "Uber Group": return uberStateCompletions; + case "Uber Id": + const group = +text.slice(0, error.range.start).split(/[|\n]/).slice(-2)[0]; + return uberIdCompletions(group); + case "Uber Id": return null; + case "Uber Trigger Value": return null; + case "Uber Condition Value": return null; + case "Integer": return null; + case "Float": return null; + case "Identifier": return null; + case "Expression": return uberStateCompletions; + case "Boolean": return booleanCompletions; + case "Numeric Boolean": return getItemCompletions(NumericBoolean); + case "Interpolation Command": return getNameCompletions(InterpolationCommand); + case "Item Kind": return getItemCompletions(ItemVariant); + case "Resource": return getItemCompletions(ResourceVariant); + case "Skill": return getItemCompletions(AbilityVariant); + case "Shard": return getItemCompletions(ShardVariant); + case "Command Kind": return getItemCompletions(SysCommandVariant); + case "Equip Slot": return getItemCompletions(Slot); + case "Spell": return getItemCompletions(EquipmentVariants); + case "Toggle Command Kind": return getItemCompletions(ToggleCommand); + // case CompletionVariant.keybind: return keybindCompletions; + case "Teleporter": return getItemCompletions(TeleporterVariant); + case "Message Flag": return messageFlagCompletions; + case "Uber Type": return uberTypeCompletions; + case "World Event": return waterCompletions; + case "Bonus Item": return getItemCompletions(BonusItemVariant); + case "Bonus Upgrade": return getItemCompletions(BonusUpgradeVariant); + case "Zone": return getItemCompletions(ZoneVariants); + case "Sys Message Kind": return getItemCompletions(ProgressVariant); + case "Wheel Command Kind": return getItemCompletions(WheelCommandVariant); + case "IconKind": return iconTypeCompletions; + case "Shard Icon": return getItemCompletions(ShardIconVariant); + case "Spell Icon": return getItemCompletions(SpellIconVariant); + case "Opher Icon": return getItemCompletions(OpherIconVariant); + case "Lupo Icon": return getItemCompletions(LupoIconVariant); + case "Grom Icon": return getItemCompletions(GromIconVariant); + case "Tuley Icon": return getItemCompletions(TuleyIconVariant); + case "Wheel Bind": return wheelBindCompletions; + case "Wheel Item Position": return getItemCompletions(WheelPosition); + case "Shop Command Kind": return getItemCompletions(ShopCommandVariant); + case "HeaderCommand": return commandCompletions; + case "ParameterType": return parameterTypeCompletions; + case "Annotation": return getNameCompletions(AnnotationVariant); + // case CompletionVariant.flag: return getNameCompletions(FlagVariant); default: - const safeguard: never = completion; - return safeguard; + vscode.window.showWarningMessage(`Received unknown completion request "${completion}"`); + return null; } } diff --git a/src/completion/slotCompletion.ts b/src/completion/slotCompletion.ts deleted file mode 100644 index 8437934..0000000 --- a/src/completion/slotCompletion.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { CompletionItem } from "vscode"; - -const slotNamesAndCodes = [ - { - name: "Ability1", - code: "0", - }, - { - name: "Ability2", - code: "1", - }, - { - name: "Ability3", - code: "2", - }, -]; - -const slotNameCompletions: CompletionItem[] = slotNamesAndCodes.map(({ name, code }) => { - return { - label: name, - detail: code, - insertText: code, - }; -}); -const slotCodeCompletions: CompletionItem[] = slotNamesAndCodes.map(({ name, code }) => { - return { - label: code, - detail: name, - }; -}); -const slotCompletions = slotNameCompletions.concat(slotCodeCompletions); - -export default slotCompletions; diff --git a/src/description.ts b/src/description.ts deleted file mode 100644 index a8a1bc7..0000000 --- a/src/description.ts +++ /dev/null @@ -1,340 +0,0 @@ -import namedUberStates from "./uberState/namedUberStates"; -import uberStates from "./uberState/uberStates"; -import EquipmentVariants from "./equipment"; -import { Item, ItemVariant } from "./item"; -import { AbilityVariant } from "./item/ability"; -import { BonusItemVariant } from "./item/bonusItem"; -import { BonusUpgradeVariant } from "./item/bonusUpgrade"; -import { SysSubcommand, SysCommandVariant } from "./item/sysCommand"; -import { ResourceVariant } from "./item/resource"; -import { ShardVariant } from "./item/shard"; -import { TeleporterVariant } from "./item/teleporter"; -import UberIdentifier from "./uberState/uberIdentifier"; -import ZoneVariants from "./zone"; -import { ProgressVariant } from "./item/progressMessage"; -import { WheelCommandVariant, WheelSubcommand } from "./item/wheelCommand"; -import Icon from "./icon"; -import ShardIconVariant from "./icon/shardIcon"; -import SpellIconVariant from "./icon/spellIcon"; -import OpherIconVariant from "./icon/opherIcon"; -import LupoIconVariant from "./icon/lupoIcon"; -import TuleyIconVariant from "./icon/tuleyIcon"; -import GromIconVariant from "./icon/gromIcon"; -import { ShopCommandVariant, ShopSubcommand } from "./item/shopCommand"; -import { Line, LineVariant, Pickup } from "./line"; -import { Command, CommandVariant } from "./command"; - -function describeUberState(uberIdentifier: UberIdentifier, uberValue?: number): string { - const namedEntry = namedUberStates.find(uberState => - uberState.groupId === uberIdentifier.group && - uberState.uberId === uberIdentifier.id && - uberState.uberValue === uberValue - ); - if (namedEntry !== undefined) { - let description = namedEntry.id; - const value = namedEntry.uberValue; - if (value !== undefined) { - description += `=${value}`; - } - return description; - } - - const entry = uberStates.find(uberState => - uberState.groupId === uberIdentifier.group && - uberState.uberId === uberIdentifier.id - ); - if (entry !== undefined) { - return entry.id; - } - - console.warn("Failed to describe uberState: ", uberIdentifier, uberValue); - let code = `${uberIdentifier.group}|${uberIdentifier.id}`; - if (uberValue !== undefined) { - code += `=${uberValue}`; - } - return code; -} - -function describeSysCommand(command: SysSubcommand): string { - switch (command.id) { - case SysCommandVariant.autosave: - return "Autosave"; - case SysCommandVariant.setResource: - const resourceName = ResourceVariant[command.resource]; - return `Set ${resourceName} to ${command.amount}`; - case SysCommandVariant.checkpoint: - return "Checkpoint"; - case SysCommandVariant.kwolokStatue: - return `${command.value ? "Enable" : "Disable"} Kwolok statue`; - case SysCommandVariant.warp: - return `Warp to ${command.x}, ${command.y}`; - case SysCommandVariant.applier: - return `Override applier state ${command.weird} with ${command.stuff}`; - case SysCommandVariant.setHealth: - return `Set current health to ${command.amount}`; - case SysCommandVariant.setEnergy: - return `Set current energy to ${command.amount}`; - case SysCommandVariant.setSpiritLight: - return `Set current spirit light to ${command.amount}`; - case SysCommandVariant.equip: { - const equipmentName = EquipmentVariants[command.equipment]; - return `Equip ${equipmentName} to slot ${command.slot}`; - } case SysCommandVariant.unequip: { - const equipmentName = EquipmentVariants[command.equipment]; - return `Unequip ${equipmentName}`; - } case SysCommandVariant.triggerBind: - return `Trigger keybind ${command.bind}`; - case SysCommandVariant.ifEqual: { - const uberStateDescription = describeUberState(command.uberIdentifier); - const itemDescription = describeItem(command.item); - return `Grant this item if ${uberStateDescription} is equal to ${command.value}:\n\n${itemDescription}`; - } case SysCommandVariant.ifGreater: { - const uberStateDescription = describeUberState(command.uberIdentifier); - const itemDescription = describeItem(command.item); - return `Grant this item if ${uberStateDescription} is greater than ${command.value}:\n\n${itemDescription}`; - } case SysCommandVariant.ifLess: { - const uberStateDescription = describeUberState(command.uberIdentifier); - const itemDescription = describeItem(command.item); - return `Grant this item if ${uberStateDescription} is less than ${command.value}:\n\n${itemDescription}`; - } case SysCommandVariant.disableSync: { - const uberStateDescription = describeUberState(command.uberIdentifier); - return `Disable multiplayer sync for ${uberStateDescription}`; - } case SysCommandVariant.enableSync: { - const uberStateDescription = describeUberState(command.uberIdentifier); - return `Enable multiplayer sync for ${uberStateDescription}`; - } case SysCommandVariant.createWarpIcon: - return `Create warp icon ${command.warpId} at ${command.x}, ${command.y}${command.label === undefined ? "" : ` with a label "${command.label}"`}`; - case SysCommandVariant.destroyWarpIcon: - return `Destroy warp icon ${command.warpId}`; - case SysCommandVariant.ifBounds: { - const itemDescription = describeItem(command.item); - return `Grant this item if Ori is within the rectangle defined by ${command.x1},${command.y1}/${command.x2},${command.y2}:\n\n${itemDescription}`; - } case SysCommandVariant.ifSelfEqual: { - const itemDescription = describeItem(command.item); - return `Grant this item if the location's value is equal to ${command.value}:\n\n${itemDescription}`; - } case SysCommandVariant.ifSelfGreater: { - const itemDescription = describeItem(command.item); - return `Grant this item if the location's value is greater than ${command.value}:\n\n${itemDescription}`; - } case SysCommandVariant.ifSelfLess: { - const itemDescription = describeItem(command.item); - return `Grant this item if the location's value is less than ${command.value}:\n\n${itemDescription}`; - } case SysCommandVariant.saveString: - return `Stores the string "${command.string}" under the identifier ${command.stringId}`; - case SysCommandVariant.appendString: - return `Appends the string "${command.string}" to the current value stored under the identifier ${command.stringId}`; - } -} -function describeIcon(icon: Icon): string { - switch (icon.id) { - case "shard": return `the ${ShardIconVariant[icon.iconId]} icon`; - case "spell": return `the ${SpellIconVariant[icon.iconId]} icon`; - case "opher": return `the ${OpherIconVariant[icon.iconId]} icon`; - case "lupo": return `the ${LupoIconVariant[icon.iconId]} icon`; - case "grom": return `the ${GromIconVariant[icon.iconId]} icon`; - case "tuley": return `the ${TuleyIconVariant[icon.iconId]} icon`; - case "file": return `the file at "${icon.path}"`; - } -} -function describeWheelCommand(command: WheelSubcommand): string { - switch (command.id) { - case WheelCommandVariant.setText: return `Sets the name of item ${command.position} in wheel ${command.wheel} to "${command.text}"`; - case WheelCommandVariant.setDescription: return `Sets the description of item ${command.position} in wheel ${command.wheel} to "${command.text}"`; - case WheelCommandVariant.setIcon: - const iconDescription = describeIcon(command.icon); - return `Sets the icon of item ${command.position} in wheel ${command.wheel} to ${iconDescription}`; - case WheelCommandVariant.setColor: return `Sets the rgba icon color of item ${command.position} in wheel ${command.wheel} to (${command.red}, ${command.green}, ${command.blue}, ${command.alpha})`; - case WheelCommandVariant.setAction: - const itemDescription = describeItem(command.item); - return `Sets the action bound to ${command.bind === 0 ? "all binds" : `ability ${command.bind}`} of item ${command.position} in wheel ${command.wheel} to this item:\n\n${itemDescription}`; - case WheelCommandVariant.setSticky: return `Sets wheel ${command.wheel} to be ${command.sticky ? "" : "not "}sticky`; - case WheelCommandVariant.switch: return `Switch to wheel ${command.wheel}`; - case WheelCommandVariant.remove: return `Remove item ${command.position} in wheel ${command.wheel}`; - case WheelCommandVariant.clear: return "Clear all wheels"; - } -} -function describeShopCommand(command: ShopSubcommand): string { - switch (command.id) { - case ShopCommandVariant.setIcon: { - const uberStateDescription = describeUberState(command.uberIdentifier); - const iconDescription = describeIcon(command.icon); - return `Sets the shop icon of ${uberStateDescription} to ${iconDescription}`; - } case ShopCommandVariant.setTitle: { - const uberStateDescription = describeUberState(command.uberIdentifier); - return `Sets the shop item title of ${uberStateDescription} to ${command.text || "the default"}`; - } case ShopCommandVariant.setDescription: { - const uberStateDescription = describeUberState(command.uberIdentifier); - return `Sets the shop item description of ${uberStateDescription} to ${command.text || "the default"}`; - } case ShopCommandVariant.setLocked: { - const uberStateDescription = describeUberState(command.uberIdentifier); - return `${command.flag ? "L" : "Unl"}ocks the shop item at ${uberStateDescription}`; - } case ShopCommandVariant.setVisible: - const uberStateDescription = describeUberState(command.uberIdentifier); - return `Turns the shop item at ${uberStateDescription} ${command.flag ? "" : "in"}visible`; - } -} - -function describeItem(item: Item): string { - switch (item.id) { - case ItemVariant.spiritLight: - const amount = item.amount; - return `${amount < 0 ? `Remove ${-amount}` : amount} Spirit Light`; - case ItemVariant.resource: return ResourceVariant[item.variant]; - case ItemVariant.ability: return AbilityVariant[item.variant]; - case ItemVariant.shard: return ShardVariant[item.variant]; - case ItemVariant.sysCommand: return describeSysCommand(item.subcommand); - case ItemVariant.teleporter: return `${TeleporterVariant[item.variant]} Teleporter`; - case ItemVariant.message: return `Display "${item.message}"`; - case ItemVariant.setUberState: - const uberStateDescription = describeUberState(item.uberIdentifier); - - const expression = item.expression; - - const value = expression.value; - let valueDescription: string; - if (typeof value !== "object") { - valueDescription = `${value}`; - } else if ("pointerIdentifier" in value) { - const pointerDescription = describeUberState(value.pointerIdentifier); - valueDescription = `the value of ${pointerDescription}`; - } else if ("lower" in value) { - const lower = value.lower; - let lowerDescription: string; - if (typeof lower !== "object") { - lowerDescription = `${lower}`; - } else if ("pointerIdentifier" in lower) { - const pointerDescription = describeUberState(lower.pointerIdentifier); - lowerDescription = `the value of ${pointerDescription}`; - } else { - console.warn("failed to describe uberSet value of: ", lower); - lowerDescription = ""; - } - const upper = value.upper; - let upperDescription: string; - if (typeof upper !== "object") { - upperDescription = `${upper}`; - } else if ("pointerIdentifier" in upper) { - const pointerDescription = describeUberState(upper.pointerIdentifier); - upperDescription = `the value of ${pointerDescription}`; - } else { - console.warn("failed to describe uberSet value of: ", upper); - upperDescription = ""; - } - valueDescription = `a random value between ${lowerDescription} and ${upperDescription}`; - } else { - console.warn("failed to describe uberSet value of: ", value); - valueDescription = ""; - } - - let description; - switch (expression.sign) { - case undefined: - description = `Set ${uberStateDescription} to ${valueDescription}`; - break; - case true: - description = `Add ${valueDescription} to ${uberStateDescription}`; - break; - case false: - description = `Subtract ${valueDescription} from ${uberStateDescription}`; - break; - } - - const skip = item.skip; - if (skip > 0) { - description += `, skipping the next ${skip === 1 ? "trigger" : `${skip} triggers`}`; - } - - return description; - case ItemVariant.water: return "Water"; - case ItemVariant.bonusItem: return BonusItemVariant[item.variant]; - case ItemVariant.bonusUpgrade: return BonusUpgradeVariant[item.variant]; - case ItemVariant.relic: return `${ZoneVariants[item.variant]} Relic`; - case ItemVariant.progressMessage: - const variant = item.progressVariant; - switch (variant.id) { - case ProgressVariant.relic: - return "Relic progress"; - case ProgressVariant.zoneRelic: - return `${ZoneVariants[variant.zone]} Relic Progress`; - case ProgressVariant.pickup: - return "Pickup progress"; - case ProgressVariant.goalmode: - return "Goalmode progress"; - } - case ItemVariant.wheelCommand: return describeWheelCommand(item.subcommand); - case ItemVariant.shopCommand: return describeShopCommand(item.subcommand); - default: - const safeguard: never = item; - return safeguard; - } -} - -function describePickup(pickup: Pickup): string[] { - const uberStateDescription = describeUberState(pickup.uberIdentifier, pickup.uberValue); - const itemDescription = describeItem(pickup.item); - - return [ - `**Location**\n\n${uberStateDescription}`, - `**Item**\n\n${itemDescription}`, - ]; -} - -function describeCommand(command: Command): string { - switch (command.id) { - case CommandVariant.include: return `Include header "${command.path}"`; - case CommandVariant.exclude: return `Exclude header "${command.path}"`; - case CommandVariant.add: - case CommandVariant.remove: { - const add = command.id === CommandVariant.add; - const amount = command.amount; - const amountDescription = amount === 1 ? "" : `${amount} times `; - const itemDescription = describeItem(command.item); - return `${add ? "Add" : "Remove"} this item ${amountDescription}${add ? "to" : "from"} the item pool:\n\n${itemDescription}`; - } case CommandVariant.name: { - const itemDescription = describeItem(command.item); - return `Set the name of this item to "${command.name}":\n\n${itemDescription}`; - } case CommandVariant.display: { - const itemDescription = describeItem(command.item); - return `Set the display name of this item to "${command.display}":\n\n${itemDescription}`; - } case CommandVariant.description: { - const itemDescription = describeItem(command.item); - return `Set the shop description of this item to "${command.description}":\n\n${itemDescription}`; - } case CommandVariant.price: { - const itemDescription = describeItem(command.item); - return `Set the price of this item to "${command.price}":\n\n${itemDescription}`; - } case CommandVariant.icon: { - const itemDescription = describeItem(command.item); - const iconDescription = describeIcon(command.icon); - return `Set the icon of this item to "${iconDescription}":\n\n${itemDescription}`; - } case CommandVariant.parameter: { - const parameter = command.parameter; - return `Add a parameter "${parameter.identifier}" with default value "${parameter.defaultValue}"`; - } case CommandVariant.pool: return `Add "${command.poolItem}" to the random pool`; - case CommandVariant.addpool: return `Add ${command.amount} random items from the random pool to the item pool`; - case CommandVariant.flush: return "Flush the random pool"; - case CommandVariant.set: return `Sets the logic state "${command.state}" to be met`; - case CommandVariant.if: return `Opens a block that will only be added to the seed if the parameter "${command.parameterId}" is "${command.value}"`; - case CommandVariant.endif: return "Closes one if block"; - } -} -function describeCommandLine(command: Command): string[] { - const commandDescription = describeCommand(command); - - return [ - `**Command**\n\n${commandDescription}` - ]; -} -function describeTimerLine(trigger: UberIdentifier, timer: UberIdentifier): string[] { - return [ - `**Timer**\n\nBind a timer on ${trigger.group}|${trigger.id} to a toggle on ${timer.group}|${timer.id}` - ]; -} - -export function describeLine(line: Line): string[] { - switch (line.id) { - case LineVariant.pickup: return describePickup(line.pickup); - case LineVariant.command: return describeCommandLine(line.command); - case LineVariant.timer: return describeTimerLine(line.trigger, line.timer); - case LineVariant.flags: - case LineVariant.spawn: return []; - } -} diff --git a/src/diagnostics.ts b/src/diagnostics.ts deleted file mode 100644 index f830590..0000000 --- a/src/diagnostics.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as vscode from 'vscode'; - -import { ParseFailure, Token } from "./parser"; - -function errorMessage(parseFailure: ParseFailure): string { - const expected = parseFailure.expected; - if (typeof expected === "string") { - return `expected "${expected}"`; - } - - return `expected ${Token[expected]}`; -} - -export function diagnose(document: vscode.TextDocument, parseFailure: ParseFailure): vscode.Diagnostic | undefined { - const position = document.positionAt(parseFailure.status.offsetInSource()); - let range = document.getWordRangeAtPosition(position); - if (range === undefined) { range = new vscode.Range(position, position); } - - const message = errorMessage(parseFailure); - - return new vscode.Diagnostic(range, message); -} diff --git a/src/extension.ts b/src/extension.ts index 68d04df..425c872 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,10 +1,7 @@ -import { watch } from 'fs'; import * as vscode from 'vscode'; -import { CompletionVariant, offerCompletions } from './completion'; -import { describeLine } from './description'; -import { diagnose } from './diagnostics'; +import { offerCompletions } from './completion'; -import { fail, parseAnnotation, parseComment, parseLine, parseLineBreak, parseRemainingLine, ParseStatus, Token } from './parser'; +import { checkErrors, parseLine } from 'wotw-seedgen'; const completionTriggerCharacters = [ "0", @@ -26,55 +23,34 @@ const filePattern = "**/*.{wotwr,wotwrh}"; class HeaderCompletionItemProvider implements vscode.CompletionItemProvider { provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): vscode.ProviderResult { const documentLine = document.lineAt(position); - const status: ParseStatus = new ParseStatus(documentLine.text); + const text = documentLine.text; - const line = parseLine(status); - if (line.success) { return null; } + const errors = checkErrors(text); + const error = errors[0]; + if (error === undefined) { return null; } - const completion = line.completion; - if (completion !== undefined) { - return offerCompletions(completion); - } - - return null; + return offerCompletions(error, text); } } class HeaderHoverProvider implements vscode.HoverProvider { provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult { const documentLine = document.lineAt(position); - let lineText = documentLine.text; - const status: ParseStatus = new ParseStatus(lineText); + const lineText = documentLine.text; - const line = parseLine(status); - if (!line.success) { return null; } + const line = parseLine(lineText); + if (line === undefined) { return null; } - const description = describeLine(line.result); + const description = line.description(); + if (description === undefined) { return null; } - const commentIndex = lineText.indexOf("//"); - if (commentIndex !== -1) { - lineText = lineText.slice(0, commentIndex); - } - lineText = lineText.trimEnd(); - - const contents = [ `\`\`\`ori-wotw-header\n${lineText}\n\`\`\`` ].concat(description); + const multilineDescription = description.map(description => description.replace(":", ":\n\n")); + const contents = [ `\`\`\`ori-wotw-header\n${lineText}\n\`\`\`` ].concat(multilineDescription); return { contents: contents }; } } -async function provideDiagnostics(collection: vscode.DiagnosticCollection) { - const files = await vscode.workspace.findFiles(filePattern); - for (const uri of files) { - try { - const document = await vscode.workspace.openTextDocument(uri); - updateDiagnostics(document, collection); - } catch (e) { - console.warn(e); - } - } -} - export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.languages.registerHoverProvider("ori-wotw-header", new HeaderHoverProvider)); context.subscriptions.push(vscode.languages.registerCompletionItemProvider("ori-wotw-header", new HeaderCompletionItemProvider, ...completionTriggerCharacters)); @@ -82,7 +58,9 @@ export function activate(context: vscode.ExtensionContext) { const diagnosticsCollection = vscode.languages.createDiagnosticCollection("ori-wotw-header"); context.subscriptions.push(diagnosticsCollection); - provideDiagnostics(diagnosticsCollection); + for (const document of vscode.workspace.textDocuments.filter(document => document.languageId === "ori-wotw-header")) { + updateDiagnostics(document, diagnosticsCollection); + } vscode.workspace.onDidOpenTextDocument(event => { if (vscode.languages.match({ language: "ori-wotw-header" }, event) > 0) { @@ -103,35 +81,15 @@ export function activate(context: vscode.ExtensionContext) { } function updateDiagnostics(document: vscode.TextDocument, collection: vscode.DiagnosticCollection) { - let diagnostics: vscode.Diagnostic[] = []; - - const status: ParseStatus = new ParseStatus(document.getText()); - - const annotationsResult = parseAnnotation(status); - if (!annotationsResult.success) { - const diagnosis = diagnose(document, annotationsResult); - if (diagnosis !== undefined) { diagnostics.push(diagnosis); } - } - - while(true) { - parseComment(status); - if (status.remaining.length === 0) { break; } - if (parseLineBreak(status)) { continue; } - - const lineResult = parseLine(status); - if (!lineResult.success) { - const diagnosis = diagnose(document, lineResult); - if (diagnosis !== undefined) { diagnostics.push(diagnosis); } - parseRemainingLine(status); - } - parseComment(status); - if (status.remaining.length === 0) { break; } - if (!parseLineBreak(status)) { - const diagnosis = diagnose(document, fail(Token.lineBreak, status, undefined)); - if (diagnosis !== undefined) { diagnostics.push(diagnosis); } - parseRemainingLine(status); - } - } + const text = document.getText(); + const errors = checkErrors(text); + const diagnostics = errors.map(error => { + const errorRange = error.range; + const start = document.positionAt(errorRange.start); + const end = document.positionAt(errorRange.end); + const range = new vscode.Range(start, end); + return new vscode.Diagnostic(range, error.message); + }); collection.set(document.uri, diagnostics); } diff --git a/src/icon.ts b/src/icon.ts deleted file mode 100644 index 9e6c9d6..0000000 --- a/src/icon.ts +++ /dev/null @@ -1,38 +0,0 @@ -import GromIconVariant from "./icon/gromIcon"; -import LupoIconVariant from "./icon/lupoIcon"; -import OpherIconVariant from "./icon/opherIcon"; -import ShardIconVariant from "./icon/shardIcon"; -import SpellIconVariant from "./icon/spellIcon"; -import TuleyIconVariant from "./icon/tuleyIcon"; - -interface ShardIcon { - id: "shard", - iconId: ShardIconVariant, -} -interface SpellIcon { - id: "spell", - iconId: SpellIconVariant, -} -interface OpherIcon { - id: "opher", - iconId: OpherIconVariant, -} -interface LupoIcon { - id: "lupo", - iconId: LupoIconVariant, -} -interface GromIcon { - id: "grom", - iconId: GromIconVariant, -} -interface TuleyIcon { - id: "tuley", - iconId: TuleyIconVariant, -} -interface FileIcon { - id: "file", - path: string, -} -type Icon = ShardIcon | SpellIcon | OpherIcon | LupoIcon | GromIcon | TuleyIcon | FileIcon; - -export default Icon; diff --git a/src/interpolationCommand.ts b/src/interpolationCommand.ts new file mode 100644 index 0000000..b97b285 --- /dev/null +++ b/src/interpolationCommand.ts @@ -0,0 +1,5 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +enum InterpolationCommand { + PARAM, +} +export default InterpolationCommand; diff --git a/src/item.ts b/src/item.ts index a76a54e..5945682 100644 --- a/src/item.ts +++ b/src/item.ts @@ -1,19 +1,3 @@ -import { SpiritLight } from "./item/spiritLight"; -import { Resource } from "./item/resource"; -import { Ability } from "./item/ability"; -import { Shard } from "./item/shard"; -import { SysCommand } from "./item/sysCommand"; -import { Teleporter } from "./item/teleporter"; -import { Message } from "./item/message"; -import { SetUberState } from "./item/setUberState"; -import { Water } from "./item/water"; -import { BonusItem } from "./item/bonusItem"; -import { BonusUpgrade } from "./item/bonusUpgrade"; -import { Relic } from "./item/relic"; -import { ProgressMessage } from "./item/progressMessage"; -import { WheelCommand } from "./item/wheelCommand"; -import { ShopCommand } from "./item/shopCommand"; - export enum ItemVariant { spiritLight = 0, resource = 1, @@ -31,5 +15,3 @@ export enum ItemVariant { wheelCommand = 16, shopCommand = 17, } - -export type Item = SpiritLight | Resource | Ability | Shard | SysCommand | Teleporter | Message | SetUberState | Water | BonusItem | BonusUpgrade | Relic | ProgressMessage | WheelCommand | ShopCommand; diff --git a/src/item/ability.ts b/src/item/ability.ts index bc27db6..0768b5a 100644 --- a/src/item/ability.ts +++ b/src/item/ability.ts @@ -1,5 +1,3 @@ -import { ItemVariant } from "../item"; - export enum AbilityVariant { bash = 0, wallJump = 3, @@ -30,8 +28,3 @@ export enum AbilityVariant { ancestralLightA = 120, ancestralLightB = 121, } -export interface Ability { - id: ItemVariant.ability, - variant: AbilityVariant, - remove: boolean, -} diff --git a/src/item/bonusItem.ts b/src/item/bonusItem.ts index 6630930..856eea5 100644 --- a/src/item/bonusItem.ts +++ b/src/item/bonusItem.ts @@ -1,12 +1,6 @@ -import { ItemVariant } from "../item"; - export enum BonusItemVariant { healthRegeneration = 30, energyRegeneration = 31, extraDoubleJump = 35, extraAirDash = 36, } -export interface BonusItem { - id: ItemVariant.bonusItem, - variant: BonusItemVariant, -} diff --git a/src/item/bonusUpgrade.ts b/src/item/bonusUpgrade.ts index 8212d02..44c3b8a 100644 --- a/src/item/bonusUpgrade.ts +++ b/src/item/bonusUpgrade.ts @@ -1,5 +1,3 @@ -import { ItemVariant } from "../item"; - export enum BonusUpgradeVariant { rapidHammer = 0, rapidSword = 1, @@ -17,7 +15,3 @@ export enum BonusUpgradeVariant { chargeBlaze = 48, rapidSentry = 49, } -export interface BonusUpgrade { - id: ItemVariant.bonusUpgrade, - variant: BonusUpgradeVariant, -} diff --git a/src/item/message.ts b/src/item/message.ts deleted file mode 100644 index 4197f40..0000000 --- a/src/item/message.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ItemVariant } from "../item"; - -export interface Message { - id: ItemVariant.message, - message: string, - mute?: true, - lifetime?: number, - instant?: true, - quiet?: true, - position?: number, - noclear?: true, -} diff --git a/src/item/numericBoolean.ts b/src/item/numericBoolean.ts new file mode 100644 index 0000000..f7acf31 --- /dev/null +++ b/src/item/numericBoolean.ts @@ -0,0 +1,4 @@ +export enum NumericBoolean { + false = 0, + true = 1, +} diff --git a/src/item/progressMessage.ts b/src/item/progressMessage.ts index e748af6..f37f442 100644 --- a/src/item/progressMessage.ts +++ b/src/item/progressMessage.ts @@ -1,29 +1,6 @@ -import { ItemVariant } from "../item"; -import ZoneVariants from "../zone"; - export enum ProgressVariant { relic, zoneRelic, pickup, goalmode, } - -interface RelicProgress { - id: ProgressVariant.relic, -} -interface ZoneRelicProgress { - id: ProgressVariant.zoneRelic, - zone: ZoneVariants, -} -interface PickupProgress { - id: ProgressVariant.pickup, -} -interface GoalmodeProgress { - id: ProgressVariant.goalmode, -} -export type ProgressMessageVariant = RelicProgress | ZoneRelicProgress | PickupProgress | GoalmodeProgress; - -export interface ProgressMessage { - id: ItemVariant.progressMessage, - progressVariant: ProgressMessageVariant, -} diff --git a/src/item/relic.ts b/src/item/relic.ts deleted file mode 100644 index 5ce0023..0000000 --- a/src/item/relic.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ItemVariant } from "../item"; -import ZoneVariants from "../zone"; - -export interface Relic { - id: ItemVariant.relic, - variant: ZoneVariants, -} diff --git a/src/item/resource.ts b/src/item/resource.ts index 4f99a16..eb563ef 100644 --- a/src/item/resource.ts +++ b/src/item/resource.ts @@ -1,5 +1,3 @@ -import { ItemVariant } from "../item"; - export enum ResourceVariant { healthFragment, energyFragment, @@ -7,7 +5,3 @@ export enum ResourceVariant { keystone, shardSlot, } -export interface Resource { - id: ItemVariant.resource, - variant: ResourceVariant, -} diff --git a/src/item/setUberState.ts b/src/item/setUberState.ts deleted file mode 100644 index cdae672..0000000 --- a/src/item/setUberState.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ItemVariant } from "../item"; -import UberIdentifier from "../uberState/uberIdentifier"; - -export interface SetPointer { - pointerIdentifier: UberIdentifier, -} -export interface SetRange { - lower: ValueType | SetPointer, - upper: ValueType | SetPointer, -} - -export interface SetExpression { - type: "bool" | "teleporter" | "byte" | "int" | "float", - sign?: boolean, - value: ValueType | SetPointer | SetRange, -} - -export interface SetUberState { - id: ItemVariant.setUberState, - uberIdentifier: UberIdentifier, - expression: SetExpression, - skip: number, -} diff --git a/src/item/shard.ts b/src/item/shard.ts index c209ce3..017278c 100644 --- a/src/item/shard.ts +++ b/src/item/shard.ts @@ -1,5 +1,3 @@ -import { ItemVariant } from "../item"; - export enum ShardVariant { overcharge = 1, tripleJump = 2, @@ -33,8 +31,3 @@ export enum ShardVariant { fracture = 46, arcing = 47, } -export interface Shard { - id: ItemVariant.shard, - variant: ShardVariant, - remove: boolean, -} diff --git a/src/item/shopCommand.ts b/src/item/shopCommand.ts index 47e3bfb..2cee014 100644 --- a/src/item/shopCommand.ts +++ b/src/item/shopCommand.ts @@ -1,7 +1,3 @@ -import Icon from "../icon"; -import { ItemVariant } from "../item"; -import UberIdentifier from "../uberState/uberIdentifier"; - export enum ShopCommandVariant { setIcon = 0, setTitle = 1, @@ -9,35 +5,3 @@ export enum ShopCommandVariant { setLocked = 3, setVisible = 4, } - -interface SetShopItemIcon { - id: ShopCommandVariant.setIcon, - uberIdentifier: UberIdentifier, - icon: Icon, -} -interface SetShopItemTitle { - id: ShopCommandVariant.setTitle, - uberIdentifier: UberIdentifier, - text: string | null, -} -interface SetShopItemDescription { - id: ShopCommandVariant.setDescription, - uberIdentifier: UberIdentifier, - text: string | null, -} -interface SetShopItemLocked { - id: ShopCommandVariant.setLocked, - uberIdentifier: UberIdentifier, - flag: boolean, -} -interface SetShopItemVisible { - id: ShopCommandVariant.setVisible, - uberIdentifier: UberIdentifier, - flag: boolean, -} -export type ShopSubcommand = SetShopItemIcon | SetShopItemTitle | SetShopItemDescription | SetShopItemLocked | SetShopItemVisible; - -export interface ShopCommand { - id: ItemVariant.shopCommand, - subcommand: ShopSubcommand -} diff --git a/src/item/slot.ts b/src/item/slot.ts new file mode 100644 index 0000000..957afa5 --- /dev/null +++ b/src/item/slot.ts @@ -0,0 +1,6 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +export enum Slot { + Ability1 = 0, + Ability2 = 1, + Ability3 = 2, +} diff --git a/src/item/spiritLight.ts b/src/item/spiritLight.ts deleted file mode 100644 index 8c23899..0000000 --- a/src/item/spiritLight.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ItemVariant } from "../item"; - -export interface SpiritLight { - id: ItemVariant.spiritLight, - amount: number, -} diff --git a/src/item/sysCommand.ts b/src/item/sysCommand.ts index 7c2cf98..7380fef 100644 --- a/src/item/sysCommand.ts +++ b/src/item/sysCommand.ts @@ -1,8 +1,3 @@ -import { ResourceVariant } from "./resource"; -import UberIdentifier from "../uberState/uberIdentifier"; -import EquipmentVariants from "../equipment"; -import { Item, ItemVariant } from "../item"; - export enum SysCommandVariant { autosave = 0, setResource = 1, @@ -30,155 +25,3 @@ export enum SysCommandVariant { saveString = 29, appendString = 30, } - -interface Autosave { - id: SysCommandVariant.autosave, -} -interface SetResource { - id: SysCommandVariant.setResource, - resource: ResourceVariant, - amount: number, -} -interface Checkpoint { - id: SysCommandVariant.checkpoint, -} -interface KwolokStatue { - id: SysCommandVariant.kwolokStatue, - value: number, -} -interface Warp { - id: SysCommandVariant.warp, - x: number, - y: number, -} -interface Applier { - id: SysCommandVariant.applier, - weird: number, - stuff: number, -} -interface SetHealth { - id: SysCommandVariant.setHealth, - amount: number, -} -interface SetEnergy { - id: SysCommandVariant.setEnergy, - amount: number, -} -interface SetSpiritLight { - id: SysCommandVariant.setSpiritLight, - amount: number, -} -interface Equip { - id: SysCommandVariant.equip, - slot: 0 | 1 | 2, - equipment: EquipmentVariants, -} -interface TriggerBind { - id: SysCommandVariant.triggerBind, - bind: string, -} -interface IfEqual { - id: SysCommandVariant.ifEqual, - uberIdentifier: UberIdentifier, - value: number, - item: Item, -} -interface IfGreater { - id: SysCommandVariant.ifGreater, - uberIdentifier: UberIdentifier, - value: number, - item: Item, -} -interface IfLess { - id: SysCommandVariant.ifLess, - uberIdentifier: UberIdentifier, - value: number, - item: Item, -} -interface DisableSync { - id: SysCommandVariant.disableSync, - uberIdentifier: UberIdentifier, -} -interface EnableSync { - id: SysCommandVariant.enableSync, - uberIdentifier: UberIdentifier, -} -interface CreateWarpIcon { - id: SysCommandVariant.createWarpIcon, - warpId: number, - x: number, - y: number, - label?: string, -} -interface DestroyWarpIcon { - id: SysCommandVariant.destroyWarpIcon, - warpId: number, -} -interface IfBounds { - id: SysCommandVariant.ifBounds, - x1: number, - y1: number, - x2: number, - y2: number, - item: Item, -} -interface IfSelfEqual { - id: SysCommandVariant.ifSelfEqual, - value: number, - item: Item, -} -interface IfSelfGreater { - id: SysCommandVariant.ifSelfGreater, - value: number, - item: Item, -} -interface IfSelfLess { - id: SysCommandVariant.ifSelfLess, - value: number, - item: Item, -} -interface Unequip { - id: SysCommandVariant.unequip, - equipment: EquipmentVariants, -} -interface SaveString { - id: SysCommandVariant.saveString, - stringId: number, - string: string, -} -interface AppendString { - id: SysCommandVariant.appendString, - stringId: number, - string: string, -} -export type SysSubcommand = -Autosave -| SetResource -| Checkpoint -| KwolokStatue -| Warp -| Applier -| SetHealth -| SetEnergy -| SetSpiritLight -| Equip -| TriggerBind -| IfEqual -| IfGreater -| IfLess -| DisableSync -| EnableSync -| CreateWarpIcon -| DestroyWarpIcon -| IfBounds -| IfSelfEqual -| IfSelfGreater -| IfSelfLess -| Unequip -| SaveString -| AppendString; - -export interface SysCommand { - id: ItemVariant.sysCommand, - subcommand: SysSubcommand, -} diff --git a/src/item/teleporter.ts b/src/item/teleporter.ts index 8841a65..d499f31 100644 --- a/src/item/teleporter.ts +++ b/src/item/teleporter.ts @@ -1,5 +1,3 @@ -import { ItemVariant } from "../item"; - export enum TeleporterVariant { midnightBurrows, howlsDen, @@ -20,7 +18,3 @@ export enum TeleporterVariant { inkwaterMarsh, glades, } -export interface Teleporter { - id: ItemVariant.teleporter, - variant: TeleporterVariant, -} diff --git a/src/item/toggleCommand.ts b/src/item/toggleCommand.ts new file mode 100644 index 0000000..b8b99e4 --- /dev/null +++ b/src/item/toggleCommand.ts @@ -0,0 +1,6 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +export enum ToggleCommand { + KwolokDoor = 0, + Rain = 1, + Howl = 2, +} diff --git a/src/item/water.ts b/src/item/water.ts deleted file mode 100644 index 87a0092..0000000 --- a/src/item/water.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ItemVariant } from "../item"; - -export interface Water { - id: ItemVariant.water, -} diff --git a/src/item/wheelPosition.ts b/src/item/wheelPosition.ts new file mode 100644 index 0000000..db67b92 --- /dev/null +++ b/src/item/wheelPosition.ts @@ -0,0 +1,15 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +export enum WheelPosition { + Top = 0, + TopRight = 1, + RightTop = 2, + Right = 3, + RightBottom = 4, + BottomRight = 5, + Bottom = 6, + BottomLeft = 7, + LeftBottom = 8, + Left = 9, + LeftTop = 10, + TopLeft = 11, +} diff --git a/src/item/wheelcommand.ts b/src/item/wheelcommand.ts index a807900..9f932c6 100644 --- a/src/item/wheelcommand.ts +++ b/src/item/wheelcommand.ts @@ -1,6 +1,3 @@ -import Icon from "../icon"; -import { Item, ItemVariant } from "../item"; - export enum WheelCommandVariant { setText, setDescription, @@ -12,61 +9,3 @@ export enum WheelCommandVariant { remove, clear, } - -interface SetWheelItemText { - id: WheelCommandVariant.setText, - wheel: number, - position: number, - text: string, -} -interface SetWheelItemDescription { - id: WheelCommandVariant.setDescription, - wheel: number, - position: number, - text: string, -} -interface SetWheelItemIcon { - id: WheelCommandVariant.setIcon, - wheel: number, - position: number, - icon: Icon, -} -interface SetWheelItemColor { - id: WheelCommandVariant.setColor, - wheel: number, - position: number, - red: number, - green: number, - blue: number, - alpha: number, -} -interface SetWheelItemAction { - id: WheelCommandVariant.setAction, - wheel: number, - position: number, - bind: 0 | 1 | 2 | 3, - item: Item, -} -interface SetWheelSticky { - id: WheelCommandVariant.setSticky, - wheel: number, - sticky: boolean, -} -interface SwitchWheel { - id: WheelCommandVariant.switch, - wheel: number, -} -interface RemoveWheelItem { - id: WheelCommandVariant.remove, - wheel: number, - position: number, -} -interface ClearWheels { - id: WheelCommandVariant.clear, -} -export type WheelSubcommand = SetWheelItemText | SetWheelItemDescription | SetWheelItemIcon | SetWheelItemColor | SetWheelItemAction | SetWheelSticky | SwitchWheel | RemoveWheelItem | ClearWheels; - -export interface WheelCommand { - id: ItemVariant.wheelCommand, - subcommand: WheelSubcommand -} diff --git a/src/line.ts b/src/line.ts deleted file mode 100644 index c837cd0..0000000 --- a/src/line.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Command } from "./command"; -import { Item } from "./item"; -import UberIdentifier from "./uberState/uberIdentifier"; - -export enum LineVariant { - pickup, - command, - timer, - flags, - spawn, -} - -export interface Pickup { - uberIdentifier: UberIdentifier, - uberValue?: number, - item: Item, -} - -export interface PickupLine { - id: LineVariant.pickup, - pickup: Pickup, -} -export interface CommandLine { - id: LineVariant.command, - command: Command, -} -export interface TimerLine { - id: LineVariant.timer, - trigger: UberIdentifier, - timer: UberIdentifier, -} -export interface FlagLine { - id: LineVariant.flags, -} -export interface SpawnLine { - id: LineVariant.spawn, -} - -export type Line = PickupLine | CommandLine | TimerLine | FlagLine | SpawnLine; diff --git a/src/parser.ts b/src/parser.ts deleted file mode 100644 index 1269862..0000000 --- a/src/parser.ts +++ /dev/null @@ -1,444 +0,0 @@ -import { parseItem } from "./parser/parseItem"; -import UberIdentifier from "./uberState/uberIdentifier"; -import { Completion, CompletionVariant } from "./completion"; -import { Line, LineVariant, Pickup } from "./line"; -import { parseCommand } from "./parser/parseCommand"; -import { AnnotationVariant } from "./annotation"; - -export enum Token { - integer, - float, - word, - text, - boolean, - uberGroup, - uberId, - itemIdentifier, - resourceIdentifier, - abilityIdentifier, - shardIdentifier, - sysCommandIdentifier, - slot, - equipment, - teleporterIdentifier, - message, - uberStateType, - water, - bonusItem, - bonusUpgrade, - zone, - progressIdentifier, - wheelCommandIdentifier, - wheelItemPosition, - iconType, - shardIconValue, - spellIconValue, - opherIconValue, - lupoIconValue, - gromIconValue, - tuleyIconValue, - wheelItemBind, - shopCommandIdentifier, - commandIdentifier, - path, - logicIdentifier, - parameter, - parameterType, - annotation, - lineBreak, - flag, -} - -export interface ParseSuccess { - success: true, - result: Result, -} -export function succeed(result: Result): ParseSuccess { - return { - success: true, - result, - }; -} - -export interface ParseFailure { - success: false, - expected: Token | string, - status: ParseStatus, - completion?: Completion, -} - -export function fail(expected: Token | string, status: ParseStatus, completion: Completion | undefined): ParseFailure { - return { - success: false, - expected, - status, - completion, - }; -} - -export interface Parameter { - identifier: string, - defaultValue: boolean | number | string, -} - -export class ParseStatus { - remaining: string; - offset: number; - lengthChanges: [number, number][]; - parameters: Parameter[]; - pool: string[]; - - constructor(input: string, offset: number = 0, lengthChanges: [number, number][] = [], parameters: Parameter[] = [], pool: string[] = []) { - this.remaining = input; - this.offset = offset; - this.lengthChanges = lengthChanges; - this.parameters = parameters; - this.pool = pool; - } - - progress(offset: number) { - this.remaining = this.remaining.slice(offset); - this.offset += offset; - } - - take(): string | undefined { - if (this.pool.length === 0) { return undefined; } - const index = Math.floor(Math.random() * this.pool.length); - return this.pool.splice(index, 1)[0]; - } - - clone(): ParseStatus { - return new ParseStatus(this.remaining, this.offset, this.lengthChanges, this.parameters, this.pool); - } - - replaceWith(other: ParseStatus) { - this.remaining = other.remaining; - this.offset = other.offset; - this.lengthChanges = other.lengthChanges; - this.parameters = other.parameters; - this.pool = other.pool; - } - - offsetInSource(): number { - let offset = this.offset; - for (const [changeOffset, delta] of this.lengthChanges) { - if (this.offset >= changeOffset) { - offset += delta; - // offset = Math.max(offset + delta, changeOffset); - } else { break; } - } - return offset; - } -} - -export function eat(status: ParseStatus, eat: string): boolean { - const remaining = status.remaining; - - if (remaining.startsWith(eat)) { - status.progress(eat.length); - return true; - } else { - return false; - } -} - -function parseNumber(status: ParseStatus, regex: RegExp): number | null { - const remaining = status.remaining; - - const match = remaining.match(regex); - if (match === null) { return null; } - - status.progress(match[0].length); - return +match[0]; -} -export function parseInteger(status: ParseStatus, signed: boolean = false): number | null { - let regex; - if (signed) { - regex = /^-?\d+/; - } else { - regex = /^\d+/; - } - - return parseNumber(status, regex); -} -export function parseFloat(status: ParseStatus): number | null { - return parseNumber(status, /^-?\d+(?:\.\d+)?/); -} -export function parseBoolean(status: ParseStatus): boolean | null { - const regex = /^true|false/; - const remaining = status.remaining; - - const match = remaining.match(regex); - if (match === null) { return null; } - - status.progress(match[0].length); - const boolean = match[0] === "true"; - - return boolean; -} -export function parseString(status: ParseStatus, regex: RegExp): string | null { - const remaining = status.remaining; - - const match = remaining.match(regex); - if (match === null) { return null; } - - status.progress(match[0].length); - return match[0]; -} -export function parseWord(status: ParseStatus): string | null { - return parseString(status, /^\w+/); -} -export function parseLogicIdentifier(status: ParseStatus): string | null { - return parseString(status, /^\w+(\.\w+)?/); -} -export function parseRemainingLine(status: ParseStatus): string | null { - return parseString(status, /^.+/); -} -export function parseComment(status: ParseStatus): boolean { - const regex = /^\s*?\/\/.*/; - const remaining = status.remaining; - - const match = remaining.match(regex); - if (match === null) { return false; } - - status.progress(match[0].length); - return true; -} -export function parseLineBreak(status: ParseStatus): boolean { - const regex = /^\s*?(\r\n|\r|\n|\z)/; - const remaining = status.remaining; - - const match = remaining.match(regex); - if (match === null) { return false; } - - status.progress(match[0].length); - return true; -} - -type ParseUberIdentifierSuccess = ParseSuccess; -export function parseUberIdentifier(status: ParseStatus): ParseUberIdentifierSuccess | ParseFailure { - const group = parseInteger(status); - if (group === null) { return fail(Token.uberGroup, status, { id: CompletionVariant.uberState }); } - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.uberState }); } - - const id = parseInteger(status); - if (id === null) { return fail(Token.uberId, status, { id: CompletionVariant.uberId, group }); } - - const uberIdentifier = { - group, - id, - }; - - return { - success: true, - result: uberIdentifier, - }; -} - -type ParseUberValueSuccess = ParseSuccess; -function parseUberValue(status: ParseStatus): ParseUberValueSuccess | ParseFailure { - const value = parseInteger(status); - if (value === null) { return fail(Token.integer, status, undefined); } - - return { - success: true, - result: value, - }; -} - -type ParsePickupSuccess = ParseSuccess; -function parsePickup(status: ParseStatus): ParsePickupSuccess | ParseFailure { - eat(status, "!"); - - const uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const uberIdentifier = uberIdentifierResult.result; - - let uberValue; - if (eat(status, "=")) { - const uberValueResult = parseUberValue(status); - if (!uberValueResult.success) { return uberValueResult; } - uberValue = uberValueResult.result; - } - - if (!eat(status, "|")) { - let completion: Completion | undefined; - if (uberValue === undefined) { - completion = { id: CompletionVariant.uberId, group: uberIdentifier.group }; - } - return fail("|", status, completion); - } - - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - const pickup: Pickup = { - uberIdentifier, - uberValue, - item, - }; - - return succeed(pickup); -} - -function preprocessLine(status: ParseStatus): ParseFailure | undefined { - let hasMatch; - do { - hasMatch = false; - const remaining = status.remaining; - - const paramMatch = remaining.match(/\$PARAM\((.*?)\)|\n|\r/); - if (paramMatch !== null) { - const identifier = paramMatch[1]; - const index = paramMatch.index; - if (identifier !== undefined && index !== undefined) { - hasMatch = true; - - const value = status.parameters.find(param => param.identifier === identifier)?.defaultValue; - if (value === undefined) { - const errorStatus = status.clone(); - errorStatus.offset += index + 7; - return fail(Token.parameter, errorStatus, undefined); - } - const valueString = value.toString(); - - const paramMatchLength = paramMatch[0].length; - const lengthChange: [number, number] = [status.offset + index, paramMatchLength - valueString.length]; - status.lengthChanges.push(lengthChange); - - status.remaining = remaining.slice(0, index) + valueString + remaining.slice(index + paramMatchLength); - } - } - const takeMatch = remaining.match(/(!!take)|\n|\r/); - if (takeMatch !== null) { - const take = takeMatch[1]; - const index = takeMatch.index; - if (take !== undefined && index !== undefined) { - hasMatch = true; - - const value = status.take(); - if (value === undefined) { - const errorStatus = status.clone(); - errorStatus.offset += index + 2; - return fail("!!pool before !!take", errorStatus, undefined); - } - const valueString = value.toString(); - - const takeMatchLength = 6; - const lengthChange: [number, number] = [status.offset + index, takeMatchLength - valueString.length]; - status.lengthChanges.push(lengthChange); - - status.remaining = remaining.slice(0, index) + valueString + remaining.slice(index + takeMatchLength); - } - } - } while (hasMatch); -} - -type ParseLineSuccess = ParseSuccess; -export function parseLine(status: ParseStatus): ParseLineSuccess | ParseFailure { - const preprocessResult = preprocessLine(status); - if (preprocessResult !== undefined) { return preprocessResult; } - - if (eat(status, "!!")) { - const commandResult = parseCommand(status); - if (!commandResult.success) { return commandResult; } - const command = commandResult.result; - - const line: Line = { - id: LineVariant.command, - command, - }; - - return succeed(line); - } - - if (eat(status, "timer:")) { - eat(status, " "); - - let uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const trigger = uberIdentifierResult.result; - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.uberState }); } - - uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const timer = uberIdentifierResult.result; - - const line: Line = { - id: LineVariant.timer, - trigger, - timer, - }; - - return succeed(line); - } - if (eat(status, "Flags:")) { - do { - eat(status, " "); - const flag = parseString(status, /[^,\n]+/); - if (flag === null) { return fail(Token.flag, status, { id: CompletionVariant.flag }); } - } while (eat(status, ",")); - - const line: Line = { - id: LineVariant.flags, - }; - - return succeed(line); - } - if (eat(status, "Spawn:")) { - eat(status, " "); - - const x = parseFloat(status); - if (x === null) { return fail(Token.float, status, undefined); } - - if (!eat(status, ",")) { return fail(",", status, undefined); } - eat(status, " "); - - const y = parseFloat(status); - if (y === null) { return fail(Token.float, status, undefined); } - - const line: Line = { - id: LineVariant.spawn, - }; - - return succeed(line); - } - - const pickupResult = parsePickup(status); - if (!pickupResult.success) { return pickupResult; } - const pickup = pickupResult.result; - - const line: Line = { - id: LineVariant.pickup, - pickup, - }; - - return succeed(line); -} - -type ParseAnnotationsSuccess = ParseSuccess; -export function parseAnnotation(status: ParseStatus): ParseAnnotationsSuccess | ParseFailure { - const annotations: AnnotationVariant[] = []; - - while(true) { - if (!eat(status, "#")) { break; } - - const identifier = parseWord(status); - if (identifier === null) { return fail(Token.word, status, undefined); } - - switch(identifier) { - case "hide": - annotations.push(AnnotationVariant.hide); - break; - default: - return fail(Token.annotation, status, { id: CompletionVariant.annotation }); - } - - if (!parseLineBreak(status)) { return fail(Token.lineBreak, status, undefined); } - } - - return succeed(annotations); -} diff --git a/src/parser/parseCommand.ts b/src/parser/parseCommand.ts deleted file mode 100644 index 7b60aa5..0000000 --- a/src/parser/parseCommand.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { Command, CommandVariant } from "../command"; -import { CompletionVariant } from "../completion"; -import { eat, fail, Parameter, parseBoolean, ParseFailure, parseFloat, parseInteger, parseLogicIdentifier, parseRemainingLine, ParseStatus, ParseSuccess, parseWord, succeed, Token } from "../parser"; -import parseIcon from "./parseIcon"; -import { parseItem } from "./parseItem"; - -type ParseCommandSuccess = ParseSuccess; - -function parseAmount(status: ParseStatus): number | null { - const backup = status.clone(); - - const amount = parseInteger(status); - if (amount === null) { return null; } - - if (!eat(status, "x")) { - status.replaceWith(backup); - return null; - } - - return amount; -} - -function parseDependency(status: ParseStatus, variant: CommandVariant.include | CommandVariant.exclude): ParseCommandSuccess | ParseFailure { - const path = parseRemainingLine(status); - if (path === null) { return fail(Token.path, status, undefined); } - - const command: Command = { - id: variant, - path, - }; - - return succeed(command); -} -function parseChangeItemPool(status: ParseStatus, variant: CommandVariant.add | CommandVariant.remove): ParseCommandSuccess | ParseFailure { - const amountResult = parseAmount(status); - if (amountResult !== null && !eat(status, " ")) { return fail(" ", status, undefined); } - const amount = amountResult || 1; - - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - const command: Command = { - id: variant, - amount, - item, - }; - - return succeed(command); -} -// TODO the below functions are very similar -function parseNameCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - if (!eat(status, " ")) { return fail(" ", status, { id: CompletionVariant.command }); } - - const name = parseRemainingLine(status); - if (name === null) { return fail(Token.text, status, undefined); } - - const command: Command = { - id: CommandVariant.name, - item, - name, - }; - - return succeed(command); -} -function parseDisplayCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - if (!eat(status, " ")) { return fail(" ", status, { id: CompletionVariant.command }); } - - const display = parseRemainingLine(status); - if (display === null) { return fail(Token.message, status, undefined); } - - const command: Command = { - id: CommandVariant.display, - item, - display, - }; - - return succeed(command); -} -function parseDescriptionCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - if (!eat(status, " ")) { return fail(" ", status, { id: CompletionVariant.command }); } - - const description = parseRemainingLine(status); - if (description === null) { return fail(Token.message, status, undefined); } - - const command: Command = { - id: CommandVariant.display, - item, - display: description, - }; - - return succeed(command); -} -function parsePriceCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - if (!eat(status, " ")) { return fail(" ", status, { id: CompletionVariant.command }); } - - const price = parseInteger(status); - if (price === null) { return fail(Token.integer, status, undefined); } - - const command: Command = { - id: CommandVariant.price, - item, - price, - }; - - return succeed(command); -} -function parseIconCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - if (!eat(status, " ")) { return fail(" ", status, { id: CompletionVariant.command }); } - - const iconResult = parseIcon(status); - if (!iconResult.success) { return iconResult; } - const icon = iconResult.result; - - const command: Command = { - id: CommandVariant.icon, - item, - icon, - }; - - return succeed(command); -} -function parseParameterCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const parameterId = parseWord(status); - if (parameterId === null) { return fail(Token.word, status, undefined); } - - if (!eat(status, " ")) { return fail(" ", status, { id: CompletionVariant.command }); } - - const parameterType = parseWord(status); - if (parameterType === null) { return fail(Token.parameterType, status, undefined); } - - if (!eat(status, ":")) { return fail(":", status, { id: CompletionVariant.parameterType }); } - - let defaultValue: boolean | number | string; - switch (parameterType) { - case "bool": { - const defaultValueResult = parseBoolean(status); - if (defaultValueResult === null) { return fail(Token.boolean, status, { id: CompletionVariant.boolean }); } - defaultValue = defaultValueResult; - break; - } case "int": { - const defaultValueResult = parseInteger(status); - if (defaultValueResult === null) { return fail(Token.integer, status, undefined); } - defaultValue = defaultValueResult; - break; - } case "float": { - const defaultValueResult = parseFloat(status); - if (defaultValueResult === null) { return fail(Token.float, status, undefined); } - defaultValue = defaultValueResult; - break; - } case "string": { - const defaultValueResult = parseRemainingLine(status); - if (defaultValueResult === null) { return fail(Token.text, status, undefined); } - defaultValue = defaultValueResult; - break; - } default: - const errorStatus = status.clone(); - errorStatus.offset -= 2; - return fail(Token.parameterType, errorStatus, { id: CompletionVariant.parameterType }); - } - - const parameter: Parameter = { - identifier: parameterId, - defaultValue, - }; - - status.parameters.push(parameter); - - const command: Command = { - id: CommandVariant.parameter, - parameter, - }; - - return succeed(command); -} -function parsePoolCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const poolItem = parseRemainingLine(status); - if (poolItem === null) { return fail(Token.text, status, undefined); } - - status.pool.push(poolItem); - - const command: Command = { - id: CommandVariant.pool, - poolItem, - }; - - return succeed(command); -} -function parseAddPoolCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const amount = parseAmount(status) || 1; - - const command: Command = { - id: CommandVariant.addpool, - amount, - }; - - return succeed(command); -} -function parseSetCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const state = parseLogicIdentifier(status); - if (state === null) { return fail(Token.logicIdentifier, status, undefined); } - - const command: Command = { - id: CommandVariant.set, - state, - }; - - return succeed(command); -} -function parseIfCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const parameterId = parseWord(status); - if (parameterId === null) { return fail(Token.word, status, undefined); } - - const value = parseRemainingLine(status); - if (value === null) { return fail(Token.text, status, undefined); } - - const command: Command = { - id: CommandVariant.if, - parameterId, - value, - }; - - return succeed(command); -} - -export function parseCommand(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const commandIdentifier = parseWord(status); - if (commandIdentifier === null) { return fail(Token.commandIdentifier, status, { id: CompletionVariant.command }); } - - if (commandIdentifier === "flush") { return succeed({ id: CommandVariant.flush }); } - if (commandIdentifier === "endif") { return succeed({ id: CommandVariant.endif }); } - - if (!eat(status, " ")) { return fail(" ", status, { id: CompletionVariant.command }); } - - switch (commandIdentifier) { - case "include": return parseDependency(status, CommandVariant.include); - case "exclude": return parseDependency(status, CommandVariant.exclude); - case "add": return parseChangeItemPool(status, CommandVariant.add); - case "remove": return parseChangeItemPool(status, CommandVariant.remove); - case "name": return parseNameCommand(status); - case "display": return parseDisplayCommand(status); - case "description": return parseDescriptionCommand(status); - case "price": return parsePriceCommand(status); - case "icon": return parseIconCommand(status); - case "parameter": return parseParameterCommand(status); - case "pool": return parsePoolCommand(status); - case "addpool": return parseAddPoolCommand(status); - case "set": return parseSetCommand(status); - case "if": return parseIfCommand(status); - default: - const errorStatus = status.clone(); - errorStatus.offset -= 2; - return fail(Token.commandIdentifier, errorStatus, { id: CompletionVariant.command }); - } -} diff --git a/src/parser/parseIcon.ts b/src/parser/parseIcon.ts deleted file mode 100644 index d80f7fc..0000000 --- a/src/parser/parseIcon.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Completion, CompletionVariant } from "../completion"; -import Icon from "../icon"; -import GromIconVariant from "../icon/gromIcon"; -import LupoIconVariant from "../icon/lupoIcon"; -import OpherIconVariant from "../icon/opherIcon"; -import ShardIconVariant from "../icon/shardIcon"; -import SpellIconVariant from "../icon/spellIcon"; -import TuleyIconVariant from "../icon/tuleyIcon"; -import { ParseSuccess, Token, ParseFailure, parseInteger, succeed, parseWord, fail, eat, ParseStatus, parseRemainingLine } from "../parser"; - -type ParseIconSuccess = ParseSuccess; -function parseIconId(status: ParseStatus, typeId: "shard" | "spell" | "opher" | "lupo" | "grom" | "tuley", enumObject: Object, expected: Token, completion: Completion): ParseIconSuccess | ParseFailure { - if (!eat(status, ":")) { return fail(":", status, undefined); } - - const variant = parseInteger(status, true); - if (variant === null) { return fail(expected, status, completion); } - - if (!(variant in enumObject)) { return fail(expected, status, completion); } - - const icon: Icon = { - id: typeId, - iconId: variant, - }; - - return succeed(icon); -} -function parseIcon(status: ParseStatus): ParseIconSuccess | ParseFailure { - const iconType = parseWord(status); - if (iconType === null) { return fail(Token.iconType, status, { id: CompletionVariant.iconType }); } - - switch (iconType) { - case "shard": return parseIconId(status, iconType, ShardIconVariant, Token.shardIconValue, { id: CompletionVariant.shardIconValue }); - case "spell": return parseIconId(status, iconType, SpellIconVariant, Token.spellIconValue, { id: CompletionVariant.spellIconValue }); - case "opher": return parseIconId(status, iconType, OpherIconVariant, Token.opherIconValue, { id: CompletionVariant.opherIconValue }); - case "lupo": return parseIconId(status, iconType, LupoIconVariant, Token.lupoIconValue, { id: CompletionVariant.lupoIconValue }); - case "grom": return parseIconId(status, iconType, GromIconVariant, Token.gromIconValue, { id: CompletionVariant.gromIconValue }); - case "tuley": return parseIconId(status, iconType, TuleyIconVariant, Token.tuleyIconValue, { id: CompletionVariant.tuleyIconValue }); - case "file": - if (!eat(status, ":")) { return fail(":", status, undefined); } - - const path = parseRemainingLine(status); - if (path === null) { return fail(Token.path, status, undefined); } - - const icon: Icon = { - id: "file", - path, // TODO comments? - }; - - return succeed(icon); - default: return fail(Token.iconType, status, { id: CompletionVariant.iconType }); - } -} - -export default parseIcon; diff --git a/src/parser/parseItem.ts b/src/parser/parseItem.ts deleted file mode 100644 index fc04168..0000000 --- a/src/parser/parseItem.ts +++ /dev/null @@ -1,976 +0,0 @@ -import { Completion, CompletionVariant } from "../completion"; -import EquipmentVariants from "../equipment"; -import { Item, ItemVariant } from "../item"; -import { AbilityVariant } from "../item/ability"; -import { BonusItemVariant } from "../item/bonusItem"; -import { BonusUpgradeVariant } from "../item/bonusUpgrade"; -import { SysSubcommand, SysCommandVariant } from "../item/sysCommand"; -import { ProgressMessageVariant, ProgressVariant } from "../item/progressMessage"; -import { ResourceVariant } from "../item/resource"; -import { SetPointer, SetRange } from "../item/setUberState"; -import { ShardVariant } from "../item/shard"; -import { ShopCommandVariant, ShopSubcommand } from "../item/shopCommand"; -import { TeleporterVariant } from "../item/teleporter"; -import { WheelCommandVariant, WheelSubcommand } from "../item/wheelCommand"; -import ZoneVariants from "../zone"; -import { eat, fail, parseBoolean, ParseFailure, parseFloat, parseInteger, parseRemainingLine, ParseStatus, ParseSuccess, parseUberIdentifier, parseWord, succeed, Token } from "../parser"; -import parseIcon from "./parseIcon"; - -type ParseItemSuccess = ParseSuccess; - -function parseVariantItem( - status: ParseStatus, - variantEnum: Object, - itemVariant: ItemVariant.resource | ItemVariant.bonusItem | ItemVariant.bonusUpgrade | ItemVariant.relic, - completion: Completion, - expected: Token -): ParseItemSuccess | ParseFailure { - const variant = parseInteger(status, true); - if (variant === null || !(variant in variantEnum)) { return fail(expected, status, completion); } - - const item: Item = { - id: itemVariant, - variant, - }; - - return succeed(item); -} -function parseRemovableVariantItem( - status: ParseStatus, - variantEnum: Object, - itemVariant: ItemVariant.ability | ItemVariant.shard | ItemVariant.teleporter, - completion: Completion, - expected: Token -): ParseItemSuccess | ParseFailure { - let variant = parseInteger(status, true); - if (variant === null) { return fail(expected, status, completion); } - - let remove = false; - if (variant < 0) { - variant = -variant; - remove = true; - } - - if (!(variant in variantEnum)) { return fail(expected, status, completion); } - - const item: Item = { - id: itemVariant, - variant, - remove, - }; - - return succeed(item); -} - -function parseSpiritLight(status: ParseStatus): ParseItemSuccess | ParseFailure { - const amount = parseInteger(status, true); - if (amount === null) { return fail(Token.integer, status, undefined); } - - const item: Item = { - id: ItemVariant.spiritLight, - amount, - }; - - return succeed(item); -} -function parseResource(status: ParseStatus): ParseItemSuccess | ParseFailure { - return parseVariantItem(status, ResourceVariant, ItemVariant.resource, { id: CompletionVariant.resource }, Token.resourceIdentifier); -} -function parseAbility(status: ParseStatus): ParseItemSuccess | ParseFailure { - return parseRemovableVariantItem(status, AbilityVariant, ItemVariant.ability, { id: CompletionVariant.ability }, Token.abilityIdentifier); -} -function parseShard(status: ParseStatus): ParseItemSuccess | ParseFailure { - return parseRemovableVariantItem(status, ShardVariant, ItemVariant.shard, { id: CompletionVariant.shard }, Token.shardIdentifier); -} -type ParseCommandSuccess = ParseSuccess; -function parseSetResource(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const resource = parseInteger(status); - if (resource === null || !(resource in ResourceVariant)) { return fail(Token.resourceIdentifier, status, { id: CompletionVariant.resource }); } - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.resource }); } - - const amount = parseInteger(status); - if (amount === null) { return fail(Token.integer, status, undefined); } - - const command: SysSubcommand = { - id: SysCommandVariant.setResource, - resource, - amount - }; - - return succeed(command); -} -function parseKwolokStatue(status: ParseStatus): ParseCommandSuccess | ParseFailure { - if (!eat(status, "0")) { return fail(Token.integer, status, undefined); } - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const value = parseInteger(status); - if (value === null || ![0, 1].includes(value)) { return fail(Token.integer, status, undefined); } - - const command: SysSubcommand = { - id: SysCommandVariant.kwolokStatue, - value, - }; - - return succeed(command); -} -function parseWarp(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const x = parseFloat(status); - if (x === null) { return fail(Token.float, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const y = parseFloat(status); - if (y === null) { return fail(Token.float, status, undefined); } - - const command: SysSubcommand = { - id: SysCommandVariant.warp, - x, - y, - }; - - return succeed(command); -} -function parseApplier(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const weird = parseInteger(status); - if (weird === null) { return fail(Token.integer, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const stuff = parseInteger(status); - if (stuff === null) { return fail(Token.integer, status, undefined); } - - const command: SysSubcommand = { - id: SysCommandVariant.applier, - weird, - stuff, - }; - - return succeed(command); -} -function parseSetCurrentResource(status: ParseStatus, variant: SysCommandVariant.setHealth | SysCommandVariant.setEnergy | SysCommandVariant.setSpiritLight): ParseCommandSuccess | ParseFailure { - const amount = parseInteger(status); - if (amount === null) { return fail(Token.integer, status, undefined); } - - const command: SysSubcommand = { - id: variant, - amount, - }; - - return succeed(command); -} -function parseSetHealth(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseSetCurrentResource(status, SysCommandVariant.setHealth); -} -function parseSetEnergy(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseSetCurrentResource(status, SysCommandVariant.setEnergy); -} -function parseSetSpiritLight(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseSetCurrentResource(status, SysCommandVariant.setSpiritLight); -} -function parseEquip(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const slot = parseInteger(status); - if (slot === null || !(slot === 0 || slot === 1 || slot === 2)) { return fail(Token.slot, status, { id: CompletionVariant.slot }); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const equipment = parseInteger(status); - if (equipment === null || !(equipment in EquipmentVariants)) { return fail(Token.equipment, status, { id: CompletionVariant.equipment }); } - - const command: SysSubcommand = { - id: SysCommandVariant.equip, - slot, - equipment, - }; - - return succeed(command); -} -function parseUnequip(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const equipment = parseInteger(status); - if (equipment === null || !(equipment in EquipmentVariants)) { return fail(Token.equipment, status, { id: CompletionVariant.equipment }); } - - const command: SysSubcommand = { - id: SysCommandVariant.unequip, - equipment, - }; - - return succeed(command); -} -function parseTriggerBind(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const bind = parseWord(status); - if (bind === null) { return fail(Token.word, status, { id: CompletionVariant.keybind }); } - - const command: SysSubcommand = { - id: SysCommandVariant.triggerBind, - bind, - }; - - return succeed(command); -} -function parseIf(status: ParseStatus, variant: SysCommandVariant.ifEqual | SysCommandVariant.ifGreater | SysCommandVariant.ifLess): ParseCommandSuccess | ParseFailure { - const uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const uberIdentifier = uberIdentifierResult.result; - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.uberId, group: uberIdentifier.group }); } - - const value = parseFloat(status); - if (value === null) { return fail(Token.float, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - const command: SysSubcommand = { - id: variant, - uberIdentifier, - value, - item, - }; - - return succeed(command); -} -function parseIfEqual(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseIf(status, SysCommandVariant.ifEqual); -} -function parseIfGreater(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseIf(status, SysCommandVariant.ifGreater); -} -function parseIfLess(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseIf(status, SysCommandVariant.ifLess); -} -function parseToggleSync(status: ParseStatus, variant: SysCommandVariant.disableSync | SysCommandVariant.enableSync): ParseCommandSuccess | ParseFailure { - const uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const uberIdentifier = uberIdentifierResult.result; - - const command: SysSubcommand = { - id: variant, - uberIdentifier, - }; - - return succeed(command); -} -function parseDisableSync(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseToggleSync(status, SysCommandVariant.disableSync); -} -function parseEnableSync(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseToggleSync(status, SysCommandVariant.enableSync); -} -function parseCreateWarpIcon(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const warpId = parseInteger(status); - if (warpId === null) { return fail(Token.integer, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const x = parseFloat(status); - if (x === null) { return fail(Token.float, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const y = parseFloat(status); - if (y === null) { return fail(Token.float, status, undefined); } - - let label; - if (eat(status, "|")) { - label = parseRemainingLine(status); - if (label === null) { return fail(Token.text, status, undefined); } - } - - const command: SysSubcommand = { - id: SysCommandVariant.createWarpIcon, - warpId, - x, - y, - label, - }; - - return succeed(command); -} -function parseDestroyWarpIcon(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const warpId = parseInteger(status); - if (warpId === null) { return fail(Token.integer, status, undefined); } - - const command: SysSubcommand = { - id: SysCommandVariant.destroyWarpIcon, - warpId, - }; - - return succeed(command); -} -function parseIfBounds(status: ParseStatus): ParseCommandSuccess | ParseFailure { - const x1 = parseFloat(status); - if (x1 === null) { return fail(Token.float, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const y1 = parseFloat(status); - if (y1 === null) { return fail(Token.float, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const x2 = parseFloat(status); - if (x2 === null) { return fail(Token.float, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const y2 = parseFloat(status); - if (y2 === null) { return fail(Token.float, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - const command: SysSubcommand = { - id: SysCommandVariant.ifBounds, - x1, - y1, - x2, - y2, - item, - }; - - return succeed(command); -} -function parseIfSelf(status: ParseStatus, variant: SysCommandVariant.ifSelfEqual | SysCommandVariant.ifSelfGreater | SysCommandVariant.ifSelfLess): ParseCommandSuccess | ParseFailure { - const value = parseFloat(status); - if (value === null) { return fail(Token.float, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - const command: SysSubcommand = { - id: variant, - value, - item, - }; - - return succeed(command); -} -function parseIfSelfEqual(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseIfSelf(status, SysCommandVariant.ifSelfEqual); -} -function parseIfSelfGreater(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseIfSelf(status, SysCommandVariant.ifSelfGreater); -} -function parseIfSelfLess(status: ParseStatus): ParseCommandSuccess | ParseFailure { - return parseIfSelf(status, SysCommandVariant.ifSelfLess); -} -function parseStringCommand(status: ParseStatus, id: SysCommandVariant.saveString | SysCommandVariant.appendString): ParseCommandSuccess | ParseFailure { - const stringId = parseInteger(status); - if (stringId === null) { return fail(Token.integer, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const string = parseRemainingLine(status); - if (string === null) { return fail(Token.text, status, undefined); } - - const command: SysSubcommand = { - id, - stringId, - string, - }; - - return succeed(command); -} -function parseSaveString(status: ParseStatus) { - return parseStringCommand(status, SysCommandVariant.saveString); -} -function parseAppendString(status: ParseStatus) { - return parseStringCommand(status, SysCommandVariant.appendString); -} -function parseSubcommand(status: ParseStatus, commandId: number): ParseCommandSuccess | ParseFailure { - switch (commandId) { - case SysCommandVariant.setResource: return parseSetResource(status); - case SysCommandVariant.kwolokStatue: return parseKwolokStatue(status); - case SysCommandVariant.warp: return parseWarp(status); - case SysCommandVariant.applier: return parseApplier(status); - case SysCommandVariant.setHealth: return parseSetHealth(status); - case SysCommandVariant.setEnergy: return parseSetEnergy(status); - case SysCommandVariant.setSpiritLight: return parseSetSpiritLight(status); - case SysCommandVariant.equip: return parseEquip(status); - case SysCommandVariant.triggerBind: return parseTriggerBind(status); - case SysCommandVariant.ifEqual: return parseIfEqual(status); - case SysCommandVariant.ifGreater: return parseIfGreater(status); - case SysCommandVariant.ifLess: return parseIfLess(status); - case SysCommandVariant.disableSync: return parseDisableSync(status); - case SysCommandVariant.enableSync: return parseEnableSync(status); - case SysCommandVariant.createWarpIcon: return parseCreateWarpIcon(status); - case SysCommandVariant.destroyWarpIcon: return parseDestroyWarpIcon(status); - case SysCommandVariant.ifBounds: return parseIfBounds(status); - case SysCommandVariant.ifSelfEqual: return parseIfSelfEqual(status); - case SysCommandVariant.ifSelfGreater: return parseIfSelfGreater(status); - case SysCommandVariant.ifSelfLess: return parseIfSelfLess(status); - case SysCommandVariant.unequip: return parseUnequip(status); - case SysCommandVariant.saveString: return parseSaveString(status); - case SysCommandVariant.appendString: return parseAppendString(status); - default: - const errorStatus = status.clone(); - errorStatus.offset -= 2; - return fail(Token.sysCommandIdentifier, errorStatus, { id: CompletionVariant.sysCommand }); - } -} -function parseCommand(status: ParseStatus): ParseItemSuccess | ParseFailure { - const commandId = parseInteger(status); - if (commandId === null) { return fail(Token.sysCommandIdentifier, status, { id: CompletionVariant.sysCommand }); } - - // handle the commands without further parts - if (commandId === SysCommandVariant.autosave || commandId === SysCommandVariant.checkpoint) { - const item: Item = { - id: ItemVariant.sysCommand, - subcommand: { - id: commandId, - }, - }; - - return succeed(item); - } - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.sysCommand }); } - - const subcommandResult = parseSubcommand(status, commandId); - if (!subcommandResult.success) { return subcommandResult; } - const subcommand = subcommandResult.result; - - const item: Item = { - id: ItemVariant.sysCommand, - subcommand, - }; - - return succeed(item); -} -function parseTeleporter(status: ParseStatus): ParseItemSuccess | ParseFailure { - return parseRemovableVariantItem(status, TeleporterVariant, ItemVariant.teleporter, { id: CompletionVariant.teleporter }, Token.teleporterIdentifier); -} -function parseMessage(status: ParseStatus): ParseItemSuccess | ParseFailure { - const message = parseRemainingLine(status); - if (message === null) { return fail(Token.message, status, undefined); } - - const item: Item = { - id: ItemVariant.message, - message, // TODO this proper - }; - - return succeed(item); -} -type ParsePointerSuccess = ParseSuccess; -function parsePointer(status: ParseStatus): ParsePointerSuccess | ParseFailure | null { - if (!eat(status, "$(")) { return null; } - - const uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const pointerIdentifier = uberIdentifierResult.result; - - if (!eat(status, ")")) { return fail(")", status, { id: CompletionVariant.uberId, group: pointerIdentifier.group }); } - - // TODO why manual? - return { - success: true, - result: { pointerIdentifier }, - }; -} -type ParseSetValueOrPointerSuccess = ParseSuccess; -function parseSetValueOrPointer(status: ParseStatus, parseValue: (status: ParseStatus) => Value | null, expected: Token, completion: Completion | undefined): ParseSetValueOrPointerSuccess | ParseFailure { - const pointerResult = parsePointer(status); - if (pointerResult !== null) { - if (!pointerResult.success) { return pointerResult; } - const value = pointerResult.result; - return succeed(value); - } - - const value = parseValue(status); - if (value === null) { return fail(expected, status, completion); } - - return succeed(value); -} -type ParseSetRangeSuccess = ParseSuccess>; -function parseSetRange(status: ParseStatus, parseValue: (status: ParseStatus) => Value | null, expected: Token, completion: Completion | undefined): ParseSetRangeSuccess | ParseFailure { - const lowerResult = parseSetValueOrPointer(status, parseValue, expected, completion); - if (!lowerResult.success) { return lowerResult; } - const lower = lowerResult.result; - - if (!eat(status, ",")) { - let lowerCompletion: Completion | undefined; - if ("pointerIdentifier" in lower) { - lowerCompletion = { id: CompletionVariant.uberId, group: lower.pointerIdentifier.group }; - } else { - lowerCompletion = completion; - } - return fail(",", status, lowerCompletion); - } - - const upperResult = parseSetValueOrPointer(status, parseValue, expected, completion); - if (!upperResult.success) { return upperResult; } - const upper = upperResult.result; - - if (!eat(status, "]")) { - let upperCompletion: Completion | undefined; - if ("pointerIdentifier" in upper) { - upperCompletion = { id: CompletionVariant.uberId, group: upper.pointerIdentifier.group }; - } else { - upperCompletion = completion; - } - return fail("]", status, upperCompletion); - } - - return { - success: true, - result: { - lower, - upper, - } - }; -} -type ParseSetValueSuccess = ParseSuccess>; -function parseSetValue(status: ParseStatus, parseValue: (status: ParseStatus) => Value | null, expected: Token, completion: Completion | undefined): ParseSetValueSuccess | ParseFailure { - if (eat(status, "[")) { - return parseSetRange(status, parseValue, expected, completion ); - } - return parseSetValueOrPointer(status, parseValue, expected, completion); -} -function parseSetUberState(status: ParseStatus): ParseItemSuccess | ParseFailure { - const uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const uberIdentifier = uberIdentifierResult.result; - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.uberId, group: uberIdentifier.group }); } - - type UberType = "bool" | "teleporter" | "byte" | "int" | "float"; - let uberType: UberType | undefined; - const remaining = status.remaining; - for (const type of [ "bool", "teleporter", "byte", "int", "float" ]) { - if (remaining.startsWith(type)) { - status.progress(type.length); - uberType = type as UberType; - break; - } - } - if (uberType === undefined) { return fail(Token.uberStateType, status, { id: CompletionVariant.uberStateType }); } - - if (!eat(status, "|")) { return fail(Token.uberStateType, status, { id: CompletionVariant.uberStateType }); } - - let sign: boolean | undefined; - if (eat(status, "+")) { - sign = true; - } else if (eat(status, "-")) { - sign = false; - } - - let valueResult; - switch (uberType) { - case "bool": - case "teleporter": - valueResult = parseSetValue(status, parseBoolean, Token.boolean, { id: CompletionVariant.boolean }); - break; - case "byte": - case "int": - valueResult = parseSetValue(status, parseInteger, Token.integer, undefined); - break; - case "float": - valueResult = parseSetValue(status, parseFloat, Token.float, undefined); - break; - } - - if (!valueResult.success) { return valueResult; } - const value = valueResult.result; - - let skip = 0; - if (eat(status, "|")) { - eat(status, "skip="); - - const skipResult = parseInteger(status); - if (skipResult === null) { return fail(Token.integer, status, undefined); } - skip = skipResult; - } - - const item: Item = { - id: ItemVariant.setUberState, - uberIdentifier, - expression: { - type: uberType, - sign, - value, - }, - skip, - }; - - return succeed(item); -} -function parseWater(status: ParseStatus): ParseItemSuccess | ParseFailure { - const water = parseInteger(status); - if (water === null) { return fail(Token.water, status, { id: CompletionVariant.water }); } - - if (water !== 0) { return fail(Token.water, status, undefined); } - - const item: Item = { - id: ItemVariant.water, - }; - - return succeed(item); -} -function parseBonusItem(status: ParseStatus): ParseItemSuccess | ParseFailure { - return parseVariantItem(status, BonusItemVariant, ItemVariant.bonusItem, { id: CompletionVariant.bonusItem }, Token.bonusItem); -} -function parseBonusUpgrade(status: ParseStatus): ParseItemSuccess | ParseFailure { - return parseVariantItem(status, BonusUpgradeVariant, ItemVariant.bonusUpgrade, { id: CompletionVariant.bonusUpgrade }, Token.bonusUpgrade); -} -function parseRelic(status: ParseStatus): ParseItemSuccess | ParseFailure { - return parseVariantItem(status, ZoneVariants, ItemVariant.relic, { id: CompletionVariant.zone }, Token.zone); -} -function parseProgressMessage(status: ParseStatus): ParseItemSuccess | ParseFailure { - const progressId = parseInteger(status); - if (progressId === null) { return fail(Token.progressIdentifier, status, { id: CompletionVariant.progressMessage }); } - - const id = ItemVariant.progressMessage; - - switch (progressId) { - case ProgressVariant.relic: - case ProgressVariant.pickup: - case ProgressVariant.goalmode: { - const progressVariant: ProgressMessageVariant = { - id: progressId, - }; - const item: Item = { - id, - progressVariant, - }; - - return succeed(item); - } case ProgressVariant.zoneRelic: { - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.sysCommand }); } - - const zone = parseInteger(status, true); - if (zone === null || !(zone in ZoneVariants)) { return fail(Token.zone, status, { id: CompletionVariant.zone }); } - - const item: Item = { - id, - progressVariant: { - id: progressId, - zone, - }, - }; - - return succeed(item); - } default: return fail(Token.progressIdentifier, status, { id: CompletionVariant.progressMessage }); - } -} -type ParseWheelCommandSuccess = ParseSuccess; -function parseWheelSetText(status: ParseStatus, wheel: number, position: number, variant: WheelCommandVariant.setText | WheelCommandVariant.setDescription): ParseWheelCommandSuccess | ParseFailure { - const text = parseRemainingLine(status); - if (text === null) { return fail(Token.message, status, undefined); } - - const subcommand: WheelSubcommand = { - id: variant, - wheel, - position, - text, // TODO this proper - }; - - return succeed(subcommand); -} -function parseWheelSetIcon(status: ParseStatus, wheel: number, position: number): ParseWheelCommandSuccess | ParseFailure { - const iconResult = parseIcon(status); - if (!iconResult.success) { return iconResult; } - const icon = iconResult.result; - - const subcommand: WheelSubcommand = { - id: WheelCommandVariant.setIcon, - wheel, - position, - icon, - }; - - return succeed(subcommand); -} -function parseWheelSetColor(status: ParseStatus, wheel: number, position: number): ParseWheelCommandSuccess | ParseFailure { - const red = parseInteger(status); - if (red === null) { return fail(Token.integer, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const green = parseInteger(status); - if (green === null) { return fail(Token.integer, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const blue = parseInteger(status); - if (blue === null) { return fail(Token.integer, status, undefined); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const alpha = parseInteger(status); - if (alpha === null) { return fail(Token.integer, status, undefined); } - - const subcommand: WheelSubcommand = { - id: WheelCommandVariant.setColor, - wheel, - position, - red, - green, - blue, - alpha, - }; - - return succeed(subcommand); -} -function parseWheelSetAction(status: ParseStatus, wheel: number, position: number): ParseWheelCommandSuccess | ParseFailure { - const bind = parseInteger(status); - if (bind === null || !(bind === 0 || bind === 1 || bind === 2 || bind === 3)) { return fail(Token.wheelItemBind, status, { id: CompletionVariant.wheelItemBind }); } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - const itemResult = parseItem(status); - if (!itemResult.success) { return itemResult; } - const item = itemResult.result; - - const subcommand: WheelSubcommand = { - id: WheelCommandVariant.setAction, - wheel, - position, - bind, - item, - }; - - return succeed(subcommand); -} -function parseWheelCommand(status: ParseStatus): ParseItemSuccess | ParseFailure { - const commandId = parseInteger(status); - if (commandId === null) { return fail(Token.wheelCommandIdentifier, status, { id: CompletionVariant.wheelCommand }); } - - const id = ItemVariant.wheelCommand; - - // handle the command without further parts - if (commandId === WheelCommandVariant.clear) { - const item: Item = { - id, - subcommand: { - id: commandId, - }, - }; - - return succeed(item); - } - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.wheelCommand }); } - - // All remaining commands take the wheel as first parameter - const wheel = parseInteger(status); - if (wheel === null) { return fail(Token.integer, status, undefined); } - - // handle the command without further parts - if (commandId === WheelCommandVariant.switch) { - const item: Item = { - id: ItemVariant.wheelCommand, - subcommand: { - id: commandId, - wheel, - } - }; - - return succeed(item); - } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - // handle the command that doesn't take the position as next parameter - if (commandId === WheelCommandVariant.setSticky) { - const sticky = parseBoolean(status); - if (sticky === null) { return fail(Token.boolean, status, { id: CompletionVariant.boolean }); } - - const item: Item = { - id: ItemVariant.wheelCommand, - subcommand: { - id: commandId, - wheel, - sticky, - } - }; - - return succeed(item); - } - - // All remaining commands take the position as next parameter - const position = parseInteger(status); - if (position === null || !([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ].includes(position))) { return fail(Token.wheelItemPosition, status, undefined); } - - // handle the command without further parts - if (commandId === WheelCommandVariant.remove) { - const item: Item = { - id: ItemVariant.wheelCommand, - subcommand: { - id: commandId, - wheel, - position, - } - }; - - return succeed(item); - } - - if (!eat(status, "|")) { return fail("|", status, undefined); } - - let subcommandResult: ParseWheelCommandSuccess | ParseFailure; - switch (commandId) { - case WheelCommandVariant.setText: - subcommandResult = parseWheelSetText(status, wheel, position, WheelCommandVariant.setText); - break; - case WheelCommandVariant.setDescription: - subcommandResult = parseWheelSetText(status, wheel, position, WheelCommandVariant.setDescription); - break; - case WheelCommandVariant.setIcon: - subcommandResult = parseWheelSetIcon(status, wheel, position); - break; - case WheelCommandVariant.setColor: - subcommandResult = parseWheelSetColor(status, wheel, position); - break; - case WheelCommandVariant.setAction: - subcommandResult = parseWheelSetAction(status, wheel, position); - break; - default: - const errorStatus = status.clone(); - errorStatus.offset -= 2; - return fail(Token.wheelCommandIdentifier, errorStatus, { id: CompletionVariant.wheelCommand }); - } - - if (!subcommandResult.success) { return subcommandResult; } - const subcommand = subcommandResult.result; - - const item: Item = { - id: ItemVariant.wheelCommand, - subcommand, - }; - - return succeed(item); -} -type ParseShopCommandSuccess = ParseSuccess; -function parseShopSetIcon(status: ParseStatus): ParseShopCommandSuccess | ParseFailure { - const uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const uberIdentifier = uberIdentifierResult.result; - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.sysCommand }); } - - const iconResult = parseIcon(status); - if (!iconResult.success) { return iconResult; } - const icon = iconResult.result; - - const subcommand: ShopSubcommand = { - id: ShopCommandVariant.setIcon, - uberIdentifier, - icon, - }; - - return succeed(subcommand); -} -function parseShopSetText(status: ParseStatus, variant: ShopCommandVariant.setTitle | ShopCommandVariant.setDescription): ParseShopCommandSuccess | ParseFailure { - const uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const uberIdentifier = uberIdentifierResult.result; - - let text = null; - if (eat(status, "|")) { - text = parseRemainingLine(status) || ""; - } - - const subcommand: ShopSubcommand = { - id: variant, - uberIdentifier, - text, - }; - - return succeed(subcommand); -} -function parseShopSetFlag(status: ParseStatus, variant: ShopCommandVariant.setLocked | ShopCommandVariant.setVisible): ParseShopCommandSuccess | ParseFailure { - const uberIdentifierResult = parseUberIdentifier(status); - if (!uberIdentifierResult.success) { return uberIdentifierResult; } - const uberIdentifier = uberIdentifierResult.result; - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.sysCommand }); } - - const flag = parseBoolean(status); - if (flag === null) { return fail(Token.boolean, status, { id: CompletionVariant.boolean }); } - - const subcommand: ShopSubcommand = { - id: variant, - uberIdentifier, - flag, - }; - - return succeed(subcommand); -} -function parseShopCommand(status: ParseStatus): ParseItemSuccess | ParseFailure { - const commandId = parseInteger(status); - if (commandId === null) { return fail(Token.shopCommandIdentifier, status, { id: CompletionVariant.shopCommand }); } - - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.sysCommand }); } - - let subcommandResult: ParseShopCommandSuccess | ParseFailure; - switch (commandId) { - case ShopCommandVariant.setIcon: - subcommandResult = parseShopSetIcon(status); - break; - case ShopCommandVariant.setTitle: - subcommandResult = parseShopSetText(status, ShopCommandVariant.setTitle); - break; - case ShopCommandVariant.setDescription: - subcommandResult = parseShopSetText(status, ShopCommandVariant.setDescription); - break; - case ShopCommandVariant.setLocked: - subcommandResult = parseShopSetFlag(status, ShopCommandVariant.setLocked); - break; - case ShopCommandVariant.setVisible: - subcommandResult = parseShopSetFlag(status, ShopCommandVariant.setVisible); - break; - default: - const errorStatus = status.clone(); - errorStatus.offset -= 2; - return fail(Token.shopCommandIdentifier, errorStatus, { id: CompletionVariant.shopCommand }); - } - - if (!subcommandResult.success) { return subcommandResult; } - const subcommand = subcommandResult.result; - - const item: Item = { - id: ItemVariant.shopCommand, - subcommand, - }; - - return succeed(item); -} - -export function parseItem(status: ParseStatus): ParseItemSuccess | ParseFailure { - const itemId = parseInteger(status); - if (itemId === null) { return fail(Token.itemIdentifier, status, { id: CompletionVariant.item }); } - - // Each item has at least two parts, so parsing the separator here is just more efficient - if (!eat(status, "|")) { return fail("|", status, { id: CompletionVariant.item }); } - - switch (itemId) { - case ItemVariant.spiritLight: return parseSpiritLight(status); - case ItemVariant.resource: return parseResource(status); - case ItemVariant.ability: return parseAbility(status); - case ItemVariant.shard: return parseShard(status); - case ItemVariant.sysCommand: return parseCommand(status); - case ItemVariant.teleporter: return parseTeleporter(status); - case ItemVariant.message: return parseMessage(status); - case ItemVariant.setUberState: return parseSetUberState(status); - case ItemVariant.water: return parseWater(status); - case ItemVariant.bonusItem: return parseBonusItem(status); - case ItemVariant.bonusUpgrade: return parseBonusUpgrade(status); - case ItemVariant.relic: return parseRelic(status); - case ItemVariant.progressMessage: return parseProgressMessage(status); - case ItemVariant.wheelCommand: return parseWheelCommand(status); - case ItemVariant.shopCommand: return parseShopCommand(status); - default: - const errorStatus = status.clone(); - errorStatus.offset -= 2; - return fail(Token.itemIdentifier, errorStatus, { id: CompletionVariant.item }); - } -} diff --git a/syntaxes/ori-wotw-header.tmLanguage.json b/syntaxes/ori-wotw-header.tmLanguage.json index 13f495e..f8288d9 100644 --- a/syntaxes/ori-wotw-header.tmLanguage.json +++ b/syntaxes/ori-wotw-header.tmLanguage.json @@ -37,7 +37,7 @@ } }, "uberState": { - "begin": "^(!)?(\\d+\\|\\d+(?:=\\d+)?\\|)", + "begin": "^(!)?(\\d+\\|\\d+(?:(?:=|<=|<|>=|>)\\d+)?\\|)", "end": "$|(?=//)", "beginCaptures": { "1": { "name": "keyword" }, @@ -711,7 +711,7 @@ "name": "keyword" }, "annotation": { - "match": "^#\\w+", + "match": "^#[^\n]*", "name": "keyword" }, "placeholder": { diff --git a/tsconfig.json b/tsconfig.json index b65c745..68936c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "target": "es6", "outDir": "out", "lib": [ - "es6" + "es6", + "dom" ], "sourceMap": true, "rootDir": "src", diff --git a/wasm/.gitignore b/wasm/.gitignore new file mode 100644 index 0000000..fbd7c91 --- /dev/null +++ b/wasm/.gitignore @@ -0,0 +1,2 @@ +target/* +Cargo.lock diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml new file mode 100644 index 0000000..7491057 --- /dev/null +++ b/wasm/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "wasm" +description = "WASM binds for the project" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +wotw_seedgen = "0.1.2" +wasm_bindgen_helper_macros = "0.0.2" +wasm-bindgen = "0.2" +js-sys = "0.3" +rand = "0.8" +getrandom = { version = "0.2", features = ["js"] } + +[profile.release] +# Tell `rustc` to optimize for small code size. +opt-level = "s" diff --git a/wasm/src/describe.rs b/wasm/src/describe.rs new file mode 100644 index 0000000..bd039ff --- /dev/null +++ b/wasm/src/describe.rs @@ -0,0 +1,49 @@ +use js_sys::JsString; + +use wotw_seedgen::header::{Annotation, HeaderCommand, GoalmodeHack, TimerDefinition, VPickup}; + +pub fn annotation(annotation: &Annotation) -> Vec { + let description = match annotation { + Annotation::Hide => "Hide this header from the public interface".to_string(), + Annotation::Category(category) => format!("Show this header under the {category} category"), + }; + let description = format!("**Annotation**\n\n{description}"); + vec![description.into()] +} + +pub fn command(command: &HeaderCommand) -> Vec { + let description = match command { + HeaderCommand::Include { name } => format!("Include header {name}"), + HeaderCommand::Exclude { name } => format!("Exclude header {name}"), + HeaderCommand::Add { item, amount } => format!("Add this item {amount} times to the item pool:\n\n{item}"), + HeaderCommand::Remove { item, amount } => format!("Remove this item {amount} times from the item pool:\n\n{item}"), + HeaderCommand::Name { item, name } => format!("Set the name of this item to {name}:\n\n{item}"), + HeaderCommand::Display { item, name } => format!("Set the display name of this item to {name}:\n\n{item}"), + HeaderCommand::Description { item, description } => format!("Set the shop description of this item to {description}:\n\n{item}"), + HeaderCommand::Price { item, price } => format!("Set the shop price of this item to {price}:\n\n{item}"), + HeaderCommand::Icon { item, icon } => format!("Set the shop icon of this item to {icon}:\n\n{item}"), + HeaderCommand::Parameter { identifier, default } => format!("Add a parameter \"${identifier}\" with default value \"${default}\""), + HeaderCommand::Set { state } => format!("Sets the logic state \"{state}\" to be met"), + HeaderCommand::If { parameter, value } => format!("Opens a block that will only be added to the seed if the parameter \"{parameter}\" is \"${value}\""), + HeaderCommand::EndIf => "Closes one if block".to_string(), + HeaderCommand::GoalmodeHack(hack) => match hack { + GoalmodeHack::Trees => "Enables the All Trees goalmode".to_string(), + GoalmodeHack::Wisps => "Enables the All Wisps goalmode".to_string(), + GoalmodeHack::Quests => "Enables the All Quests goalmode".to_string(), + GoalmodeHack::Relics { chance, amount } => format!("Enables the Relics goalmode with {chance} relic chance per area or {amount} relics"), + }, + }; + let description = format!("**Command**\n\n{description}"); + vec![description.into()] +} + +pub fn timer(timer: &TimerDefinition) -> Vec { + let description = format!("**Timer**\n\nBind a timer on {} to a toggle on {}", timer.counter, timer.switch); + vec![description.into()] +} + +pub fn pickup(pickup: &VPickup) -> Vec { + let location = format!("**Location**\n\n{}", pickup.trigger); + let item = format!("**Item**\n\n{}", pickup.item); + vec![location.into(), item.into()] +} diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs new file mode 100644 index 0000000..9ba1ded --- /dev/null +++ b/wasm/src/lib.rs @@ -0,0 +1,117 @@ +mod describe; + +use std::ops::Deref; + +use wasm_bindgen::prelude::*; +use js_sys::JsString; + +use wotw_seedgen::Header; +use wotw_seedgen::languages::ParseError as SeedgenParseError; +use wotw_seedgen::header::HeaderContent as SeedgenHeaderContent; + +use wasm_bindgen_helper_macros::{wrapper_type, wrapper_list}; + +#[wasm_bindgen(js_name = "checkErrors")] +/// Parses the input string to check for errors +/// Returns all `ParseError`s that occured, or an empty array +pub fn check_errors(input: String) -> parse_error_list::ReturnArray { + let errors = Header::parse(input, &mut rand::thread_rng()) + .err() + .unwrap_or_default() + .deref() + .to_owned() + .into_iter() + .map(ParseError::from) + .collect::>(); + ParseErrorList::from(errors).into_js_array() +} + +wrapper_list! { + #[wasm_bindgen] + pub struct ParseErrorList { + inner: IntoIter, + } + mod parse_error_list { typescript_type = "ParseError[]" } +} + +wrapper_type! { + #[wasm_bindgen] + #[doc = " Contains information about an error that occured while parsing"] + pub struct ParseError { + inner: SeedgenParseError, + } +} +#[wasm_bindgen] +impl ParseError { + #[wasm_bindgen(getter)] + /// Summary of the problem that caused this error + pub fn message(&self) -> String { + self.inner.to_string() + } + #[wasm_bindgen(getter)] + /// `Range` that can be used to index the source file to find the source of the error + pub fn range(&self) -> Range { + self.inner.range.clone().into() + } + #[wasm_bindgen(getter)] + /// A suggestion for what kind of syntax may belong here + pub fn completion(&self) -> Option { + self.inner.suggestion.clone() + } +} + +wrapper_type! { + #[wasm_bindgen] + #[doc = " A range between two bounds, where `start` is included, but `end` is excluded"] + pub struct Range { + inner: core::ops::Range, + } +} +#[wasm_bindgen] +impl Range { + #[wasm_bindgen(getter)] + pub fn start(&self) -> usize { + self.inner.start + } + #[wasm_bindgen(getter)] + pub fn end(&self) -> usize { + self.inner.end + } +} + +#[wasm_bindgen(js_name = "parseLine")] +/// Parses one line of the input string +/// Returns a `HeaderContent` if successful, or `undefined` if the line caused a parsing error +pub fn parse_line(input: String) -> Option { + let content = Header::parse(input, &mut rand::thread_rng()) + .ok()? + .contents.pop()? + .into(); + Some(content) +} + +wrapper_type! { + #[wasm_bindgen] + #[doc = " Contains information about a line of header syntax"] + pub struct HeaderContent { + inner: SeedgenHeaderContent, + } +} +#[wasm_bindgen] +impl HeaderContent { + /// Returns a description of this `HeaderContent` + /// On pickup lines, the first element will be a description of the location and the second element a description of the item + /// On other lines, the array will only contain one element + pub fn description(&self) -> Option> { + let description = match &self.inner { + SeedgenHeaderContent::OuterDocumentation(_) + | SeedgenHeaderContent::InnerDocumentation(_) + | SeedgenHeaderContent::Flags(_) => return None, + SeedgenHeaderContent::Annotation(annotation) => describe::annotation(annotation), + SeedgenHeaderContent::Command(command) => describe::command(command), + SeedgenHeaderContent::Timer(timer) => describe::timer(timer), + SeedgenHeaderContent::Pickup(pickup) => describe::pickup(pickup), + }; + Some(description) + } +}