From 58407ecc9fb80000bf2d788e651d30e82e5a3e15 Mon Sep 17 00:00:00 2001 From: Daniel Seiller Date: Sun, 7 May 2023 21:29:21 +0200 Subject: [PATCH] Add web-based .packed explorer, updated parser and ghidra untility script --- scrapper_web/.gitignore | 24 + scrapper_web/.vscode/extensions.json | 3 + scrapper_web/README.md | 47 + scrapper_web/index.html | 13 + scrapper_web/jsconfig.json | 33 + scrapper_web/package.json | 26 + scrapper_web/pnpm-lock.yaml | 1777 +++++++++++++++++ scrapper_web/postcss.config.cjs | 11 + scrapper_web/public/vite.svg | 1 + scrapper_web/scrapper/.gitignore | 14 + scrapper_web/scrapper/Cargo.toml | 31 + scrapper_web/scrapper/README.md | 23 + scrapper_web/scrapper/src/lib.rs | 155 ++ scrapper_web/src/App.svelte | 13 + scrapper_web/src/app.pcss | 109 + scrapper_web/src/lib/Explorer.svelte | 52 + scrapper_web/src/lib/TreeView.svelte | 56 + scrapper_web/src/main.js | 6 + scrapper_web/src/scrapper.worker.js | 28 + scrapper_web/src/vite-env.d.ts | 2 + scrapper_web/svelte.config.js | 6 + scrapper_web/tailwind.config.cjs | 36 + scrapper_web/vite.config.js | 10 + tools/ghidra_scripts/mark_up_py.py | 125 ++ tools/remaster/scrap_parse/.gitignore | 177 ++ tools/remaster/scrap_parse/Cargo.lock | 747 +++++-- tools/remaster/scrap_parse/Cargo.toml | 9 +- .../scrap_parse/blender_plugin/__init__.py | 23 + .../level_import.py} | 101 +- .../blender_plugin/packed_browser.py | 118 ++ .../remaster/scrap_parse/get_vertex_size.cpp | 66 + tools/remaster/scrap_parse/packed_loader.py | 103 - tools/remaster/scrap_parse/src/find_scrap.rs | 15 + tools/remaster/scrap_parse/src/main.rs | 286 ++- .../remaster/scrap_parse/src/pixel_shader.rs | 4 + 35 files changed, 3897 insertions(+), 353 deletions(-) create mode 100644 scrapper_web/.gitignore create mode 100644 scrapper_web/.vscode/extensions.json create mode 100644 scrapper_web/README.md create mode 100644 scrapper_web/index.html create mode 100644 scrapper_web/jsconfig.json create mode 100644 scrapper_web/package.json create mode 100644 scrapper_web/pnpm-lock.yaml create mode 100644 scrapper_web/postcss.config.cjs create mode 100644 scrapper_web/public/vite.svg create mode 100644 scrapper_web/scrapper/.gitignore create mode 100644 scrapper_web/scrapper/Cargo.toml create mode 100644 scrapper_web/scrapper/README.md create mode 100644 scrapper_web/scrapper/src/lib.rs create mode 100644 scrapper_web/src/App.svelte create mode 100644 scrapper_web/src/app.pcss create mode 100644 scrapper_web/src/lib/Explorer.svelte create mode 100644 scrapper_web/src/lib/TreeView.svelte create mode 100644 scrapper_web/src/main.js create mode 100644 scrapper_web/src/scrapper.worker.js create mode 100644 scrapper_web/src/vite-env.d.ts create mode 100644 scrapper_web/svelte.config.js create mode 100644 scrapper_web/tailwind.config.cjs create mode 100644 scrapper_web/vite.config.js create mode 100644 tools/ghidra_scripts/mark_up_py.py create mode 100644 tools/remaster/scrap_parse/.gitignore create mode 100644 tools/remaster/scrap_parse/blender_plugin/__init__.py rename tools/remaster/scrap_parse/{blender_import.py => blender_plugin/level_import.py} (87%) create mode 100644 tools/remaster/scrap_parse/blender_plugin/packed_browser.py create mode 100644 tools/remaster/scrap_parse/get_vertex_size.cpp delete mode 100644 tools/remaster/scrap_parse/packed_loader.py create mode 100644 tools/remaster/scrap_parse/src/find_scrap.rs diff --git a/scrapper_web/.gitignore b/scrapper_web/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/scrapper_web/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/scrapper_web/.vscode/extensions.json b/scrapper_web/.vscode/extensions.json new file mode 100644 index 0000000..bdef820 --- /dev/null +++ b/scrapper_web/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["svelte.svelte-vscode"] +} diff --git a/scrapper_web/README.md b/scrapper_web/README.md new file mode 100644 index 0000000..69c2ac5 --- /dev/null +++ b/scrapper_web/README.md @@ -0,0 +1,47 @@ +# Svelte + Vite + +This template should help get you started developing with Svelte in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + +This template contains as little as possible to get started with Vite + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `checkJs` in the JS template?** + +It is likely that most cases of changing variable types in runtime are likely to be accidental, rather than deliberate. This provides advanced typechecking out of the box. Should you like to take advantage of the dynamically-typed nature of JavaScript, it is trivial to change the configuration. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```js +// store.js +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/scrapper_web/index.html b/scrapper_web/index.html new file mode 100644 index 0000000..26c29c4 --- /dev/null +++ b/scrapper_web/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Svelte + + +
+ + + diff --git a/scrapper_web/jsconfig.json b/scrapper_web/jsconfig.json new file mode 100644 index 0000000..2df8094 --- /dev/null +++ b/scrapper_web/jsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "moduleResolution": "Node", + "target": "ESNext", + "module": "ESNext", + /** + * svelte-preprocess cannot figure out whether you have + * a value or a type, so tell TypeScript to enforce using + * `import type` instead of `import` for Types. + */ + "importsNotUsedAsValues": "error", + "isolatedModules": true, + "resolveJsonModule": true, + /** + * To have warnings / errors of the Svelte compiler at the + * correct position, enable source maps by default. + */ + "sourceMap": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable this if you'd like to use dynamic types. + */ + "checkJs": false + }, + /** + * Use global.d.ts instead of compilerOptions.types + * to avoid limiting type declarations. + */ + "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"] +} diff --git a/scrapper_web/package.json b/scrapper_web/package.json new file mode 100644 index 0000000..b66da50 --- /dev/null +++ b/scrapper_web/package.json @@ -0,0 +1,26 @@ +{ + "name": "scrapper_web", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "wasm-pack build ./scrapper -t web && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^2.0.2", + "@tailwindcss/forms": "^0.5.3", + "autoprefixer": "^10.4.13", + "cssnano": "^5.1.14", + "cssnano-preset-advanced": "^5.3.9", + "daisyui": "^2.50.0", + "filedrop-svelte": "^0.1.2", + "postcss": "^8.4.21", + "svelte": "^3.55.1", + "svelte-preprocess": "^5.0.1", + "tailwindcss": "^3.2.4", + "vite": "^4.1.0", + "vite-plugin-wasm-pack": "^0.1.12" + } +} \ No newline at end of file diff --git a/scrapper_web/pnpm-lock.yaml b/scrapper_web/pnpm-lock.yaml new file mode 100644 index 0000000..739e35e --- /dev/null +++ b/scrapper_web/pnpm-lock.yaml @@ -0,0 +1,1777 @@ +lockfileVersion: 5.4 + +specifiers: + '@sveltejs/vite-plugin-svelte': ^2.0.2 + '@tailwindcss/forms': ^0.5.3 + autoprefixer: ^10.4.13 + cssnano: ^5.1.14 + cssnano-preset-advanced: ^5.3.9 + daisyui: ^2.50.0 + filedrop-svelte: ^0.1.2 + postcss: ^8.4.21 + svelte: ^3.55.1 + svelte-preprocess: ^5.0.1 + tailwindcss: ^3.2.4 + vite: ^4.1.0 + vite-plugin-wasm-pack: ^0.1.12 + +devDependencies: + '@sveltejs/vite-plugin-svelte': 2.0.2_svelte@3.55.1+vite@4.1.1 + '@tailwindcss/forms': 0.5.3_tailwindcss@3.2.6 + autoprefixer: 10.4.13_postcss@8.4.21 + cssnano: 5.1.14_postcss@8.4.21 + cssnano-preset-advanced: 5.3.9_postcss@8.4.21 + daisyui: 2.50.0_gbtt6ss3tbiz4yjtvdr6fbrj44 + filedrop-svelte: 0.1.2 + postcss: 8.4.21 + svelte: 3.55.1 + svelte-preprocess: 5.0.1_pehl75e5jsy22vp33udjja4soi + tailwindcss: 3.2.6_postcss@8.4.21 + vite: 4.1.1 + vite-plugin-wasm-pack: 0.1.12 + +packages: + + /@esbuild/android-arm/0.16.17: + resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64/0.16.17: + resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.16.17: + resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.16.17: + resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.16.17: + resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.16.17: + resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.16.17: + resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.16.17: + resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.16.17: + resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.16.17: + resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64/0.16.17: + resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el/0.16.17: + resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.16.17: + resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.16.17: + resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.16.17: + resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.16.17: + resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.16.17: + resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.16.17: + resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.16.17: + resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.16.17: + resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.16.17: + resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.16.17: + resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@jridgewell/sourcemap-codec/1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@nodelib/fs.scandir/2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat/2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk/1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@sveltejs/vite-plugin-svelte/2.0.2_svelte@3.55.1+vite@4.1.1: + resolution: {integrity: sha512-xCEan0/NNpQuL0l5aS42FjwQ6wwskdxC3pW1OeFtEKNZwRg7Evro9lac9HesGP6TdFsTv2xMes5ASQVKbCacxg==} + engines: {node: ^14.18.0 || >= 16} + peerDependencies: + svelte: ^3.54.0 + vite: ^4.0.0 + dependencies: + debug: 4.3.4 + deepmerge: 4.3.0 + kleur: 4.1.5 + magic-string: 0.27.0 + svelte: 3.55.1 + svelte-hmr: 0.15.1_svelte@3.55.1 + vite: 4.1.1 + vitefu: 0.2.4_vite@4.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@tailwindcss/forms/0.5.3_tailwindcss@3.2.6: + resolution: {integrity: sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==} + peerDependencies: + tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1' + dependencies: + mini-svg-data-uri: 1.4.4 + tailwindcss: 3.2.6_postcss@8.4.21 + dev: true + + /@trysound/sax/0.2.0: + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + dev: true + + /@types/node/18.13.0: + resolution: {integrity: sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==} + dev: true + + /@types/pug/2.0.6: + resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==} + dev: true + + /@types/sass/1.43.1: + resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==} + dependencies: + '@types/node': 18.13.0 + dev: true + + /acorn-node/1.8.2: + resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + xtend: 4.0.2 + dev: true + + /acorn-walk/7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn/7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /anymatch/3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /arg/5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: true + + /autoprefixer/10.4.13_postcss@8.4.21: + resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.21.5 + caniuse-lite: 1.0.30001450 + fraction.js: 4.2.0 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /boolbase/1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browserslist/4.21.5: + resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001450 + electron-to-chromium: 1.4.288 + node-releases: 2.0.10 + update-browserslist-db: 1.0.10_browserslist@4.21.5 + dev: true + + /buffer-crc32/0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: true + + /camelcase-css/2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + dev: true + + /caniuse-api/3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + dependencies: + browserslist: 4.21.5 + caniuse-lite: 1.0.30001450 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + dev: true + + /caniuse-lite/1.0.30001450: + resolution: {integrity: sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==} + dev: true + + /chalk/4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chokidar/3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /color-string/1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: true + + /color/4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + dev: true + + /colord/2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + dev: true + + /commander/7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: true + + /concat-map/0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /css-declaration-sorter/6.3.1_postcss@8.4.21: + resolution: {integrity: sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==} + engines: {node: ^10 || ^12 || >=14} + peerDependencies: + postcss: ^8.0.9 + dependencies: + postcss: 8.4.21 + dev: true + + /css-select/4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + dev: true + + /css-selector-tokenizer/0.8.0: + resolution: {integrity: sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==} + dependencies: + cssesc: 3.0.0 + fastparse: 1.1.2 + dev: true + + /css-tree/1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + dev: true + + /css-what/6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + dev: true + + /cssesc/3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /cssnano-preset-advanced/5.3.9_postcss@8.4.21: + resolution: {integrity: sha512-njnh4pp1xCsibJcEHnWZb4EEzni0ePMqPuPNyuWT4Z+YeXmsgqNuTPIljXFEXhxGsWs9183JkXgHxc1TcsahIg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + autoprefixer: 10.4.13_postcss@8.4.21 + cssnano-preset-default: 5.2.13_postcss@8.4.21 + postcss: 8.4.21 + postcss-discard-unused: 5.1.0_postcss@8.4.21 + postcss-merge-idents: 5.1.1_postcss@8.4.21 + postcss-reduce-idents: 5.2.0_postcss@8.4.21 + postcss-zindex: 5.1.0_postcss@8.4.21 + dev: true + + /cssnano-preset-default/5.2.13_postcss@8.4.21: + resolution: {integrity: sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + css-declaration-sorter: 6.3.1_postcss@8.4.21 + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-calc: 8.2.4_postcss@8.4.21 + postcss-colormin: 5.3.0_postcss@8.4.21 + postcss-convert-values: 5.1.3_postcss@8.4.21 + postcss-discard-comments: 5.1.2_postcss@8.4.21 + postcss-discard-duplicates: 5.1.0_postcss@8.4.21 + postcss-discard-empty: 5.1.1_postcss@8.4.21 + postcss-discard-overridden: 5.1.0_postcss@8.4.21 + postcss-merge-longhand: 5.1.7_postcss@8.4.21 + postcss-merge-rules: 5.1.3_postcss@8.4.21 + postcss-minify-font-values: 5.1.0_postcss@8.4.21 + postcss-minify-gradients: 5.1.1_postcss@8.4.21 + postcss-minify-params: 5.1.4_postcss@8.4.21 + postcss-minify-selectors: 5.2.1_postcss@8.4.21 + postcss-normalize-charset: 5.1.0_postcss@8.4.21 + postcss-normalize-display-values: 5.1.0_postcss@8.4.21 + postcss-normalize-positions: 5.1.1_postcss@8.4.21 + postcss-normalize-repeat-style: 5.1.1_postcss@8.4.21 + postcss-normalize-string: 5.1.0_postcss@8.4.21 + postcss-normalize-timing-functions: 5.1.0_postcss@8.4.21 + postcss-normalize-unicode: 5.1.1_postcss@8.4.21 + postcss-normalize-url: 5.1.0_postcss@8.4.21 + postcss-normalize-whitespace: 5.1.1_postcss@8.4.21 + postcss-ordered-values: 5.1.3_postcss@8.4.21 + postcss-reduce-initial: 5.1.1_postcss@8.4.21 + postcss-reduce-transforms: 5.1.0_postcss@8.4.21 + postcss-svgo: 5.1.0_postcss@8.4.21 + postcss-unique-selectors: 5.1.1_postcss@8.4.21 + dev: true + + /cssnano-utils/3.1.0_postcss@8.4.21: + resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /cssnano/5.1.14_postcss@8.4.21: + resolution: {integrity: sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + cssnano-preset-default: 5.2.13_postcss@8.4.21 + lilconfig: 2.0.6 + postcss: 8.4.21 + yaml: 1.10.2 + dev: true + + /csso/4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + dependencies: + css-tree: 1.1.3 + dev: true + + /daisyui/2.50.0_gbtt6ss3tbiz4yjtvdr6fbrj44: + resolution: {integrity: sha512-KiqRvqMXi9rgoH84M8D69gXPg6x+cbdiaHqm8pFHOsXXN1rTl/+OcCKkSnkEwTtIge9VJVDGU6l4B8/n+Juc5g==} + peerDependencies: + autoprefixer: ^10.0.2 + postcss: ^8.1.6 + dependencies: + autoprefixer: 10.4.13_postcss@8.4.21 + color: 4.2.3 + css-selector-tokenizer: 0.8.0 + postcss: 8.4.21 + postcss-js: 4.0.1_postcss@8.4.21 + tailwindcss: 3.2.6_postcss@8.4.21 + transitivePeerDependencies: + - ts-node + dev: true + + /debug/4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /deepmerge/4.3.0: + resolution: {integrity: sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==} + engines: {node: '>=0.10.0'} + dev: true + + /defined/1.0.1: + resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} + dev: true + + /detect-indent/6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + + /detective/5.2.1: + resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} + engines: {node: '>=0.8.0'} + hasBin: true + dependencies: + acorn-node: 1.8.2 + defined: 1.0.1 + minimist: 1.2.7 + dev: true + + /didyoumean/1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dev: true + + /dlv/1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dev: true + + /dom-serializer/1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + dev: true + + /domelementtype/2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: true + + /domhandler/4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + dependencies: + domelementtype: 2.3.0 + dev: true + + /domutils/2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + dev: true + + /electron-to-chromium/1.4.288: + resolution: {integrity: sha512-8s9aJf3YiokIrR+HOQzNOGmEHFXVUQzXM/JaViVvKdCkNUjS+lEa/uT7xw3nDVG/IgfxiIwUGkwJ6AR1pTpYsQ==} + dev: true + + /entities/2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + dev: true + + /es6-promise/3.3.1: + resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} + dev: true + + /esbuild/0.16.17: + resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.16.17 + '@esbuild/android-arm64': 0.16.17 + '@esbuild/android-x64': 0.16.17 + '@esbuild/darwin-arm64': 0.16.17 + '@esbuild/darwin-x64': 0.16.17 + '@esbuild/freebsd-arm64': 0.16.17 + '@esbuild/freebsd-x64': 0.16.17 + '@esbuild/linux-arm': 0.16.17 + '@esbuild/linux-arm64': 0.16.17 + '@esbuild/linux-ia32': 0.16.17 + '@esbuild/linux-loong64': 0.16.17 + '@esbuild/linux-mips64el': 0.16.17 + '@esbuild/linux-ppc64': 0.16.17 + '@esbuild/linux-riscv64': 0.16.17 + '@esbuild/linux-s390x': 0.16.17 + '@esbuild/linux-x64': 0.16.17 + '@esbuild/netbsd-x64': 0.16.17 + '@esbuild/openbsd-x64': 0.16.17 + '@esbuild/sunos-x64': 0.16.17 + '@esbuild/win32-arm64': 0.16.17 + '@esbuild/win32-ia32': 0.16.17 + '@esbuild/win32-x64': 0.16.17 + dev: true + + /escalade/3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /fast-glob/3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fastparse/1.1.2: + resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==} + dev: true + + /fastq/1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /file-selector/0.2.4: + resolution: {integrity: sha512-ZDsQNbrv6qRi1YTDOEWzf5J2KjZ9KMI1Q2SGeTkCJmNNW25Jg4TW4UMcmoqcg4WrAyKRcpBXdbWRxkfrOzVRbA==} + engines: {node: '>= 10'} + dependencies: + tslib: 2.5.0 + dev: true + + /filedrop-svelte/0.1.2: + resolution: {integrity: sha512-S0Z+zCO2dy/g3tRjswD8pLEcorj78olkLWvhKEp511gwHUI6x+uWjXacuvFmRQnjbCCPByXzGlC5Asb9nPzUKw==} + dependencies: + file-selector: 0.2.4 + pretty-bytes: 6.1.0 + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /fraction.js/4.2.0: + resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} + dev: true + + /fs-extra/10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.10 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent/6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob/7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /is-arrayish/0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + dev: true + + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-core-module/2.11.0: + resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + dependencies: + has: 1.0.3 + dev: true + + /is-extglob/2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /jsonfile/6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.10 + dev: true + + /kleur/4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + + /lilconfig/2.0.6: + resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} + engines: {node: '>=10'} + dev: true + + /lodash.memoize/4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + dev: true + + /lodash.uniq/4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + dev: true + + /magic-string/0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /mdn-data/2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + dev: true + + /merge2/1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch/4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /min-indent/1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /mini-svg-data-uri/1.4.4: + resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} + hasBin: true + dev: true + + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimist/1.2.7: + resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + dev: true + + /mkdirp/0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.7 + dev: true + + /ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /narrowing/1.5.0: + resolution: {integrity: sha512-DUu4XdKgkfAPTAL28k79pdnshDE2W5T24QAnidSPo2F/W1TX6CjNzmEeXQfE5O1lxQvC0GYI6ZRDsLcyzugEYA==} + dev: true + + /node-releases/2.0.10: + resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-range/0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-url/6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + dev: true + + /nth-check/2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + + /object-hash/3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: true + + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pify/2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + + /postcss-calc/8.2.4_postcss@8.4.21: + resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} + peerDependencies: + postcss: ^8.2.2 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-colormin/5.3.0_postcss@8.4.21: + resolution: {integrity: sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.5 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-convert-values/5.1.3_postcss@8.4.21: + resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.5 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-discard-comments/5.1.2_postcss@8.4.21: + resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-discard-duplicates/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-discard-empty/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-discard-overridden/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-discard-unused/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + dev: true + + /postcss-import/14.1.0_postcss@8.4.21: + resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} + engines: {node: '>=10.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.1 + dev: true + + /postcss-js/4.0.1_postcss@8.4.21: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.21 + dev: true + + /postcss-load-config/3.1.4_postcss@8.4.21: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.0.6 + postcss: 8.4.21 + yaml: 1.10.2 + dev: true + + /postcss-merge-idents/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-merge-longhand/5.1.7_postcss@8.4.21: + resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + stylehacks: 5.1.1_postcss@8.4.21 + dev: true + + /postcss-merge-rules/5.1.3_postcss@8.4.21: + resolution: {integrity: sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.5 + caniuse-api: 3.0.0 + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + dev: true + + /postcss-minify-font-values/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-minify-gradients/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + colord: 2.9.3 + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-minify-params/5.1.4_postcss@8.4.21: + resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.5 + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-minify-selectors/5.2.1_postcss@8.4.21: + resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + dev: true + + /postcss-nested/6.0.0_postcss@8.4.21: + resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + dev: true + + /postcss-normalize-charset/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss-normalize-display-values/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-positions/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-repeat-style/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-string/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-timing-functions/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-unicode/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.5 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-url/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + normalize-url: 6.1.0 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-whitespace/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-ordered-values/5.1.3_postcss@8.4.21: + resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + cssnano-utils: 3.1.0_postcss@8.4.21 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-reduce-idents/5.2.0_postcss@8.4.21: + resolution: {integrity: sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-reduce-initial/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.5 + caniuse-api: 3.0.0 + postcss: 8.4.21 + dev: true + + /postcss-reduce-transforms/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-selector-parser/6.0.11: + resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-svgo/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + svgo: 2.8.0 + dev: true + + /postcss-unique-selectors/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + dev: true + + /postcss-value-parser/4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: true + + /postcss-zindex/5.1.0_postcss@8.4.21: + resolution: {integrity: sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.21 + dev: true + + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /pretty-bytes/6.1.0: + resolution: {integrity: sha512-Rk753HI8f4uivXi4ZCIYdhmG1V+WKzvRMg/X+M42a6t7D07RcmopXJMDNk6N++7Bl75URRGsb40ruvg7Hcp2wQ==} + engines: {node: ^14.13.1 || >=16.0.0} + dev: true + + /queue-microtask/1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru/5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: true + + /read-cache/1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + dev: true + + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /reusify/1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf/2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup/3.14.0: + resolution: {integrity: sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /run-parallel/1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /sander/0.5.1: + resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==} + dependencies: + es6-promise: 3.3.1 + graceful-fs: 4.2.10 + mkdirp: 0.5.6 + rimraf: 2.7.1 + dev: true + + /simple-swizzle/0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + dependencies: + is-arrayish: 0.3.2 + dev: true + + /sorcery/0.11.0: + resolution: {integrity: sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==} + hasBin: true + dependencies: + '@jridgewell/sourcemap-codec': 1.4.14 + buffer-crc32: 0.2.13 + minimist: 1.2.7 + sander: 0.5.1 + dev: true + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /stable/0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + dev: true + + /strip-indent/3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /stylehacks/5.1.1_postcss@8.4.21: + resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + browserslist: 4.21.5 + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + dev: true + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /svelte-hmr/0.15.1_svelte@3.55.1: + resolution: {integrity: sha512-BiKB4RZ8YSwRKCNVdNxK/GfY+r4Kjgp9jCLEy0DuqAKfmQtpL38cQK3afdpjw4sqSs4PLi3jIPJIFp259NkZtA==} + engines: {node: ^12.20 || ^14.13.1 || >= 16} + peerDependencies: + svelte: '>=3.19.0' + dependencies: + svelte: 3.55.1 + dev: true + + /svelte-preprocess/5.0.1_pehl75e5jsy22vp33udjja4soi: + resolution: {integrity: sha512-0HXyhCoc9rsW4zGOgtInylC6qj259E1hpFnJMJWTf+aIfeqh4O/QHT31KT2hvPEqQfdjmqBR/kO2JDkkciBLrQ==} + engines: {node: '>= 14.10.0'} + requiresBuild: true + peerDependencies: + '@babel/core': ^7.10.2 + coffeescript: ^2.5.1 + less: ^3.11.3 || ^4.0.0 + postcss: ^7 || ^8 + postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0 + pug: ^3.0.0 + sass: ^1.26.8 + stylus: ^0.55.0 + sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0 + svelte: ^3.23.0 + typescript: ^3.9.5 || ^4.0.0 + peerDependenciesMeta: + '@babel/core': + optional: true + coffeescript: + optional: true + less: + optional: true + postcss: + optional: true + postcss-load-config: + optional: true + pug: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + typescript: + optional: true + dependencies: + '@types/pug': 2.0.6 + '@types/sass': 1.43.1 + detect-indent: 6.1.0 + magic-string: 0.27.0 + postcss: 8.4.21 + sorcery: 0.11.0 + strip-indent: 3.0.0 + svelte: 3.55.1 + dev: true + + /svelte/3.55.1: + resolution: {integrity: sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ==} + engines: {node: '>= 8'} + dev: true + + /svgo/2.8.0: + resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} + engines: {node: '>=10.13.0'} + hasBin: true + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 4.3.0 + css-tree: 1.1.3 + csso: 4.2.0 + picocolors: 1.0.0 + stable: 0.1.8 + dev: true + + /tailwindcss/3.2.6_postcss@8.4.21: + resolution: {integrity: sha512-BfgQWZrtqowOQMC2bwaSNe7xcIjdDEgixWGYOd6AL0CbKHJlvhfdbINeAW76l1sO+1ov/MJ93ODJ9yluRituIw==} + engines: {node: '>=12.13.0'} + hasBin: true + peerDependencies: + postcss: ^8.0.9 + dependencies: + arg: 5.0.2 + chokidar: 3.5.3 + color-name: 1.1.4 + detective: 5.2.1 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.2.12 + glob-parent: 6.0.2 + is-glob: 4.0.3 + lilconfig: 2.0.6 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.21 + postcss-import: 14.1.0_postcss@8.4.21 + postcss-js: 4.0.1_postcss@8.4.21 + postcss-load-config: 3.1.4_postcss@8.4.21 + postcss-nested: 6.0.0_postcss@8.4.21 + postcss-selector-parser: 6.0.11 + postcss-value-parser: 4.2.0 + quick-lru: 5.1.1 + resolve: 1.22.1 + transitivePeerDependencies: + - ts-node + dev: true + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /tslib/2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + dev: true + + /universalify/2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: true + + /update-browserslist-db/1.0.10_browserslist@4.21.5: + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.5 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /util-deprecate/1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /vite-plugin-wasm-pack/0.1.12: + resolution: {integrity: sha512-WliYvQp9HXluir4OKGbngkcKxtYtifU11cqLurRRJGsl770Sjr1iIkp5RuvU3IC1poT4A57Z2/YgAKI2Skm7ZA==} + dependencies: + chalk: 4.1.2 + fs-extra: 10.1.0 + narrowing: 1.5.0 + dev: true + + /vite/4.1.1: + resolution: {integrity: sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.16.17 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.14.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitefu/0.2.4_vite@4.1.1: + resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 4.1.1 + dev: true + + /wrappy/1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /xtend/4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /yaml/1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true diff --git a/scrapper_web/postcss.config.cjs b/scrapper_web/postcss.config.cjs new file mode 100644 index 0000000..059077c --- /dev/null +++ b/scrapper_web/postcss.config.cjs @@ -0,0 +1,11 @@ +let cssnano_plugin = {}; +if (process.env.NODE_ENV === "production") { + cssnano_plugin = { cssnano: { preset: "advanced" } }; +} +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + ...cssnano_plugin, + }, +}; diff --git a/scrapper_web/public/vite.svg b/scrapper_web/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/scrapper_web/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/scrapper_web/scrapper/.gitignore b/scrapper_web/scrapper/.gitignore new file mode 100644 index 0000000..6985cf1 --- /dev/null +++ b/scrapper_web/scrapper/.gitignore @@ -0,0 +1,14 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb diff --git a/scrapper_web/scrapper/Cargo.toml b/scrapper_web/scrapper/Cargo.toml new file mode 100644 index 0000000..ee8e4d6 --- /dev/null +++ b/scrapper_web/scrapper/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "scrapper" +version = "0.1.0" +authors = [] +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[profile.release] +lto = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +aes = "0.8.2" +anyhow = "1.0.69" +binrw = "0.11.1" +cbc = "0.1.2" +console_error_panic_hook = "0.1.7" +derivative = "2.2.0" +js-sys = "0.3.61" +pelite = "0.10.0" +serde = { version = "1.0.152", features = ["derive"] } +serde-wasm-bindgen = "0.4.5" +wasm-bindgen = "0.2.83" +wasm-bindgen-file-reader = "1.0.0" +web-sys = { version = "0.3.61", features = ["File", "BlobPropertyBag", "Blob", "Url"] } + +[package.metadata.wasm-pack.profile.release] +wasm-opt = ["-O4"] diff --git a/scrapper_web/scrapper/README.md b/scrapper_web/scrapper/README.md new file mode 100644 index 0000000..a923c54 --- /dev/null +++ b/scrapper_web/scrapper/README.md @@ -0,0 +1,23 @@ +# scrapper + +## Usage + +[rsw-rs doc](https://github.com/lencx/rsw-rs) + +```bash +# install rsw +cargo install rsw + +# --- help --- +# rsw help +rsw -h +# new help +rsw new -h + +# --- usage --- +# dev +rsw watch + +# production +rsw build +``` diff --git a/scrapper_web/scrapper/src/lib.rs b/scrapper_web/scrapper/src/lib.rs new file mode 100644 index 0000000..fda2f4b --- /dev/null +++ b/scrapper_web/scrapper/src/lib.rs @@ -0,0 +1,155 @@ +use binrw::{binread, BinReaderExt}; +use serde::Serialize; +use std::collections::BTreeMap; +use std::io::{Read, Seek, SeekFrom}; +use wasm_bindgen::prelude::*; +use wasm_bindgen_file_reader::WebSysFile; +use web_sys::{Blob, File}; + +type JsResult = Result; + +#[binread] +#[derive(Serialize, Debug)] +struct ScrapFile { + #[br(temp)] + name_len: u32, + #[br(count = name_len)] + #[br(map = |s: Vec| String::from_utf8_lossy(&s).to_string())] + path: String, + size: u32, + offset: u32, +} + +#[binread] +#[br(magic = b"BFPK", little)] +#[derive(Serialize, Debug)] +struct PackedHeader { + version: u32, + #[br(temp)] + num_files: u32, + #[br(count= num_files)] + files: Vec, +} + +#[derive(Serialize, Debug)] +#[serde(tag = "type", rename_all = "snake_case")] +enum DirectoryTree { + File { + size: u32, + offset: u32, + file_index: u8, + }, + Directory { + entries: BTreeMap, + }, +} + +#[wasm_bindgen(inspectable)] +pub struct MultiPack { + files: Vec<(String,WebSysFile)>, + tree: DirectoryTree, +} + +fn blob_url(buffer: &[u8]) -> JsResult { + let uint8arr = + js_sys::Uint8Array::new(&unsafe { js_sys::Uint8Array::view(buffer) }.into()); + let array = js_sys::Array::new(); + array.push(&uint8arr.buffer()); + let blob = Blob::new_with_u8_array_sequence_and_options( + &array, + web_sys::BlobPropertyBag::new().type_("application/octet-stream"), + ) + .unwrap(); + web_sys::Url::create_object_url_with_blob(&blob) +} + +#[wasm_bindgen] +impl MultiPack { + #[wasm_bindgen(constructor)] + pub fn parse(files: Vec) -> Self { + let mut tree = DirectoryTree::default(); + let mut web_files = vec![]; + for (file_index, file) in files.into_iter().enumerate() { + let file_name = file.name(); + let mut fh = WebSysFile::new(file); + let header = fh.read_le::().unwrap(); + tree.merge(&header.files, file_index.try_into().unwrap()); + web_files.push((file_name,fh)); + } + Self { + tree, + files: web_files, + } + } + + #[wasm_bindgen] + pub fn tree(&self) -> JsValue { + serde_wasm_bindgen::to_value(&self.tree).unwrap() + } + + #[wasm_bindgen] + pub fn download( + &mut self, + file_index: u8, + offset: u32, + size: u32, + ) -> Result { + let Some((_,file)) = self.files.get_mut(file_index as usize) else { + return Err("File not found".into()); + }; + let mut buffer = vec![0u8; size as usize]; + file.seek(SeekFrom::Start(offset as u64)) + .map_err(|e| format!("Failed to seek file: {e}"))?; + file.read(&mut buffer) + .map_err(|e| format!("Failed to read from file: {e}"))?; + Ok(blob_url(&buffer)?.into()) + } +} + +impl Default for DirectoryTree { + fn default() -> Self { + Self::Directory { + entries: Default::default(), + } + } +} + +impl DirectoryTree { + fn add_child(&mut self, name: &str, node: Self) -> &mut Self { + match self { + Self::File { .. } => panic!("Can't add child to file!"), + Self::Directory { + entries + } => entries.entry(name.to_owned()).or_insert(node), + } + } + + fn merge(&mut self, files: &[ScrapFile], file_index: u8) { + for file in files { + let mut folder = &mut *self; + let path: Vec<_> = file.path.split('/').collect(); + if let Some((filename, path)) = path.as_slice().split_last() { + for part in path { + let DirectoryTree::Directory { entries } = folder else { + unreachable!(); + }; + folder = entries.entry(part.to_string()).or_default(); + } + folder.add_child( + filename, + DirectoryTree::File { + size: file.size, + offset: file.offset, + file_index, + }, + ); + } + } + } +} + +#[wasm_bindgen(start)] +pub fn main() -> Result<(), JsValue> { + console_error_panic_hook::set_once(); + Ok(()) +} diff --git a/scrapper_web/src/App.svelte b/scrapper_web/src/App.svelte new file mode 100644 index 0000000..70adfa0 --- /dev/null +++ b/scrapper_web/src/App.svelte @@ -0,0 +1,13 @@ + + +
+
+

Scrapland .packed explorer

+ +
+
+ + diff --git a/scrapper_web/src/app.pcss b/scrapper_web/src/app.pcss new file mode 100644 index 0000000..19ea342 --- /dev/null +++ b/scrapper_web/src/app.pcss @@ -0,0 +1,109 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +li { + text-align: left; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} + +.lds-dual-ring { + display: inline-block; + width: 80px; + height: 80px; +} +.lds-dual-ring:after { + content: " "; + display: block; + width: 64px; + height: 64px; + margin: 8px; + border-radius: 50%; + border: 6px solid #fff; + border-color: #fff transparent #fff transparent; + animation: lds-dual-ring 1.2s linear infinite; +} +@keyframes lds-dual-ring { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/scrapper_web/src/lib/Explorer.svelte b/scrapper_web/src/lib/Explorer.svelte new file mode 100644 index 0000000..5a7b44b --- /dev/null +++ b/scrapper_web/src/lib/Explorer.svelte @@ -0,0 +1,52 @@ + + +
+ +
+ +{#if tree} + {#each [...tree.entries] as [name, child]} + + {/each} +{/if} diff --git a/scrapper_web/src/lib/TreeView.svelte b/scrapper_web/src/lib/TreeView.svelte new file mode 100644 index 0000000..f2699f6 --- /dev/null +++ b/scrapper_web/src/lib/TreeView.svelte @@ -0,0 +1,56 @@ + + + +
    +
  • + {#if tree.type == "directory" && tree.entries} + + {#if expanded} + [-] + {:else} + [+] + {/if} + {label} + + {#if tree.entries && expanded} + {#each [...tree.entries] as [name, child]} + + {/each} + {/if} + {:else} + + + {label} + + {/if} +
  • +
+ + diff --git a/scrapper_web/src/main.js b/scrapper_web/src/main.js new file mode 100644 index 0000000..e7acd1d --- /dev/null +++ b/scrapper_web/src/main.js @@ -0,0 +1,6 @@ +import './app.pcss' +import App from './App.svelte' + +export default new App({ + target: document.getElementById('app'), +}); diff --git a/scrapper_web/src/scrapper.worker.js b/scrapper_web/src/scrapper.worker.js new file mode 100644 index 0000000..a1146b1 --- /dev/null +++ b/scrapper_web/src/scrapper.worker.js @@ -0,0 +1,28 @@ +import wasm, { MultiPack } from "scrapper"; + +async function initialize() { + await wasm(); + let pack; + let handlers = { + parse(data) { + pack = new MultiPack(data); + return pack.tree(); + }, + download(data) { + if (pack) { + let { label, file_index, offset, size } = data; + return [label, pack.download(file_index, offset, size)]; + } + }, + }; + self.onmessage = (event) => { + for (var [name, func] of Object.entries(handlers)) { + let data = event.data[name]; + if (data) { + postMessage(Object.fromEntries([[name, func(data)]])); + } + } + }; +} + +initialize(); diff --git a/scrapper_web/src/vite-env.d.ts b/scrapper_web/src/vite-env.d.ts new file mode 100644 index 0000000..4078e74 --- /dev/null +++ b/scrapper_web/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/scrapper_web/svelte.config.js b/scrapper_web/svelte.config.js new file mode 100644 index 0000000..66fa030 --- /dev/null +++ b/scrapper_web/svelte.config.js @@ -0,0 +1,6 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/scrapper_web/tailwind.config.cjs b/scrapper_web/tailwind.config.cjs new file mode 100644 index 0000000..ad70a37 --- /dev/null +++ b/scrapper_web/tailwind.config.cjs @@ -0,0 +1,36 @@ +module.exports = { + content: ["./src/**/*.{svelte,js,ts}"], + plugins: [require("@tailwindcss/forms"),require("daisyui")], + theme: { + container: { + center: true, + }, + }, + daisyui: { + styled: true, + themes: true, + base: true, + utils: true, + logs: true, + rtl: false, + prefix: "", + darkTheme: "scraptool", + themes: [ + { + scraptool: { + primary: "#F28C18", + secondary: "#b45309", + accent: "#22d3ee", + neutral: "#1B1D1D", + "base-100": "#212121", + info: "#2463EB", + success: "#16A249", + warning: "#DB7706", + error: "#DC2828", + // "--rounded-box": "0.4rem", + // "--rounded-btn": "0.2rem" + }, + }, + ], + }, +}; diff --git a/scrapper_web/vite.config.js b/scrapper_web/vite.config.js new file mode 100644 index 0000000..6935bc3 --- /dev/null +++ b/scrapper_web/vite.config.js @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' +import wasmPack from 'vite-plugin-wasm-pack'; +import preprocess from 'svelte-preprocess'; + +export default defineConfig({ + plugins: [wasmPack("./scrapper/"),svelte({ + preprocess: preprocess({ postcss: true }) + })] +}); diff --git a/tools/ghidra_scripts/mark_up_py.py b/tools/ghidra_scripts/mark_up_py.py new file mode 100644 index 0000000..5dc9d71 --- /dev/null +++ b/tools/ghidra_scripts/mark_up_py.py @@ -0,0 +1,125 @@ +import time +try: + import ghidra_bridge + has_bridge=True +except ImportError: + has_bridge=False + +from contextlib import contextmanager + +if has_bridge: + import ghidra_bridge + b = ghidra_bridge.GhidraBridge(namespace=globals(), hook_import=True) + @contextmanager + def transaction(): + start() + try: + yield + except Exception as e: + end(False) + raise e + end(True) +else: + @contextmanager + def transaction(): + yield + +import ghidra.program.model.symbol.SymbolType as SymbolType +import ghidra.program.model.symbol.SourceType as SourceType +from ghidra.app.cmd.label import CreateNamespacesCmd +from ghidra.program.model.data.DataUtilities import createData +from ghidra.program.model.data.DataUtilities import ClearDataMode +from ghidra.program.model.listing.CodeUnit import PLATE_COMMENT + +listing = currentProgram.getListing() +dtm = currentProgram.getDataTypeManager() +py_mod = dtm.getDataType("/PyModuleDef") +py_meth = dtm.getDataType("/PyMethodDef") + +NULL=toAddr(0) + +def make_namespace(parts): + ns_cmd = CreateNamespacesCmd("::".join(parts), SourceType.USER_DEFINED) + ns_cmd.applyTo(currentProgram) + return ns_cmd.getNamespace() + +def create_data(addr,dtype): + return createData(currentProgram,addr,dtype,0,False,ClearDataMode.CLEAR_ALL_CONFLICT_DATA) + +def create_str(addr): + if addr.equals(NULL): + return None + str_len = (findBytes(addr, b"\0").offset - addr.offset) + 1 + clearListing(addr, addr.add(str_len)) + return createAsciiString(addr) + +def get_call_obj(addr): + func = getFunctionContaining(addr) + if func is None: + disassemble(addr) + func = createFunction(addr,None) + call_obj = {"this": None, "stack": []} + for inst in currentProgram.listing.getInstructions(func.body, True): + affected_objs = [r.toString() for r in inst.resultObjects.tolist()] + inst_name = inst.getMnemonicString() + if inst_name == "PUSH": + val=inst.getScalar(0) + if val is not None: + call_obj["stack"].insert(0, toAddr(val.getValue()).toString()) + elif inst_name == "MOV" and "ECX" in affected_objs: + this = inst.getScalar(1) + if this is not None: + call_obj["this"] = toAddr(this.getValue()).toString() + elif inst_name == "CALL": + break + func=func.symbol.address + return func, call_obj + +def data_to_dict(data): + ret={} + for idx in range(data.dataType.getNumComponents()): + name=data.dataType.getComponent(idx).getFieldName() + value=data.getComponent(idx).getValue() + ret[name]=value + return ret + +def try_create_str(addr): + ret=create_str(addr) + if ret: + return ret.getValue() + +with transaction(): + PyInitModule=getSymbolAt(toAddr("006f31c0")) + for ref in getReferencesTo(PyInitModule.address).tolist(): + func,args=get_call_obj(ref.fromAddress) + print(func,args) + module_name=create_str(toAddr(args['stack'][0])).getValue() + methods=toAddr(args['stack'][1]) + module_doc=create_str(toAddr(args['stack'][2])) + if module_doc: + module_doc=module_doc.getValue() + print(methods,module_name,module_doc) + mod_ns = make_namespace(["Python", module_name]) + createLabel(func, "__init__", mod_ns, True, SourceType.USER_DEFINED) + if module_doc: + listing.getCodeUnitAt(func).setComment(PLATE_COMMENT,module_doc) + while True: + mod_data=data_to_dict(create_data(methods,py_meth)) + if mod_data['name'] is None: + clearListing(methods, methods.add(16)) + break + mod_data['name']=try_create_str(mod_data['name']) + try: + mod_data['doc']=try_create_str(mod_data['doc']) + except: + mod_data['doc']=None + print(mod_data) + createLabel(mod_data['ml_method'], mod_data['name'], mod_ns, True, SourceType.USER_DEFINED) + if mod_data['doc']: + listing.getCodeUnitAt(mod_data['ml_method']).setComment(PLATE_COMMENT,module_doc) + methods=methods.add(16) + try: + if getBytes(methods,4).tolist()==[0,0,0,0]: + break + except: + break \ No newline at end of file diff --git a/tools/remaster/scrap_parse/.gitignore b/tools/remaster/scrap_parse/.gitignore new file mode 100644 index 0000000..758f49c --- /dev/null +++ b/tools/remaster/scrap_parse/.gitignore @@ -0,0 +1,177 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +*.pkl.gz \ No newline at end of file diff --git a/tools/remaster/scrap_parse/Cargo.lock b/tools/remaster/scrap_parse/Cargo.lock index 90147a3..533cb1d 100644 --- a/tools/remaster/scrap_parse/Cargo.lock +++ b/tools/remaster/scrap_parse/Cargo.lock @@ -8,6 +8,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +dependencies = [ + "memchr", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -18,10 +27,59 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.69" +name = "anstream" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" [[package]] name = "array-init" @@ -56,7 +114,7 @@ dependencies = [ "owo-colors", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -66,16 +124,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bumpalo" -version = "3.12.0" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" [[package]] name = "bytemuck" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" @@ -91,9 +164,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ "iana-time-zone", "js-sys", @@ -106,50 +179,46 @@ dependencies = [ ] [[package]] -name = "chrono-humanize" -version = "0.2.2" +name = "clap" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32dce1ea1988dbdf9f9815ff11425828523bd2a134ec0805d2ac8af26ee6096e" +checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62" dependencies = [ - "chrono", + "clap_builder", + "clap_derive", + "once_cell", ] [[package]] -name = "clap" -version = "4.1.6" +name = "clap_builder" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3" +checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749" dependencies = [ + "anstream", + "anstyle", "bitflags", - "clap_derive", "clap_lex", - "is-terminal", - "once_cell", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "clap_lex" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] name = "codespan-reporting" @@ -161,6 +230,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "configparser" version = "3.0.2" @@ -172,9 +247,18 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] [[package]] name = "crc32fast" @@ -186,10 +270,20 @@ dependencies = [ ] [[package]] -name = "cxx" -version = "1.0.91" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cxx" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" dependencies = [ "cc", "cxxbridge-flags", @@ -199,9 +293,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.91" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" dependencies = [ "cc", "codespan-reporting", @@ -209,24 +303,54 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn", + "syn 2.0.15", ] [[package]] name = "cxxbridge-flags" -version = "1.0.91" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" [[package]] name = "cxxbridge-macro" -version = "1.0.91" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dece029acd3353e3a58ac2e3eb3c8d6c35827a892edc6cc4138ef9c33df46ecd" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04414300db88f70d74c5ff54e50f9e1d1737d9a5b90f53fcf2e95ca2a9ab554b" +dependencies = [ + "libc", + "redox_users", + "windows-sys 0.45.0", ] [[package]] @@ -237,13 +361,13 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -272,6 +396,27 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -292,16 +437,16 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] @@ -316,9 +461,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", @@ -327,31 +472,38 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.5" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ + "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "is-terminal" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] -name = "itoa" -version = "1.0.5" +name = "iter-read" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "c397ca3ea05ad509c4ec451fea28b4771236a376ca1c69fd5143aae0cf8f93c4" + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" @@ -363,10 +515,35 @@ dependencies = [ ] [[package]] -name = "libc" -version = "0.2.139" +name = "keyvalues-parser" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "7d990301996c856ea07a84bc291e76f1273db52683663efc05c8d355976897e5" +dependencies = [ + "pest", + "pest_derive", + "thiserror", +] + +[[package]] +name = "keyvalues-serde" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da419ac133bb3ddf0dbf9c12fcc0ce01d994fcb65f6f1713faf15cc689320b5f" +dependencies = [ + "keyvalues-parser", + "once_cell", + "paste", + "regex", + "serde", + "thiserror", +] + +[[package]] +name = "libc" +version = "0.2.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "link-cplusplus" @@ -379,9 +556,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" [[package]] name = "log" @@ -392,6 +569,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + [[package]] name = "miniz_oxide" version = "0.6.2" @@ -419,7 +602,24 @@ checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", +] + +[[package]] +name = "nom" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce" + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", ] [[package]] @@ -441,18 +641,18 @@ dependencies = [ "autocfg", ] +[[package]] +name = "obj" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059c95245738cdc7b40078cdd51a23200252a4c0a0a6dd005136152b3f467a4a" + [[package]] name = "once_cell" version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - [[package]] name = "owo-colors" version = "3.5.0" @@ -460,47 +660,110 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "paste" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "pest" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1403e8401ad5dedea73c626b99758535b342502f8d1e361f4a2dd952749122" dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", + "thiserror", + "ucd-trie", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "pest_derive" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "be99c4c1d2fc2769b1d00239431d711d08f6efedcecb8b6e30707160aee99c15" dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e56094789873daa36164de2e822b3888c6ae4b4f9da555a1103587658c805b1e" +dependencies = [ + "pest", + "pest_meta", "proc-macro2", "quote", - "version_check", + "syn 2.0.15", +] + +[[package]] +name = "pest_meta" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6733073c7cff3d8459fda0e42f13a047870242aed8b509fe98000928975f359e" +dependencies = [ + "once_cell", + "pest", + "sha2", ] [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + [[package]] name = "rhexdump" version = "0.1.1" @@ -509,23 +772,32 @@ checksum = "c5e9af64574935e39f24d1c0313a997c8b880ca0e087c888bc6af8af31579847" [[package]] name = "rustix" -version = "0.36.8" +version = "0.37.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "ryu" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] [[package]] name = "scrap_parse" @@ -534,61 +806,112 @@ dependencies = [ "anyhow", "binrw", "chrono", - "chrono-humanize", "clap", "configparser", "flate2", "fs-err", "indexmap", "modular-bitfield", + "obj", "rhexdump", "serde", + "serde-pickle", "serde_json", + "steamlocate", + "walkdir", ] [[package]] name = "scratch" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" [[package]] name = "serde" -version = "1.0.152" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" dependencies = [ "serde_derive", ] [[package]] -name = "serde_derive" -version = "1.0.152" +name = "serde-pickle" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "c762ad136a26407c6a80825813600ceeab5e613660d93d79a41f0ec877171e71" +dependencies = [ + "byteorder", + "iter-read", + "num-bigint", + "num-traits", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.160" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "serde_json" -version = "1.0.93" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ + "indexmap", "itoa", "ryu", "serde", ] +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "steamlocate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec01c74611d14a808cb212d17c6e03f0e30736a15ed1d5736f8a53154cea3ae" +dependencies = [ + "dirs", + "keyvalues-parser", + "keyvalues-serde", + "serde", + "steamy-vdf", + "winreg", +] + +[[package]] +name = "steamy-vdf" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533127ad49314bfe71c3d3fd36b3ebac3d24f40618092e70e1cfe8362c7fac79" +dependencies = [ + "nom", +] + [[package]] name = "strsim" version = "0.10.0" @@ -597,9 +920,20 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", @@ -615,6 +949,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "time" version = "0.1.45" @@ -622,15 +976,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", - "wasi", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] [[package]] -name = "unicode-ident" -version = "1.0.6" +name = "typenum" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-width" @@ -638,18 +1004,40 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.84" @@ -671,7 +1059,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-shared", ] @@ -693,7 +1081,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -735,68 +1123,153 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.0", +] + [[package]] name = "windows-sys" version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winreg" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a1a57ff50e9b408431e8f97d5456f2807f8eb2a2cd79b06068fc87f8ecf189" +dependencies = [ + "cfg-if", + "winapi", +] diff --git a/tools/remaster/scrap_parse/Cargo.toml b/tools/remaster/scrap_parse/Cargo.toml index bdb3554..77904e2 100644 --- a/tools/remaster/scrap_parse/Cargo.toml +++ b/tools/remaster/scrap_parse/Cargo.toml @@ -9,13 +9,18 @@ edition = "2021" anyhow = "1.0.69" binrw = "0.11.1" chrono = { version = "0.4.23", features = ["serde"] } -chrono-humanize = "0.2.2" +# chrono-humanize = "0.2.2" clap = { version = "4.1.6", features = ["derive"] } configparser = { version = "3.0.2", features = ["indexmap"] } flate2 = "1.0.25" fs-err = "2.9.0" indexmap = { version = "1.9.2", features = ["serde"] } +# memmap2 = "0.5.10" modular-bitfield = "0.11.2" rhexdump = "0.1.1" serde = { version = "1.0.152", features = ["derive"] } -serde_json = { version = "1.0.93", features = ["unbounded_depth"] } +serde-pickle = "1.1.1" +serde_json = { version = "1.0.95", features = ["preserve_order", "unbounded_depth"] } +steamlocate = "1.1.0" +walkdir = "2.3.3" +obj = "0.10.2" diff --git a/tools/remaster/scrap_parse/blender_plugin/__init__.py b/tools/remaster/scrap_parse/blender_plugin/__init__.py new file mode 100644 index 0000000..84c8e51 --- /dev/null +++ b/tools/remaster/scrap_parse/blender_plugin/__init__.py @@ -0,0 +1,23 @@ +import pickle +import subprocess as SP + +from . import packed_browser +from . import level_import + +def scrap_bridge(*cmd): + cmd=["scrap_parse",*cmd] + proc=SP.Popen(cmd,stderr=None,stdin=None,stdout=SP.PIPE,shell=True,text=False) + stdout,stderr=proc.communicate() + code=proc.wait() + if code: + raise RuntimeError(str(stderr,"utf8")) + return pickle.loads(stdout) + +def register(): + packed_browser.register() + level_import.regiser() + +def unregister(): + packed_browser.unregister() + level_import.unregister() + diff --git a/tools/remaster/scrap_parse/blender_import.py b/tools/remaster/scrap_parse/blender_plugin/level_import.py similarity index 87% rename from tools/remaster/scrap_parse/blender_import.py rename to tools/remaster/scrap_parse/blender_plugin/level_import.py index eeae6cb..d0ef765 100644 --- a/tools/remaster/scrap_parse/blender_import.py +++ b/tools/remaster/scrap_parse/blender_plugin/level_import.py @@ -2,16 +2,16 @@ import bpy import sys import os import re -import json import gzip +import pickle import argparse -import shutil from glob import glob from mathutils import Vector from pathlib import Path import numpy as np import itertools as ITT from pprint import pprint +# from .. import scrap_bridge import bmesh from bpy.props import StringProperty, BoolProperty from bpy_extras.io_utils import ImportHelper @@ -25,12 +25,6 @@ if "--" in sys.argv: parser.add_argument("file_list", nargs="+") cmdline = parser.parse_args(args) - -def fix_pos(xyz): - x, y, z = xyz - return x, z, y - - class ScrapImporter(object): def __init__(self, options): self.unhandled = set() @@ -39,16 +33,22 @@ class ScrapImporter(object): self.model_scale = 1000.0 self.spawn_pos = {} self.objects = {} - print("Loading", filepath) - with gzip.open(filepath, "r") as fh: - data = json.load(fh) + # print("Loading", filepath) + # scrapland_path=scrap_bridge("find-scrapland") + # print(scrapland_path) + # packed_data=scrap_bridge("parse-packed",scrapland_path) + # print(packed_data) + # get_output(["scrap_parse","parse-file","--stdout",scrapland_path,"levels/temple"]) + # raise NotImplementedError() + with gzip.open(filepath, "rb") as fh: + data = pickle.load(fh) self.path = data.pop("path") self.root = data.pop("root") self.config = data.pop("config") - self.dummies = data.pop("dummies")["DUM"]["dummies"] + self.dummies = data.pop("dummies")["dummies"] self.moredummies = data.pop("moredummies") - self.emi = data.pop("emi")["EMI"] - self.sm3 = data.pop("sm3")["SM3"] + self.emi = data.pop("emi") + self.sm3 = data.pop("sm3") def make_empty(self, name, pos, rot=None): empty = bpy.data.objects.new(name, None) @@ -119,7 +119,7 @@ class ScrapImporter(object): bpy.context.scene.collection.objects.link(light) def create_nodes(self): - for node in self.sm3["scene"]["nodes"]: + for node in self.sm3["scene"].get("nodes",[]): node_name = node["name"] node = node.get("content", {}) if not node: @@ -212,6 +212,8 @@ class ScrapImporter(object): ) else: folders = ITT.chain([start_folder], start_folder.parents) + folders=list(folders) + print(f"Looking for {path} in {folders}") for folder in folders: for suffix in file_extensions: for dds in [".", "dds"]: @@ -227,7 +229,7 @@ class ScrapImporter(object): return list(filter(lambda i: (i.type, i.name) == (dtype, name), node.inputs)) - def build_material(self, mat_key, mat_def): + def build_material(self, mat_key, mat_def, map_def): mat_props = dict(m.groups() for m in re.finditer(r"\(\+(\w+)(?::(\w*))?\)",mat_key)) for k,v in mat_props.items(): mat_props[k]=v or True @@ -260,13 +262,13 @@ class ScrapImporter(object): "Roughness": 0.0, "Specular": 0.2, } - tex_slots=[ - "Base Color", - "Metallic", - None, # "Clearcoat" ? env map? - "Normal", - "Emission" - ] + tex_slot_map={ + "base": "Base Color", + "metallic":"Metallic", + "unk_1":None, # "Clearcoat" ? env map? + "bump":"Normal", + "glow":"Emission" + } mat = bpy.data.materials.new(mat_key) mat.use_nodes = True @@ -275,7 +277,13 @@ class ScrapImporter(object): imgs = {} animated_textures={} is_transparent = True - for slot,tex in zip(tex_slots,mat_def["maps"]): + print(map_def) + if map_def[0]: + print("=== MAP[0]:",self.resolve_path(map_def[0])) + if map_def[2]: + print("=== MAP[2]:",self.resolve_path(map_def[2])) + for slot,tex in mat_def["maps"].items(): + slot=tex_slot_map.get(slot) if (slot is None) and tex: self.unhandled.add(tex["texture"]) print(f"Don't know what to do with {tex}") @@ -286,9 +294,7 @@ class ScrapImporter(object): continue tex_name = os.path.basename(tex_file) if ".000." in tex_name: - tex_files=glob(tex_file.replace(".000.",".*.")) - num_frames=len(tex_files) - animated_textures[slot]=num_frames + animated_textures[slot]=len(glob(tex_file.replace(".000.",".*."))) mat_props.update(overrides.get(tex_name,{})) if any( tex_name.find(fragment) != -1 @@ -297,7 +303,7 @@ class ScrapImporter(object): continue else: is_transparent = False - imgs[slot]=bpy.data.images.load(tex_file) + imgs[slot]=bpy.data.images.load(tex_file,check_existing=True) for n in nodes: nodes.remove(n) out = nodes.new("ShaderNodeOutputMaterial") @@ -311,7 +317,6 @@ class ScrapImporter(object): settings.update(glass_settings) for name, value in settings.items(): shader.inputs[name].default_value = value - sockets_used = set() for socket,img in imgs.items(): img_node = nodes.new("ShaderNodeTexImage") img_node.name = img.name @@ -369,17 +374,20 @@ class ScrapImporter(object): node_tree.links.new(imgs["Base Color"].outputs["Color"],transp_shader.inputs["Color"]) shader_out=mix_shader.outputs["Shader"] node_tree.links.new(shader_out, out.inputs["Surface"]) + # try: + # bpy.ops.node.button() + # except: + # pass return mat def apply_maps(self, ob, m_mat, m_map): mat_key, m_mat = m_mat - map_key, m_map = m_map # TODO?: MAP + map_key, m_map = m_map if mat_key == 0: return mat_name = m_mat.get("name", f"MAT:{mat_key:08X}") - map_name = f"MAP:{map_key:08X}" if mat_name not in bpy.data.materials: - ob.active_material = self.build_material(mat_name, m_mat) + ob.active_material = self.build_material(mat_name, m_mat, m_map) else: ob.active_material = bpy.data.materials[mat_name] @@ -424,17 +432,17 @@ class ScrapImporter(object): ob = bpy.data.objects.new(name, me) self.apply_maps(ob, m_mat, m_map) bpy.context.scene.collection.objects.link(ob) - self.objects.setdefault(name, []).append(ob) + self.objects.setdefault(name.split("(")[0], []).append(ob) return ob class Scrap_Load(Operator, ImportHelper): - bl_idname = "scrap_utils.import_json" - bl_label = "Import JSON" + bl_idname = "scrap_utils.import_pickle" + bl_label = "Import Pickle" - filename_ext = ".json.gz" - filter_glob: StringProperty(default="*.json.gz", options={"HIDDEN"}) + filename_ext = ".pkl.gz" + filter_glob: StringProperty(default="*.pkl.gz", options={"HIDDEN"}) create_dummies: BoolProperty( name="Import dummies", @@ -447,25 +455,20 @@ class Scrap_Load(Operator, ImportHelper): ) create_tracks: BoolProperty( - name="Create track curves", - default=True + name="Create track curves", + default=True ) merge_objects: BoolProperty( - name="Merge objects by name", - default=False + name="Merge objects by name", + default=False ) remove_dup_verts: BoolProperty( - name="Remove overlapping vertices\nfor smoother meshes", - default=True + name="Remove overlapping vertices\nfor smoother meshes", + default=True ) - # remove_dup_verts: BoolProperty( - # name="Remove overlapping vertices for smoother meshes", - # default=False - # ) - def execute(self, context): bpy.ops.preferences.addon_enable(module = "node_arrange") @@ -488,7 +491,7 @@ def unregister(): if __name__ == "__main__": if cmdline is None or not cmdline.file_list: register() - bpy.ops.scrap_utils.import_json("INVOKE_DEFAULT") + bpy.ops.scrap_utils.import_pickle("INVOKE_DEFAULT") else: for file in cmdline.file_list: bpy.context.preferences.view.show_splash = False diff --git a/tools/remaster/scrap_parse/blender_plugin/packed_browser.py b/tools/remaster/scrap_parse/blender_plugin/packed_browser.py new file mode 100644 index 0000000..3981c53 --- /dev/null +++ b/tools/remaster/scrap_parse/blender_plugin/packed_browser.py @@ -0,0 +1,118 @@ +import sys +from .. import scrap_bridge +from bpy.props import (StringProperty, BoolProperty, CollectionProperty, + IntProperty) + +bl_info = { + "name": "Packed Archive File", + "blender": (2, 71, 0), + "location": "File > Import", + "description": "Import data from Scrapland .packed Archive", + "category": "Import-Export"} + + + + +class ImportFilearchives(bpy.types.Operator): + """Import whole filearchives directory.""" + bl_idname = "import_scene.packed" + bl_label = 'Import Scrapland .packed' + + directory = StringProperty(name="'Scrapland' folder", + subtype="DIR_PATH", options={'HIDDEN'}) + filter_folder = BoolProperty(default=True, options={'HIDDEN'}) + filter_glob = StringProperty(default="", options={'HIDDEN'}) + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + + def execute(self, context): + # TODO: Validate filepath + bpy.ops.ui.packed_browser('INVOKE_DEFAULT',filepath=self.directory) + return {'FINISHED'} + + +class PackedFile(bpy.types.PropertyGroup): + path = bpy.props.StringProperty() + packed_file = bpy.props.StringProperty() + selected = bpy.props.BoolProperty(name="") + offset = bpy.props.IntProperty() + size = bpy.props.IntProperty() + + +archive = None +class PackedBrowser(bpy.types.Operator): + bl_idname = "ui.packed_browser" + bl_label = "Packed Browser" + bl_options = {'INTERNAL'} + + files = CollectionProperty(type=PackedFile) + selected_index = IntProperty(default=0) + + def invoke(self, context, event): + scrapland_path=scrap_bridge("find-scrapland") + print(scrapland_path) + packed_data=scrap_bridge("parse-packed",scrapland_path) + print(packed_data) + self.packed_data=packed_data + return context.window_manager.invoke_props_dialog(self) + + def draw(self, context): + if self.selected_index != -1: + print("new selected_index: " + str(self.selected_index)) + self.files.clear() + for packed_name,files in self.archive: + for file in files: + entry = self.files.add() + entry.packed_file = packed_name + [entry.path,entry.offset,entry.size]=file + self.selected_index = -1 + self.layout.template_list("PackedDirList", "", self, "current_dir", self, "selected_index") + + def execute(self, context): + print("execute") + return {'FINISHED'} + + +class PackedDirList(bpy.types.UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + operator = data + packed_entry = item + + if self.layout_type in {'DEFAULT', 'COMPACT'}: + layout.prop(packed_entry, "name", text="", emboss=False, icon_value=icon) + layout.prop(packed_entry, "selected") + elif self.layout_type in {'GRID'}: + layout.alignment = 'CENTER' + layout.label(text="", icon_value=icon) + + +def menu_func_import(self, context): + self.layout.operator(ImportFilearchives.bl_idname, text="Scrapland .packed") + +classes=[ + PackedFile, + PackedDirList, + PackedBrowser, + ImportFilearchives, +] + +def register(): + for cls in classes: + bpy.utils.regiser_class(cls) + bpy.types.INFO_MT_file_import.append(menu_func_import) + + +def unregister(): + for cls in reversed(classes): + bpy.utils.unregister_class(cls) + bpy.types.INFO_MT_file_import.remove(menu_func_import) + + +if __name__ == "__main__": + import imp + imp.reload(sys.modules[__name__]) + for cls in classes: + bpy.utils.regiser_class(cls) + diff --git a/tools/remaster/scrap_parse/get_vertex_size.cpp b/tools/remaster/scrap_parse/get_vertex_size.cpp new file mode 100644 index 0000000..783eec4 --- /dev/null +++ b/tools/remaster/scrap_parse/get_vertex_size.cpp @@ -0,0 +1,66 @@ + +int _D3DXGetFVFVertexSize(uint fvf) + +{ + uint uVar1; + uint uVar2; + uint uVar3; + int vert_size; + + uVar1 = fvf & 0xe; + vert_size = 0; + if (uVar1 == 2) { + vert_size = 0xc; + } + else if ((uVar1 == 4) || (uVar1 == 6)) { + vert_size = 0x10; + } + else if (uVar1 == 8) { + vert_size = 0x14; + } + else if (uVar1 == 0xa) { + vert_size = 0x18; + } + else if (uVar1 == 0xc) { + vert_size = 0x1c; + } + else if (uVar1 == 0xe) { + vert_size = 0x20; + } + if ((fvf & 0x10) != 0) { + vert_size += 0xc; + } + if ((fvf & 0x20) != 0) { + vert_size += 4; + } + if ((fvf & 0x40) != 0) { + vert_size += 4; + } + if (fvf < '\0') { + vert_size += 4; + } + uVar1 = fvf >> 8 & 0xf; + uVar3 = fvf >> 16; + if (uVar3 == 0) { + vert_size += uVar1 * 8; + } + else { + for (; uVar1 != 0; uVar1 -= 1) { + uVar2 = uVar3 & 3; + if (uVar2 == 0) { + vert_size += 8; + } + else if (uVar2 == 1) { + vert_size += 0xc; + } + else if (uVar2 == 2) { + vert_size += 0x10; + } + else if (uVar2 == 3) { + vert_size += 4; + } + uVar3 >>= 2; + } + } + return vert_size; +} \ No newline at end of file diff --git a/tools/remaster/scrap_parse/packed_loader.py b/tools/remaster/scrap_parse/packed_loader.py deleted file mode 100644 index ffa6b34..0000000 --- a/tools/remaster/scrap_parse/packed_loader.py +++ /dev/null @@ -1,103 +0,0 @@ -bl_info = { - "name": "Riot Archive File (RAF)", - "blender": (2, 71, 0), - "location": "File > Import", - "description": "Import LoL data of an Riot Archive File", - "category": "Import-Export"} - - -import bpy -from io_scene_lolraf import raf_utils -from bpy.props import (StringProperty, BoolProperty, CollectionProperty, - IntProperty) - - -class ImportFilearchives(bpy.types.Operator): - """Import whole filearchives directory.""" - bl_idname = "import_scene.rafs" - bl_label = 'Import LoL filearchives' - - directory = StringProperty(name="'filearchives' folder", - subtype="DIR_PATH", options={'HIDDEN'}) - filter_folder = BoolProperty(default=True, options={'HIDDEN'}) - filter_glob = StringProperty(default="", options={'HIDDEN'}) - - def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {'RUNNING_MODAL'} - - def execute(self, context): - # TODO: Validate filepath - bpy.ops.ui.raf_browser('INVOKE_DEFAULT',filepath=self.directory) - return {'FINISHED'} - - -class RAFEntry(bpy.types.PropertyGroup): - name = bpy.props.StringProperty() - selected = bpy.props.BoolProperty(name="") - - -archive = None -class RAFBrowser(bpy.types.Operator): - bl_idname = "ui.raf_browser" - bl_label = "RAF-browser" - bl_options = {'INTERNAL'} - - filepath = StringProperty() - current_dir = CollectionProperty(type=RAFEntry) - selected_index = IntProperty(default=0) - - def invoke(self, context, event): - global archive - archive = raf_utils.RAFArchive(self.filepath) - return context.window_manager.invoke_props_dialog(self) - - def draw(self, context): - if self.selected_index != -1: - print("new selected_index: " + str(self.selected_index)) - global archive - # TODO: change current directory of archive - self.current_dir.clear() - for dir in archive.current_dir(): - entry = self.current_dir.add() - entry.name = dir - self.selected_index = -1 - self.layout.template_list("RAFDirList", "", self, "current_dir", self, "selected_index") - - def execute(self, context): - print("execute") - return {'FINISHED'} - - -class RAFDirList(bpy.types.UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname): - operator = data - raf_entry = item - - if self.layout_type in {'DEFAULT', 'COMPACT'}: - layout.prop(raf_entry, "name", text="", emboss=False, icon_value=icon) - layout.prop(raf_entry, "selected") - elif self.layout_type in {'GRID'}: - layout.alignment = 'CENTER' - layout.label(text="", icon_value=icon) - - -def menu_func_import(self, context): - self.layout.operator(ImportFilearchives.bl_idname, text="LoL Filearchives") - - -def register(): - bpy.utils.register_module(__name__) - bpy.types.INFO_MT_file_import.append(menu_func_import) - - -def unregister(): - bpy.utils.unregister_module(__name__) - bpy.types.INFO_MT_file_import.remove(menu_func_import) - - -if __name__ == "__main__": - import imp - imp.reload(raf_utils) - bpy.utils.register_module(__name__) - diff --git a/tools/remaster/scrap_parse/src/find_scrap.rs b/tools/remaster/scrap_parse/src/find_scrap.rs new file mode 100644 index 0000000..4c69b3f --- /dev/null +++ b/tools/remaster/scrap_parse/src/find_scrap.rs @@ -0,0 +1,15 @@ +use std::path::PathBuf; + +use steamlocate::SteamDir; +use anyhow::{bail,Result}; +const APP_ID: u32 = 897610; + +pub(crate) fn get_executable() -> Result { + let Some(mut steam) = SteamDir::locate() else { + bail!("Failed to find steam folder"); + }; + let Some(app) = steam.app(&APP_ID) else { + bail!("App {APP_ID} is not installed!"); + }; + Ok(app.path.clone()) +} \ No newline at end of file diff --git a/tools/remaster/scrap_parse/src/main.rs b/tools/remaster/scrap_parse/src/main.rs index 8d41f58..1dfaca3 100644 --- a/tools/remaster/scrap_parse/src/main.rs +++ b/tools/remaster/scrap_parse/src/main.rs @@ -5,6 +5,7 @@ use binrw::prelude::*; use binrw::until_exclusive; use chrono::{DateTime, NaiveDateTime, Utc}; use clap::Parser; +use clap::Subcommand; use configparser::ini::Ini; use flate2::write::GzEncoder; use flate2::Compression; @@ -15,14 +16,37 @@ use modular_bitfield::specifiers::B2; use modular_bitfield::specifiers::B4; use modular_bitfield::BitfieldSpecifier; use serde::Serialize; -use serde_json::Map; -use serde_json::Value; use std::collections::HashMap; use std::fmt::Debug; use std::fs::File; -use std::io::{BufReader, Read, Seek}; +use std::io::{BufReader, Cursor, Read, Seek}; use std::path::Path; use std::path::PathBuf; +use walkdir::WalkDir; + +mod find_scrap; + +type IniData = IndexMap>>; + +#[binread] +#[derive(Serialize, Debug)] +struct PackedFile{ + path: PascalString, + size: u32, + offset: u32 +} + +#[binread] +#[br(magic = b"BFPK")] +#[derive(Serialize, Debug)] +struct PackedHeader { + #[br(temp,assert(version==0))] + version: u32, + #[br(temp)] + num_files: u32, + #[br(count=num_files)] + files: Vec, +} #[binread] #[derive(Serialize, Debug)] @@ -141,6 +165,7 @@ struct IniSection { #[br(magic = b"INI\0")] #[derive(Debug)] struct INI { + #[br(temp)] size: u32, #[br(temp)] num_sections: u32, @@ -153,13 +178,17 @@ impl Serialize for INI { where S: serde::Serializer, { + use serde::ser::Error; let blocks: Vec = self .sections .iter() .flat_map(|s| s.sections.iter()) .map(|s| s.string.clone()) .collect(); - Ini::new().read(blocks.join("\n")).serialize(serializer) + Ini::new() + .read(blocks.join("\n")) + .map_err(Error::custom)? + .serialize(serializer) } } @@ -227,7 +256,7 @@ enum Pos { #[repr(u32)] #[derive(Debug, Serialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct FVF { - reserved_1: bool, + reserved: bool, pos: Pos, normal: bool, point_size: bool, @@ -267,17 +296,17 @@ impl FVF { } } - fn num_w(&self) -> usize { - use Pos::*; - match self.pos() { - XYZ | XYZRHW => 0, - XYZB1 => 1, - XYZB2 => 2, - XYZB3 => 3, - XYZB4 => 4, - XYZB5 => 5, - } - } + // fn num_w(&self) -> usize { + // use Pos::*; + // match self.pos() { + // XYZ | XYZRHW => 0, + // XYZB1 => 1, + // XYZB2 => 2, + // XYZB3 => 3, + // XYZB4 => 4, + // XYZB5 => 5, + // } + // } } fn vertex_size_from_id(fmt_id: u32) -> Result { @@ -361,6 +390,7 @@ struct MD3D { tris: Vec<[u16; 3]>, mesh_data: LFVF, unk_table_1: RawTable<2>, + rest: Unparsed<0x100> // TODO: // == // unk_t1_count: u32, @@ -383,7 +413,7 @@ enum NodeData { #[br(magic = 0x0u32)] Null, #[br(magic = 0xa1_00_00_01_u32)] - TriangleMesh, // Empty? + TriangleMesh(Unparsed<0x10>), // TODO: Empty or unused? #[br(magic = 0xa1_00_00_02_u32)] Mesh(MD3D), #[br(magic = 0xa2_00_00_04_u32)] @@ -393,7 +423,7 @@ enum NodeData { #[br(magic = 0xa4_00_00_10_u32)] Ground(SUEL), #[br(magic = 0xa5_00_00_20_u32)] - SisPart(Unparsed<0x10>), // TODO: Particles + SistPart(Unparsed<0x10>), // TODO: Particles #[br(magic = 0xa6_00_00_40_u32)] Graphic3D(SPR3), #[br(magic = 0xa6_00_00_80_u32)] @@ -521,6 +551,16 @@ struct MAP { unk_3: Option<[u8; 0xc]>, } +#[binread] +#[derive(Debug, Serialize)] +struct Textures { + base: Optional, + metallic: Optional, + unk_1: Optional, + bump: Optional, + glow: Optional +} + #[binread] #[br(magic = b"MAT\0")] #[derive(Debug, Serialize)] @@ -532,7 +572,7 @@ struct MAT { name: Option, unk_f: [RGBA; 7], unk_data: [RGBA; 0x18 / 4], - maps: [Optional; 5], // Base Color, Metallic?, ???, Normal, Emission + maps: Textures } #[binread] @@ -556,9 +596,9 @@ struct SCN { #[br(temp,assert(unk_3==1))] unk_3: u32, num_nodes: u32, - #[br(count = num_nodes)] // 32 + #[br(count = 1)] // 32 nodes: Vec, - ani: Optional, // TODO:? + // ani: Optional, // TODO: ? } fn convert_timestamp(dt: u32) -> Result> { @@ -682,11 +722,11 @@ struct CM3 { #[binread] #[derive(Debug, Serialize)] struct Dummy { + has_next: u32, name: PascalString, pos: [f32; 3], rot: [f32; 3], info: Optional, - has_next: u32, } #[binread] @@ -697,7 +737,6 @@ struct DUM { #[br(assert(version==1, "Invalid DUM version"))] version: u32, num_dummies: u32, - unk_1: u32, #[br(count=num_dummies)] dummies: Vec, } @@ -826,13 +865,6 @@ enum Data { EMI(EMI), } -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -struct Args { - root: PathBuf, - path: PathBuf, -} - fn parse_file(path: &PathBuf) -> Result { let mut rest_size = 0; let mut fh = BufReader::new(fs::File::open(path)?); @@ -842,11 +874,11 @@ fn parse_file(path: &PathBuf) -> Result { .unwrap_or(0) .try_into() .unwrap_or(u32::MAX); - println!("Read {} bytes from {}", pos, path.display()); + eprintln!("Read {} bytes from {}", pos, path.display()); let mut buffer = [0u8; 0x1000]; if let Ok(n) = fh.read(&mut buffer) { if n != 0 { - println!("Rest:\n{}", rhexdump::hexdump_offset(&buffer[..n], pos)); + eprintln!("Rest:\n{}", rhexdump::hexdump_offset(&buffer[..n], pos)); } }; while let Ok(n) = fh.read(&mut buffer) { @@ -855,52 +887,182 @@ fn parse_file(path: &PathBuf) -> Result { } rest_size += n; } - println!("+{rest_size} unparsed bytes"); + eprintln!("+{rest_size} unparsed bytes"); Ok(ret) } -fn load_ini(path: &PathBuf) -> IndexMap>> { +fn load_ini(path: &PathBuf) -> IniData { Ini::new().load(path).unwrap_or_default() } -fn load_data(root: &Path, path: &Path) -> Result { - let full_path = &root.join(path); - let emi_path = full_path.join("map").join("map3d.emi"); - let sm3_path = emi_path.with_extension("sm3"); - let dum_path = emi_path.with_extension("dum"); - let config_file = emi_path.with_extension("ini"); - let moredummies = emi_path.with_file_name("moredummies").with_extension("ini"); - let mut data = serde_json::to_value(HashMap::<(), ()>::default())?; - data["config"] = serde_json::to_value(load_ini(&config_file))?; - data["moredummies"] = serde_json::to_value(load_ini(&moredummies))?; - data["emi"] = serde_json::to_value(parse_file(&emi_path)?)?; - data["sm3"] = serde_json::to_value(parse_file(&sm3_path)?)?; - data["dummies"] = serde_json::to_value(parse_file(&dum_path)?)?; - data["path"] = serde_json::to_value(path)?; - data["root"] = serde_json::to_value(root)?; - Ok(data) +#[derive(Serialize, Debug)] + +struct Level { + config: IniData, + moredummies: IniData, + emi: EMI, + sm3: SM3, + dummies: DUM, + path: PathBuf, + root: PathBuf, } -fn main() -> Result<()> { - let args = Args::try_parse()?; +impl Level { + fn load(root: &Path, path: &Path) -> Result { + let full_path = &root.join(path); + let emi_path = full_path.join("map").join("map3d.emi"); + let sm3_path = emi_path.with_extension("sm3"); + let dum_path = emi_path.with_extension("dum"); + let config_file = emi_path.with_extension("ini"); + let moredummies = emi_path.with_file_name("moredummies").with_extension("ini"); + let config = load_ini(&config_file); + let moredummies = load_ini(&moredummies); + let Data::EMI(emi) = parse_file(&emi_path)? else { + bail!("Failed to parse EMI at {emi_path}", emi_path=emi_path.display()); + }; + let Data::SM3(sm3) = parse_file(&sm3_path)? else { + bail!("Failed to parse SM3 at {sm3_path}", sm3_path=sm3_path.display()); + }; + let Data::DUM(dummies) = parse_file(&dum_path)? else { + bail!("Failed to parse DUM at {dum_path}", dum_path=dum_path.display()); + }; + Ok(Level { + config, + moredummies, + emi, + sm3, + dummies, + path: path.into(), + root: root.into(), + }) + } +} + +#[derive(Subcommand, Debug)] +enum Commands { + FindScrapland, + ParsePacked { + scrap_path: PathBuf, + }, + ParseFile { + #[clap(long)] + /// Write to stdout + stdout: bool, + /// Scrapland root path + root: PathBuf, + /// Level to parse and convert + level: PathBuf, + }, +} + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +#[command(propagate_version = true)] +struct Args { + #[arg(long,short)] + /// Write data as JSON + json: bool, + #[command(subcommand)] + command: Commands, +} + +fn cmd_parse_packed(root: &Path) -> Result>> { + let mut packed_map = HashMap::new(); + for entry in WalkDir::new(root).into_iter().filter_map(|e| e.ok()) { + let path = entry.path(); + if path + .extension() + .map(|e| e.to_str() == Some("packed")) + .unwrap_or(false) + { + let path = entry.path().to_owned(); + let header: PackedHeader = BufReader::new(File::open(&path)?).read_le()?; + packed_map.insert(path, header.files); + } + } + Ok(packed_map) +} + +fn to_bytes(data: &T, json: bool) -> Result> where T: Serialize { + if json { + Ok(serde_json::to_vec_pretty(data)?) + } else { + Ok(serde_pickle::to_vec(data,Default::default())?) + } +} + +fn cmd_parse_file(stdout: bool, root: &Path, path: &Path, json: bool) -> Result<()> { let out_path = PathBuf::from( - args.path + path .components() .last() .unwrap() .as_os_str() .to_string_lossy() .into_owned(), - ) - .with_extension("json.gz"); - let full_path = &args.root.join(&args.path); - let data = if full_path.is_dir() { - load_data(&args.root, &args.path)? + ); + let out_path = if json { + out_path.with_extension("json.gz") } else { - serde_json::to_value(parse_file(full_path)?)? + out_path.with_extension("pkl.gz") + }; + let full_path = &root.join(path); + let data = if full_path.is_dir() { + let level = Level::load(root, path)?; + to_bytes(&level,json)? + } else { + let data = parse_file(full_path)?; + to_bytes(&data,json)? + }; + let mut data = Cursor::new(data); + if stdout { + let mut stdout = std::io::stdout().lock(); + std::io::copy(&mut data, &mut stdout)?; + } else { + let mut fh = GzEncoder::new(File::create(&out_path)?, Compression::best()); + std::io::copy(&mut data, &mut fh)?; + eprintln!("Wrote {path}", path = out_path.display()); }; - let mut dumpfile = GzEncoder::new(File::create(&out_path)?, Compression::best()); - serde_json::to_writer_pretty(&mut dumpfile, &data)?; - println!("Wrote {path}", path = out_path.display()); + Ok(()) +} + +fn emi_to_obj(emi: EMI) -> ! { + // let mut obj_data = obj::ObjData::default(); + + // for mesh in emi.tri { + // for vert in mesh.data.verts_1.inner.map(|d| d.data).unwrap_or_default() { + // obj_data.position.push(vert.xyz); + // obj_data.normal.push(vert.normal.unwrap_or_default()); + // obj_data.texture.push(vert.tex_1.unwrap_or_default().0.try_into().unwrap()); + // } + // for vert in mesh.data.verts_2.inner.map(|d| d.data).unwrap_or_default() { + // obj_data.position.push(vert.xyz); + // obj_data.normal.push(vert.normal.unwrap_or_default()); + // } + // } + todo!("EMI to OBJ converter"); +} + +fn main() -> Result<()> { + let args = Args::try_parse()?; + match args.command { + Commands::FindScrapland => { + let data = to_bytes(&find_scrap::get_executable()?,args.json)?; + let mut stdout = std::io::stdout().lock(); + std::io::copy(&mut &data[..], &mut stdout)?; + } + Commands::ParsePacked { scrap_path } => { + let data = to_bytes(&cmd_parse_packed(&scrap_path)?,args.json)?; + let mut stdout = std::io::stdout().lock(); + std::io::copy(&mut &data[..], &mut stdout)?; + } + Commands::ParseFile { + stdout, + root, + level, + } => { + cmd_parse_file(stdout, &root, &level, args.json)?; + } + } Ok(()) } diff --git a/tools/remaster/scrap_parse/src/pixel_shader.rs b/tools/remaster/scrap_parse/src/pixel_shader.rs index 7bc87a3..1430524 100644 --- a/tools/remaster/scrap_parse/src/pixel_shader.rs +++ b/tools/remaster/scrap_parse/src/pixel_shader.rs @@ -1,3 +1,7 @@ +// https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx9-graphics-reference-asm-ps-1-x +// +// ################################################ +// // #[derive(Debug)] // enum VecArg { // Tex(f32,f32,f32,f32),