diff --git a/.gitignore b/.gitignore index a44be407..57576085 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ dist/ downloads/ eggs/ .eggs/ -lib/ +./lib/ lib64/ parts/ sdist/ diff --git a/flama/debug/data_structures.py b/flama/debug/data_structures.py index 9dac7a0c..fc1de7aa 100644 --- a/flama/debug/data_structures.py +++ b/flama/debug/data_structures.py @@ -144,20 +144,22 @@ def from_route(cls, route: t.Union["Route", "WebSocketRoute"]) -> "Endpoint": @dataclasses.dataclass(frozen=True) class App: - urls: list[t.Union[Endpoint, "App"]] + apps: list["App"] + endpoints: list[Endpoint] path: str name: t.Optional[str] = None @classmethod def from_app(cls, app: t.Any, path: str = "/", name: t.Optional[str] = None) -> "App": - urls: list[t.Union[Endpoint, App]] = [] + apps: list[App] = [] + endpoints: list[Endpoint] = [] for route in app.routes: try: - urls.append(App.from_app(route.app, path=route.path.path, name=route.name)) + apps.append(App.from_app(route.app, path=route.path.path, name=route.name)) except AttributeError: - urls.append(Endpoint.from_route(route)) + endpoints.append(Endpoint.from_route(route)) - return cls(urls=urls, path=path, name=name) + return cls(apps=apps, endpoints=endpoints, path=path, name=name) @dataclasses.dataclass(frozen=True) diff --git a/flama/http.py b/flama/http.py index 9d82c4a4..67fc38a7 100644 --- a/flama/http.py +++ b/flama/http.py @@ -210,6 +210,8 @@ def __init__(self, *args, **kwargs): *args, **{ **kwargs, + "comment_start_string": "||*", + "comment_end_string": "*||", "block_start_string": "||%", "block_end_string": "%||", "variable_start_string": "||@", @@ -217,8 +219,21 @@ def __init__(self, *args, **kwargs): }, ) + self.filters["safe"] = self.safe self.filters["safe_json"] = self.safe_json + @t.overload + def _escape(self, value: str) -> str: ... + @t.overload + def _escape(self, value: bool) -> bool: ... + @t.overload + def _escape(self, value: int) -> int: ... + @t.overload + def _escape(self, value: float) -> float: ... + @t.overload + def _escape(self, value: None) -> None: ... + @t.overload + def _escape(self, value: types.JSONField) -> types.JSONField: ... def _escape(self, value: types.JSONField) -> types.JSONField: if isinstance(value, (list, tuple)): return [self._escape(x) for x in value] @@ -227,10 +242,13 @@ def _escape(self, value: types.JSONField) -> types.JSONField: return {k: self._escape(v) for k, v in value.items()} if isinstance(value, str): - return html.escape(value).replace("\n", " ") + return html.escape(value).replace("\n", " ") return value + def safe(self, value: str) -> str: + return self._escape(value) + def safe_json(self, value: types.JSONField): return json.dumps(self._escape(value)).replace('"', '\\"') diff --git a/flama/types/json.py b/flama/types/json.py index b72c10ce..61863bb3 100644 --- a/flama/types/json.py +++ b/flama/types/json.py @@ -3,5 +3,5 @@ __all__ = ["JSONField", "JSONSchema"] -JSONField = t.Union[str, int, float, bool, None, list["JSONField"], dict[str, "JSONField"]] +JSONField = t.Union[str, bool, int, float, None, list["JSONField"], dict[str, "JSONField"]] JSONSchema = dict[str, JSONField] diff --git a/package-lock.json b/package-lock.json index f0d34ab7..1e129179 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,48 @@ { "lockfileVersion": 3, "name": "flama", - "packages": {}, + "packages": { + "": { + "dependencies": { + "@tabler/icons-react": "^3.30.0" + } + }, + "node_modules/@tabler/icons": { + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "integrity": "sha512-c8OKLM48l00u9TFbh2qhSODMONIzML8ajtCyq95rW8vzkWcBrKRPM61tdkThz2j4kd5u17srPGIjqdeRUZdfdw==", + "license": "MIT", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.30.0.tgz", + "version": "3.30.0" + }, + "node_modules/@tabler/icons-react": { + "dependencies": { + "@tabler/icons": "3.30.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "integrity": "sha512-9KZ9D1UNAyjlLkkYp2HBPHdf6lAJ2aelDqh8YYAnnmLF3xwprWKxxW8+zw5jlI0IwdfN4XFFuzqePkaw+DpIOg==", + "license": "MIT", + "peerDependencies": { + "react": ">= 16" + }, + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.30.0.tgz", + "version": "3.30.0" + }, + "node_modules/react": { + "engines": { + "node": ">=0.10.0" + }, + "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "license": "MIT", + "peer": true, + "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", + "version": "19.0.0" + } + }, "requires": true } diff --git a/package.json b/package.json new file mode 100644 index 00000000..684346f0 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@tabler/icons-react": "^3.30.0" + } +} diff --git a/templates/babel.config.js b/templates/babel.config.js index 712951b7..359dcb4a 100644 --- a/templates/babel.config.js +++ b/templates/babel.config.js @@ -9,7 +9,12 @@ const config = { corejs: { version: 3, proposals: true }, }, ], - '@babel/preset-react', + [ + '@babel/preset-react', + { + runtime: 'automatic', + }, + ], '@babel/preset-typescript', ], plugins: ['@babel/plugin-transform-runtime', '@babel/plugin-transform-spread'], diff --git a/templates/eslint.config.js b/templates/eslint.config.js index 54ec8ecc..6658271d 100644 --- a/templates/eslint.config.js +++ b/templates/eslint.config.js @@ -28,6 +28,7 @@ export default [ rules: { // turn on errors for missing imports 'import/no-unresolved': 'error', + '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^React$' }], }, settings: { 'import/parsers': { diff --git a/templates/package-lock.json b/templates/package-lock.json index 45c13575..ee36284c 100644 --- a/templates/package-lock.json +++ b/templates/package-lock.json @@ -7,9 +7,11 @@ "name": "papago-templates", "dependencies": { "@heroicons/react": "^2.0.12", + "@tabler/icons-react": "^3.30.0", "prism-react-renderer": "^1.3.5", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "shiki": "^3.0.0" }, "devDependencies": { "@babel/core": "^7.26.9", @@ -21,9 +23,9 @@ "@babel/runtime": "^7.26.9", "@eslint/js": "^9.20.0", "@ianvs/prettier-plugin-sort-imports": "^4.4.0", + "@tailwindcss/postcss": "^4.0.7", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", - "autoprefixer": "^10.4.20", "babel-loader": "^9.2.1", "core-js": "^3.40.0", "css-loader": "^7.1.2", @@ -39,9 +41,8 @@ "postcss": "^8.4.49", "postcss-loader": "^8.1.1", "prettier": "^3.4.1", - "prettier-plugin-tailwindcss": "^0.6.9", - "tailwindcss": "^3.4.15", - "ts-loader": "^9.5.2", + "prettier-plugin-tailwindcss": "^0.6.11", + "tailwindcss": "^4.0.7", "typescript": "^5.7.3", "typescript-eslint": "^8.24.0", "webpack": "^5.96.1", @@ -2051,24 +2052,6 @@ "node": ">=10" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", @@ -2181,23 +2164,352 @@ "node": ">=12.4.0" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@shikijs/core": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.0.0.tgz", + "integrity": "sha512-gSm3JQf2J2psiUn5bWokmZwnu5N0jfBtRps4CQ1B+qrFvmZCRAkMVoaxgl9qZgAFK5KisLAS3//XaMFVytYHKw==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.0.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.4" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.0.0.tgz", + "integrity": "sha512-zoB10hTfvk1iZk1ldt6VaF+0iucQL+4TtSvTdTu5MhOeLPLEf5nZ8Wz6uxlp99y627OLalYa2z4W0iTTwb6oyA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.0.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^3.1.0" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.0.0.tgz", + "integrity": "sha512-uM9lqwMrlPHPVcdpAN/4pAzTJah1pY7mi9f1MxG887SDkjF/tdiQK+5200Y8N5Hg125sewdMQ1K2agoAo8hDiA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.0.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.0.0.tgz", + "integrity": "sha512-HBsZAukiYz7k3hzttPWa0en3PABEwK3cpxcAcERRwvwuKc5pn0Y+yPxAIYZtN9cFdtNqrbFJNhfcEu/xbG1u/A==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.0.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.0.0.tgz", + "integrity": "sha512-mz63nyVB5nXWsv5H2hifDFIThZEJ/cJhMq1/+0JjMdOuuBq2H2D1Fn8UM5yzUtEvap/ipRltv381+hsHZFs4ug==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.0.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.0.0.tgz", + "integrity": "sha512-kh/xgZHxI6m9trVvPw+C47jyVHx190r0F5gkF+VO5vYB54UtcoPJe66dzZmK7GbJbzmtGEGbOwct/jsoPjjUqg==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@tabler/icons": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.30.0.tgz", + "integrity": "sha512-c8OKLM48l00u9TFbh2qhSODMONIzML8ajtCyq95rW8vzkWcBrKRPM61tdkThz2j4kd5u17srPGIjqdeRUZdfdw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@tabler/icons-react": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.30.0.tgz", + "integrity": "sha512-9KZ9D1UNAyjlLkkYp2HBPHdf6lAJ2aelDqh8YYAnnmLF3xwprWKxxW8+zw5jlI0IwdfN4XFFuzqePkaw+DpIOg==", + "license": "MIT", + "dependencies": { + "@tabler/icons": "3.30.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "react": ">= 16" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.0.7.tgz", + "integrity": "sha512-dkFXufkbRB2mu3FPsW5xLAUWJyexpJA+/VtQj18k3SUiJVLdpgzBd1v1gRRcIpEJj7K5KpxBKfOXlZxT3ZZRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "tailwindcss": "4.0.7" + } + }, + "node_modules/@tailwindcss/node/node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.0.7.tgz", + "integrity": "sha512-yr6w5YMgjy+B+zkJiJtIYGXW+HNYOPfRPtSs+aqLnKwdEzNrGv4ZuJh9hYJ3mcA+HMq/K1rtFV+KsEr65S558g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.0.7", + "@tailwindcss/oxide-darwin-arm64": "4.0.7", + "@tailwindcss/oxide-darwin-x64": "4.0.7", + "@tailwindcss/oxide-freebsd-x64": "4.0.7", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.7", + "@tailwindcss/oxide-linux-arm64-gnu": "4.0.7", + "@tailwindcss/oxide-linux-arm64-musl": "4.0.7", + "@tailwindcss/oxide-linux-x64-gnu": "4.0.7", + "@tailwindcss/oxide-linux-x64-musl": "4.0.7", + "@tailwindcss/oxide-win32-arm64-msvc": "4.0.7", + "@tailwindcss/oxide-win32-x64-msvc": "4.0.7" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.7.tgz", + "integrity": "sha512-5iQXXcAeOHBZy8ASfHFm1k0O/9wR2E3tKh6+P+ilZZbQiMgu+qrnfpBWYPc3FPuQdWiWb73069WT5D+CAfx/tg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=14" + "node": ">= 10" } }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.7.tgz", + "integrity": "sha512-7yGZtEc5IgVYylqK/2B0yVqoofk4UAbkn1ygNpIJZyrOhbymsfr8uUFCueTu2fUxmAYIfMZ8waWo2dLg/NgLgg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.7.tgz", + "integrity": "sha512-tPQDV20fBjb26yWbPqT1ZSoDChomMCiXTKn4jupMSoMCFyU7+OJvIY1ryjqBuY622dEBJ8LnCDDWsnj1lX9nNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.7.tgz", + "integrity": "sha512-sZqJpTyTZiknU9LLHuByg5GKTW+u3FqM7q7myequAXxKOpAFiOfXpY710FuMY+gjzSapyRbDXJlsTQtCyiTo5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.7.tgz", + "integrity": "sha512-PBgvULgeSswjd8cbZ91gdIcIDMdc3TUHV5XemEpxlqt9M8KoydJzkuB/Dt910jYdofOIaTWRL6adG9nJICvU4A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.7.tgz", + "integrity": "sha512-By/a2yeh+e9b+C67F88ndSwVJl2A3tcUDb29FbedDi+DZ4Mr07Oqw9Y1DrDrtHIDhIZ3bmmiL1dkH2YxrtV+zw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.7.tgz", + "integrity": "sha512-WHYs3cpPEJb/ccyT20NOzopYQkl7JKncNBUbb77YFlwlXMVJLLV3nrXQKhr7DmZxz2ZXqjyUwsj2rdzd9stYdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.7.tgz", + "integrity": "sha512-7bP1UyuX9kFxbOwkeIJhBZNevKYPXB6xZI37v09fqi6rqRJR8elybwjMUHm54GVP+UTtJ14ueB1K54Dy1tIO6w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.7.tgz", + "integrity": "sha512-gBQIV8nL/LuhARNGeroqzXymMzzW5wQzqlteVqOVoqwEfpHOP3GMird5pGFbnpY+NP0fOlsZGrxxOPQ4W/84bQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.7.tgz", + "integrity": "sha512-aH530NFfx0kpQpvYMfWoeG03zGnRCMVlQG8do/5XeahYydz+6SIBxA1tl/cyITSJyWZHyVt6GVNkXeAD30v0Xg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.7.tgz", + "integrity": "sha512-8Cva6bbJN7ZJx320k7vxGGdU0ewmpfS5A4PudyzUuofdi8MgeINuiiWiPQ0VZCda/GX88K6qp+6UpDZNVr8HMQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.0.7.tgz", + "integrity": "sha512-zXcKs1uGssVDlnsQ+iwrkul5GPKvsXPynGCuk/eXLx3DVhHlQKMpA6tXN2oO28x2ki1xRBTfadKiHy2taVvp7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.0.7", + "@tailwindcss/oxide": "4.0.7", + "lightningcss": "^1.29.1", + "postcss": "^8.4.41", + "tailwindcss": "4.0.7" + } }, "node_modules/@trysound/sax": { "version": "0.2.0", @@ -2238,6 +2550,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/html-minifier-terser": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-7.0.2.tgz", @@ -2259,6 +2580,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/node": { "version": "22.13.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz", @@ -2289,6 +2619,12 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.24.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.1.tgz", @@ -2508,6 +2844,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -2812,19 +3154,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2851,34 +3180,6 @@ "node": ">=16" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, - "license": "MIT" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3053,44 +3354,6 @@ "node": ">= 0.4" } }, - "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -3174,19 +3437,6 @@ "dev": true, "license": "MIT" }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -3329,16 +3579,6 @@ "tslib": "^2.0.3" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -3373,6 +3613,16 @@ ], "license": "CC-BY-4.0" }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3390,42 +3640,24 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/chrome-trace-event": { @@ -3500,6 +3732,16 @@ "dev": true, "license": "MIT" }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/commander": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", @@ -3955,19 +4197,40 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, - "license": "Apache-2.0" + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/doctrine": { "version": "2.1.0", @@ -4067,13 +4330,6 @@ "node": ">= 0.4" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, "node_modules/electron-to-chromium": { "version": "1.5.102", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz", @@ -4081,11 +4337,10 @@ "dev": true, "license": "ISC" }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, + "node_modules/emoji-regex-xs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", + "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", "license": "MIT" }, "node_modules/enhanced-resolve": { @@ -4916,64 +5171,18 @@ }, "node_modules/for-each": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, "engines": { - "node": "*" + "node": ">= 0.4" }, "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/function-bind": { @@ -5097,27 +5306,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5138,32 +5326,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/globals": { "version": "15.15.0", "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", @@ -5315,6 +5477,42 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/html-bundler-webpack-plugin": { "version": "4.18.0", "resolved": "https://registry.npmjs.org/html-bundler-webpack-plugin/-/html-bundler-webpack-plugin-4.18.0.tgz", @@ -5407,6 +5605,16 @@ "node": "^14.13.1 || >=16.0.0" } }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", @@ -5632,19 +5840,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-boolean-object": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", @@ -5775,16 +5970,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-generator-function": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", @@ -6057,22 +6242,6 @@ "node": ">= 0.4" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -6238,6 +6407,245 @@ "node": ">= 0.8.0" } }, + "node_modules/lightningcss": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz", + "integrity": "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.29.1", + "lightningcss-darwin-x64": "1.29.1", + "lightningcss-freebsd-x64": "1.29.1", + "lightningcss-linux-arm-gnueabihf": "1.29.1", + "lightningcss-linux-arm64-gnu": "1.29.1", + "lightningcss-linux-arm64-musl": "1.29.1", + "lightningcss-linux-x64-gnu": "1.29.1", + "lightningcss-linux-x64-musl": "1.29.1", + "lightningcss-win32-arm64-msvc": "1.29.1", + "lightningcss-win32-x64-msvc": "1.29.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz", + "integrity": "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz", + "integrity": "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz", + "integrity": "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz", + "integrity": "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz", + "integrity": "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz", + "integrity": "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz", + "integrity": "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz", + "integrity": "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz", + "integrity": "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz", + "integrity": "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -6355,6 +6763,27 @@ "node": ">= 0.4" } }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", @@ -6375,10 +6804,99 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 8" + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" } }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", + "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -6439,16 +6957,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -6456,18 +6964,6 @@ "dev": true, "license": "MIT" }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "node_modules/nanoid": { "version": "3.3.8", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", @@ -6519,26 +7015,6 @@ "dev": true, "license": "MIT" }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -6562,16 +7038,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -6684,6 +7150,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/oniguruma-to-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz", + "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==", + "license": "MIT", + "dependencies": { + "emoji-regex-xs": "^1.0.0", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -6762,13 +7239,6 @@ "node": ">=6" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -6850,30 +7320,6 @@ "dev": true, "license": "MIT" }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -6894,26 +7340,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/pkg-dir": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", @@ -7179,80 +7605,6 @@ "postcss": "^8.4.31" } }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, "node_modules/postcss-loader": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", @@ -7494,46 +7846,6 @@ "postcss": "^8.1.0" } }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-nested/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/postcss-normalize-charset": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.0.tgz", @@ -7920,6 +8232,16 @@ "react-is": "^16.13.1" } }, + "node_modules/property-information": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.0.0.tgz", + "integrity": "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7989,29 +8311,6 @@ "dev": true, "license": "MIT" }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/rechoir": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", @@ -8085,6 +8384,30 @@ "@babel/runtime": "^7.8.4" } }, + "node_modules/regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", + "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", @@ -8520,6 +8843,22 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.0.0.tgz", + "integrity": "sha512-x6MMdYN9auPGx7kMFtyKbaj65eCdetfrfkvQZwqisZLnGMnAZsZxOpcWD0ElvLPFWHOSMukVyN9Opm7TxQjnZA==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.0.0", + "@shikijs/engine-javascript": "3.0.0", + "@shikijs/engine-oniguruma": "3.0.0", + "@shikijs/langs": "3.0.0", + "@shikijs/themes": "3.0.0", + "@shikijs/types": "3.0.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -8596,19 +8935,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8640,77 +8966,23 @@ "source-map": "^0.6.0" } }, - "node_modules/stable-hash": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", - "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", "dev": true, "license": "MIT" }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string.prototype.matchall": { "version": "4.0.12", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", @@ -8809,44 +9081,18 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/strip-bom": { @@ -8903,39 +9149,6 @@ "node": ">=4" } }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -8999,56 +9212,11 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.17", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", - "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.6.0", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.6", - "lilconfig": "^3.1.3", - "micromatch": "^4.0.8", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.47", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.2", - "postcss-nested": "^6.2.0", - "postcss-selector-parser": "^6.1.2", - "resolve": "^1.22.8", - "sucrase": "^3.35.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.7.tgz", + "integrity": "sha512-yH5bPPyapavo7L+547h3c4jcBXcrKwybQRjwdEIVAd9iXRvy/3T1CC6XSQEgZtRySjKfqvo3Cc0ZF1DTheuIdA==", "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } + "license": "MIT" }, "node_modules/tapable": { "version": "2.2.1", @@ -9121,29 +9289,6 @@ "dev": true, "license": "MIT" }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/tinyglobby": { "version": "0.2.11", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.11.tgz", @@ -9202,6 +9347,16 @@ "node": ">=8.0" } }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-api-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", @@ -9215,57 +9370,6 @@ "typescript": ">=4.8.4" } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/ts-loader": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz", - "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -9497,6 +9601,74 @@ "node": ">=4" } }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", @@ -9545,6 +9717,34 @@ "dev": true, "license": "MIT" }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/watchpack": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", @@ -9822,101 +10022,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -9924,19 +10029,6 @@ "dev": true, "license": "ISC" }, - "node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -9949,6 +10041,16 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/templates/package.json b/templates/package.json index 7f486b76..f146b4ee 100644 --- a/templates/package.json +++ b/templates/package.json @@ -21,9 +21,9 @@ "@babel/runtime": "^7.26.9", "@eslint/js": "^9.20.0", "@ianvs/prettier-plugin-sort-imports": "^4.4.0", + "@tailwindcss/postcss": "^4.0.7", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", - "autoprefixer": "^10.4.20", "babel-loader": "^9.2.1", "core-js": "^3.40.0", "css-loader": "^7.1.2", @@ -39,9 +39,8 @@ "postcss": "^8.4.49", "postcss-loader": "^8.1.1", "prettier": "^3.4.1", - "prettier-plugin-tailwindcss": "^0.6.9", - "tailwindcss": "^3.4.15", - "ts-loader": "^9.5.2", + "prettier-plugin-tailwindcss": "^0.6.11", + "tailwindcss": "^4.0.7", "typescript": "^5.7.3", "typescript-eslint": "^8.24.0", "webpack": "^5.96.1", @@ -49,8 +48,10 @@ }, "dependencies": { "@heroicons/react": "^2.0.12", + "@tabler/icons-react": "^3.30.0", "prism-react-renderer": "^1.3.5", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "shiki": "^3.0.0" } } diff --git a/templates/postcss.config.js b/templates/postcss.config.js index 96f508c6..d0613fc4 100644 --- a/templates/postcss.config.js +++ b/templates/postcss.config.js @@ -1,11 +1,7 @@ /** @type {import('postcss-load-config').Config} */ const config = { plugins: { - 'postcss-import': {}, - autoprefixer: {}, - 'tailwindcss/nesting': {}, - tailwindcss: {}, - cssnano: {}, + '@tailwindcss/postcss': { optimize: { minify: true } }, }, } diff --git a/templates/src/apps/debug/error_404.tsx b/templates/src/apps/debug/error_404.tsx index c9a4d53e..11e98a38 100644 --- a/templates/src/apps/debug/error_404.tsx +++ b/templates/src/apps/debug/error_404.tsx @@ -1,24 +1,18 @@ -import EnvironmentTable, { Environment } from '@/components/debug/EnvironmentTable' -import ErrorTitle from '@/components/debug/ErrorTitle' -import RequestTable, { Request } from '@/components/debug/RequestTable' -import AppURLTree, { RootApp } from '@/components/debug/URLTree' -import FlamaLogo from '@/components/FlamaLogo' - -import '@/styles/main.css' +import ReactDOM from 'react-dom/client' -import React from 'react' +import { Request } from '@/data/debug' +import { EnvironmentTable, ErrorTitle, RequestTable, URLTree } from '@/ui/components' +import { FlamaLogo } from '@/ui/logos' -import ReactDOM from 'react-dom/client' +import '@/styles/main.css' -function ServerErrorPage() { - const rootApp = new RootApp() +function Page() { const request = new Request() - const environment = new Environment() return ( <>
-
+
@@ -30,32 +24,32 @@ function ServerErrorPage() {
-
-

Application URLs

+
+

Application URLs

- +
-
-
-

Request

+
+
+

Request

-
- +
+
-
-
-

Environment

+
+
+

Environment

-
- +
+
@@ -63,4 +57,4 @@ function ServerErrorPage() { ) } -ReactDOM.createRoot(document.getElementById('app')!).render() +ReactDOM.createRoot(document.getElementById('app')!).render() diff --git a/templates/src/apps/debug/error_500.tsx b/templates/src/apps/debug/error_500.tsx index e8d82313..c0a556d8 100644 --- a/templates/src/apps/debug/error_500.tsx +++ b/templates/src/apps/debug/error_500.tsx @@ -1,24 +1,19 @@ -import EnvironmentTable, { Environment } from '@/components/debug/EnvironmentTable' -import ErrorTitle from '@/components/debug/ErrorTitle' -import ErrorTraceback, { Error } from '@/components/debug/ErrorTraceback' -import RequestTable, { Request } from '@/components/debug/RequestTable' -import FlamaLogo from '@/components/FlamaLogo' - -import '@/styles/main.css' +import ReactDOM from 'react-dom/client' -import React from 'react' +import { Error, Request } from '@/data/debug' +import { EnvironmentTable, ErrorTitle, ErrorTraceback, RequestTable } from '@/ui/components' +import { FlamaLogo } from '@/ui/logos' -import ReactDOM from 'react-dom/client' +import '@/styles/main.css' -function ServerErrorPage() { +function Page() { const error = new Error() const request = new Request() - const environment = new Environment() return ( <>
-
+
-
-

Traceback

+
+

Traceback

- +
-
-
-

Request

+
+
+

Request

-
- +
+
-
-
-

Environment

+
+
+

Environment

-
- +
+
@@ -68,4 +63,4 @@ function ServerErrorPage() { ) } -ReactDOM.createRoot(document.getElementById('app')!).render() +ReactDOM.createRoot(document.getElementById('app')!).render() diff --git a/templates/src/components/ClipboardButton.tsx b/templates/src/components/ClipboardButton.tsx deleted file mode 100644 index 1a23d724..00000000 --- a/templates/src/components/ClipboardButton.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React, { useCallback, useState } from 'react' -import { CheckIcon, DocumentDuplicateIcon } from '@heroicons/react/24/outline' - -export interface ClipboardButtonProps { - code: string -} - -export default function ClipboardButton({ code }: ClipboardButtonProps) { - const [copied, setCopied] = useState(false) - - const onCopy = useCallback(async () => { - await navigator.clipboard.writeText(code) - setCopied(true) - setTimeout(() => setCopied(false), 3000) - }, [code, setCopied]) - - return ( -
- -
- ) -} diff --git a/templates/src/components/CodeBlock.tsx b/templates/src/components/CodeBlock.tsx deleted file mode 100644 index 65da4b6c..00000000 --- a/templates/src/components/CodeBlock.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import type { Language } from 'prism-react-renderer' -import Highlight, { defaultProps } from 'prism-react-renderer' -import ClipboardButton from '@/components/ClipboardButton' -import React, { MutableRefObject } from 'react' - -interface LineNumbersProps { - lines: number - token?: string -} - -function LineNumbers({ lines, token }: LineNumbersProps) { - return ( - - ) -} - -interface CodeWrapperProps extends React.ComponentProps<'pre'> { - lines: number - token?: string | boolean - code: string - copyButton?: boolean -} - -function CodeWrapper({ lines, token, code, copyButton, children, className }: CodeWrapperProps) { - return ( -
-      {token && }
-      {children}
-      {copyButton && }
-    
- ) -} - -export interface CodeBlockProps { - code: string - language?: Language - lineNumbers?: string | boolean - copyButton?: boolean - selectedLine?: number - selectedLineRef?: MutableRefObject -} - -export default function CodeBlock({ - code, - language, - selectedLine, - selectedLineRef, - lineNumbers = true, - copyButton = true, -}: CodeBlockProps) { - const { theme, ...props } = defaultProps - - return language ? ( - - {({ className, tokens, getLineProps, getTokenProps }) => ( - - {tokens.map((line, i) => { - const { - className: lineClassName, - key: lineKey, - ...lineProps - } = getLineProps({ - line, - key: i, - }) - return ( -
- {line.map((token, j) => { - const { key: tokenKey, ...tokenProps } = getTokenProps({ - token, - key: j, - }) - return - })} -
- ) - })} -
- )} -
- ) : ( - - {code} - - ) -} diff --git a/templates/src/components/CodeWindow.tsx b/templates/src/components/CodeWindow.tsx deleted file mode 100644 index 377e2fe1..00000000 --- a/templates/src/components/CodeWindow.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import Window, { WindowProps } from '@/components/Window' -import CodeBlock, { CodeBlockProps } from '@/components/CodeBlock' -import React, { useEffect, useRef } from 'react' - -export interface CodeWindowProps extends WindowProps, CodeBlockProps { - autoScroll?: boolean -} - -export default function CodeWindow({ - title, - code, - language, - lineNumbers, - copyButton, - selectedLine, - autoScroll = false, - className, -}: CodeWindowProps) { - const scrollContainerRef = useRef(null) - const scrollTargetRef = useRef(null) - - useEffect(() => { - if (autoScroll && scrollContainerRef.current && scrollTargetRef.current) - scrollContainerRef.current.scrollTo({ - top: scrollTargetRef.current.offsetTop - scrollContainerRef.current.clientHeight / 2, - left: 0, - behavior: 'smooth', - }) - }) - - return ( - -
- -
-
- ) -} diff --git a/templates/src/components/FlamaIcon.tsx b/templates/src/components/FlamaIcon.tsx deleted file mode 100644 index 9bbacea7..00000000 --- a/templates/src/components/FlamaIcon.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' - -export default function FlamaIcon({ ...props }: React.ComponentProps<'svg'>) { - return ( - - - - - - ) -} diff --git a/templates/src/components/FlamaLogo.tsx b/templates/src/components/FlamaLogo.tsx deleted file mode 100644 index cfba6a05..00000000 --- a/templates/src/components/FlamaLogo.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import FlamaIcon from '@/components/FlamaIcon' -import React from 'react' - -export default function FlamaLogo() { - return ( - - - Flama - - ) -} diff --git a/templates/src/components/Window.tsx b/templates/src/components/Window.tsx deleted file mode 100644 index 526fadfc..00000000 --- a/templates/src/components/Window.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { MinusCircleIcon, PlusCircleIcon, XCircleIcon } from '@heroicons/react/24/solid' -import React, { MutableRefObject, useCallback, useState } from 'react' - -export interface WindowProps extends React.ComponentProps<'div'> { - title?: string - contentRef?: MutableRefObject -} - -export default function Window({ title, contentRef, className, children }: WindowProps) { - const [state, setState] = useState('open') - - const onMinimize = useCallback(() => setState(state === 'open' ? 'closed' : 'open'), [state, setState]) - const onMaximize = useCallback(() => setState('full'), [setState]) - const onClose = useCallback(() => setState('closed'), [setState]) - - return ( -
- {state === 'full' && ( - - ) -} diff --git a/templates/src/components/debug/EnvironmentTable.tsx b/templates/src/components/debug/EnvironmentTable.tsx deleted file mode 100644 index 9250d2cb..00000000 --- a/templates/src/components/debug/EnvironmentTable.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react' - -export class Environment { - pythonVersion: string - python: string - platform: string - path: string[] - - constructor() { - this.pythonVersion = '||@ environment.python_version @||' - this.python = '||@ environment.python @||' - this.platform = '||@ environment.platform @||' - this.path = JSON.parse('||@ environment.path|safe_json @||') as string[] - } -} - -interface EnvironmentTableProps extends React.ComponentProps<'table'> { - environment: Environment -} - -export default function EnvironmentTable({ environment, ...props }: EnvironmentTableProps) { - const { pythonVersion, python, platform, path } = environment - - return ( - - - - - - - - - - - - - - - - - - - -
Python version{pythonVersion}
Python{python}
Platform{platform}
Path -
    - {path.map((item, i) => ( -
  • {item}
  • - ))} -
-
- ) -} diff --git a/templates/src/components/debug/ErrorTraceback.tsx b/templates/src/components/debug/ErrorTraceback.tsx deleted file mode 100644 index 8338c875..00000000 --- a/templates/src/components/debug/ErrorTraceback.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import CodeWindow from '@/components/CodeWindow' -import React, { useEffect, useMemo, useRef, useState } from 'react' - -interface Frame { - filename: string - function: string - line: number - vendor: boolean - code: string -} - -export class Error { - error: string - description: string - traceback: Frame[] - - constructor() { - this.error = '||@ error.error @||' - this.description = '||@ error.description @||' - this.traceback = JSON.parse('||@ error.traceback|safe_json @||') as Frame[] - } -} - -interface TracebackListItemProps { - frame: Frame - isActive: boolean -} - -function TracebackListItem({ frame, isActive }: TracebackListItemProps) { - const filename = - frame.filename.length > 35 && frame.filename.split('/').length > 2 - ? frame.filename.split('/', 1).concat(['...', frame.filename.split('/').slice(-1)[0]]) - : frame.filename.split('/') - - return ( -
-
-
-
- {filename.map((value, i) => ( - - {i > 0 && /} - {value} - - ))} - : - {frame.line} -
-
- {frame.function} -
-
-
- ) -} - -interface TracebackListProps { - traceback: Frame[] - selected: number - - setSelected(i: number): void -} - -function TracebackList({ traceback, selected, setSelected }: TracebackListProps) { - const itemRef = useRef(null) - const listRef = useRef(null) - - useEffect(() => { - if (itemRef.current && listRef.current) - listRef.current.scrollTo({ - top: itemRef.current.offsetTop - listRef.current.clientHeight / 2, - left: 0, - behavior: 'smooth', - }) - }, [itemRef, listRef]) - - return ( -
-
    - {traceback.map((frame, i) => ( -
  • setSelected(i)}> - -
  • - ))} -
-
- ) -} - -interface ErrorTracebackProps extends React.ComponentProps<'div'> { - error: Error -} - -export default function ErrorTraceback({ error, ...props }: ErrorTracebackProps) { - const { traceback } = error - const [selected, setSelected] = useState(traceback.length - 1) - - const code = useMemo( - () => new DOMParser().parseFromString(traceback[selected].code, 'text/html').body.textContent || '', - [selected, traceback] - ) - - return ( -
-
- -
-
- -
-
- ) -} diff --git a/templates/src/components/debug/RequestTable.tsx b/templates/src/components/debug/RequestTable.tsx deleted file mode 100644 index b0f21294..00000000 --- a/templates/src/components/debug/RequestTable.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import React from 'react' - -export class Request { - path: string - method: string - clientHost: string - clientPort: number - pathParams: Map - queryParams: Map - headers: Map - cookies: Map - - constructor() { - this.path = '||@ request.path @||' - this.method = '||@ request.method @||' - this.clientHost = '||@ request.client.host @||' - this.clientPort = parseInt('||@ request.client.port @||') - this.pathParams = new Map( - Object.entries(JSON.parse('||@ request.params.path|safe_json @||') as object) - ) - this.queryParams = new Map( - Object.entries(JSON.parse('||@ request.params.query|safe_json @||') as object) - ) - this.headers = new Map(Object.entries(JSON.parse('||@ request.headers|safe_json @||') as object)) - this.cookies = new Map(Object.entries(JSON.parse('||@ request.cookies|safe_json @||') as object)) - } -} - -export interface RequestTableProps extends React.ComponentProps<'table'> { - request: Request -} - -export default function RequestTable({ request, ...props }: RequestTableProps) { - const { path, method, pathParams, queryParams, headers, cookies, clientHost, clientPort } = request - - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - {clientHost && ( - - - - - )} - {clientPort && ( - - - - - )} - -
Path{path}
Method{method}
Query params -
    - {Object.entries(queryParams).map(([key, value], i) => ( -
  • - {`${key} :`} - {value} -
  • - ))} -
-
Path params -
    - {Object.entries(pathParams).map(([key, value], i) => ( -
  • - {`${key} :`} - {value} -
  • - ))} -
-
Headers -
    - {Object.entries(headers).map(([key, value], i) => ( -
  • - {`${key} :`} - {value} -
  • - ))} -
-
Cookies -
    - {Object.entries(cookies).map(([key, value], i) => ( -
  • - {`${key} :`} - {value} -
  • - ))} -
-
Client host{clientHost}
Client port{clientPort}
- ) -} diff --git a/templates/src/components/debug/URLTree.tsx b/templates/src/components/debug/URLTree.tsx deleted file mode 100644 index 97fe530f..00000000 --- a/templates/src/components/debug/URLTree.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import { ChevronRightIcon } from '@heroicons/react/20/solid' -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' - -interface URL { - endpoint: string - file: string - line: number - module: string - name?: string - path: string -} - -interface App { - name?: string - path: string - urls: (URL | App)[] -} - -export class RootApp { - name?: string - path: string - urls: (URL | App)[] - - constructor() { - this.name = '||@ app.name @||' - this.path = '||@ app.path @||' - this.urls = JSON.parse('||@ app.urls|safe_json @||') as (URL | App)[] - } -} - -interface TooltipProps { - data: Map -} - -function Tooltip({ data }: TooltipProps) { - return ( -
-
    - {Array.from(data.entries()) - .sort((a, b) => a[0].localeCompare(b[0])) - .filter((x) => x[1]) - .map(([k, v], i) => ( -
  • - {k}: {v} -
  • - ))} -
-
- ) -} - -function isApp(item: URL | App): item is App { - return 'urls' in item -} - -interface URLProps { - url: URL -} - -function URL({ url }: URLProps) { - const { endpoint, file, line, module, name, path } = url - return ( -
-
-
-
{path}
-
- -
- ) -} - -interface AppProps { - app: App -} - -function App({ app }: AppProps) { - const { name, path, urls } = app - const [isOpen, setIsOpen] = useState(false) - const contentRef = useRef(null) - - const countItems = useCallback((items: (App | URL)[]): number => - items.reduce((y, x) => y + (isApp(x) ? 1 + countItems(x.urls) : 1), 0), []) - - const urlsLength = useMemo(() => countItems(urls), [countItems, urls]) - - useEffect(() => { - if (contentRef.current) contentRef.current.style.maxHeight = `${isOpen ? urlsLength * 32 : 0}px` - }, [isOpen, contentRef, urlsLength]) - - return ( -
-
-
setIsOpen(!isOpen)} - > -
- -
-
{path}
-
- -
-
- -
-
- ) -} - -interface URLListProps { - urls: (URL | App)[] -} - -function URLList({ urls }: URLListProps) { - return ( -
    - {urls - .sort((a, b) => a.path.localeCompare(b.path)) - .map((item) => ( -
  • - {isApp(item) ? : } -
  • - ))} -
- ) -} - -export interface URLTreeProps { - root: RootApp -} - -export default function URLTree({ root }: URLTreeProps) { - const { urls } = root - - return ( -
- -
- ) -} diff --git a/templates/src/data/debug/Environment.ts b/templates/src/data/debug/Environment.ts new file mode 100644 index 00000000..675f42aa --- /dev/null +++ b/templates/src/data/debug/Environment.ts @@ -0,0 +1,13 @@ +export default class Environment { + pythonVersion: string + python: string + platform: string + path: string[] + + constructor() { + this.pythonVersion = '||@ environment.python_version|safe @||' + this.python = '||@ environment.python|safe @||' + this.platform = '||@ environment.platform|safe @||' + this.path = JSON.parse('||@ environment.path|safe_json @||') as string[] + } +} diff --git a/templates/src/data/debug/Error.ts b/templates/src/data/debug/Error.ts new file mode 100644 index 00000000..3e427272 --- /dev/null +++ b/templates/src/data/debug/Error.ts @@ -0,0 +1,19 @@ +interface Frame { + filename: string + function: string + line: number + vendor: boolean + code: string +} + +export default class Error { + error: string + description: string + traceback: Frame[] + + constructor() { + this.error = '||@ error.error @||' + this.description = '||@ error.description @||' + this.traceback = JSON.parse('||@ error.traceback|safe_json @||') as Frame[] + } +} diff --git a/templates/src/data/debug/Request.ts b/templates/src/data/debug/Request.ts new file mode 100644 index 00000000..cf4296df --- /dev/null +++ b/templates/src/data/debug/Request.ts @@ -0,0 +1,25 @@ +export default class Request { + path: string + method: string + clientHost: string + clientPort: number + pathParams: Map + queryParams: Map + headers: Map + cookies: Map + + constructor() { + this.path = '||@ request.path @||' + this.method = '||@ request.method @||' + this.clientHost = '||@ request.client.host @||' + this.clientPort = parseInt('||@ request.client.port @||') + this.pathParams = new Map( + Object.entries(JSON.parse('||@ request.params.path|safe_json @||') as object), + ) + this.queryParams = new Map( + Object.entries(JSON.parse('||@ request.params.query|safe_json @||') as object), + ) + this.headers = new Map(Object.entries(JSON.parse('||@ request.headers|safe_json @||') as object)) + this.cookies = new Map(Object.entries(JSON.parse('||@ request.cookies|safe_json @||') as object)) + } +} diff --git a/templates/src/data/debug/URLs.ts b/templates/src/data/debug/URLs.ts new file mode 100644 index 00000000..615c24eb --- /dev/null +++ b/templates/src/data/debug/URLs.ts @@ -0,0 +1,29 @@ +interface Endpoint { + endpoint: string + file: string + line: number + module: string + name?: string + path: string +} + +interface App { + name?: string + path: string + apps: App[] + endpoints: Endpoint[] +} + +export default class URLs { + name?: string + path: string + apps: App[] + endpoints: Endpoint[] + + constructor() { + this.name = '||@ app.name @||' + this.path = '||@ app.path @||' + this.apps = JSON.parse('||@ app.apps|safe_json @||') as App[] + this.endpoints = JSON.parse('||@ app.endpoints|safe_json @||') as Endpoint[] + } +} diff --git a/templates/src/data/debug/index.ts b/templates/src/data/debug/index.ts new file mode 100644 index 00000000..8221ca0e --- /dev/null +++ b/templates/src/data/debug/index.ts @@ -0,0 +1,4 @@ +export { default as Environment } from './Environment' +export { default as Error } from './Error' +export { default as Request } from './Request' +export { default as URLs } from './URLs' diff --git a/templates/src/styles/base.css b/templates/src/styles/base.css deleted file mode 100644 index bcf21ebb..00000000 --- a/templates/src/styles/base.css +++ /dev/null @@ -1,5 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - - diff --git a/templates/src/styles/main.css b/templates/src/styles/main.css index 23ee3b19..697d16ba 100644 --- a/templates/src/styles/main.css +++ b/templates/src/styles/main.css @@ -1,11 +1,13 @@ -@import 'base.css'; +@import 'tailwindcss'; +@import './theme.css'; /*! purgecss start ignore */ -@import 'scrollbar.css'; -@import 'prism.css'; +@import './scrollbar.css'; +@import './prism.css'; /*! purgecss end ignore */ body { - height: 100%; - @apply bg-primary-100 text-primary-600; -} \ No newline at end of file + height: 100%; + @apply bg-primary-100 text-primary-600; +} + diff --git a/templates/src/styles/prism.css b/templates/src/styles/prism.css index 9bf5ae52..cc23a60f 100644 --- a/templates/src/styles/prism.css +++ b/templates/src/styles/prism.css @@ -1,91 +1,91 @@ code[class*='language-'], pre[class*='language-'] { - color: theme('colors.primary.200'); - background-color: inherit; + color: theme('colors.primary.200'); + background-color: inherit; - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; } .token-line-selected { - background-color: theme('colors.brand.700'); + background-color: theme('colors.flama.700'); } .token { - &.comment, - &.block-comment, - &.prolog, - &.doctype, - &.cdata { - color: #999; - } + &.comment, + &.block-comment, + &.prolog, + &.doctype, + &.cdata { + color: #999; + } - &.punctuation { - color: #ccc; - } + &.punctuation { + color: #ccc; + } - &.tag, - &.attr-name, - &.namespace, - &.deleted { - color: #e2777a; - } + &.tag, + &.attr-name, + &.namespace, + &.deleted { + color: #e2777a; + } - &.function-name { - color: #6196cc; - } + &.function-name { + color: #6196cc; + } - &.boolean, - &.number, - &.function { - color: #f08d49; - } + &.boolean, + &.number, + &.function { + color: #f08d49; + } - &.property, - &.class-name, - &.constant, - &.symbol { - color: #f8c555; - } + &.property, + &.class-name, + &.constant, + &.symbol { + color: #f8c555; + } - &.selector, - &.important, - &.atrule, - &.keyword, - &.builtin { - color: #cc99cd; - } + &.selector, + &.important, + &.atrule, + &.keyword, + &.builtin { + color: #cc99cd; + } - &.string, - &.char, - &.attr-value, - &.regex, - &.variable { - color: #7ec699; - } + &.string, + &.char, + &.attr-value, + &.regex, + &.variable { + color: #7ec699; + } - &.operator, - &.entity, - &.url { - color: #67cdcc; - } + &.operator, + &.entity, + &.url { + color: #67cdcc; + } - &.inserted { - color: green; - } + &.inserted { + color: green; + } - &.important, - &.bold { - font-weight: bold; - } + &.important, + &.bold { + font-weight: bold; + } - &.italic { - font-style: italic; - } + &.italic { + font-style: italic; + } - &.entity { - cursor: help; - } + &.entity { + cursor: help; + } } diff --git a/templates/src/styles/schemas/docs.css b/templates/src/styles/schemas/docs.css index 58613fdb..68937ab7 100644 --- a/templates/src/styles/schemas/docs.css +++ b/templates/src/styles/schemas/docs.css @@ -1,15 +1,15 @@ -@import "../main.css"; +@import '../main.css'; .sl-elements-api { - min-height: 100vh; + min-height: 100vh; - /* Sidebar */ + /* Sidebar */ - > div:first-child { - @apply border-r border-brand-500/50; + > div:first-child { + @apply border-flama/50 border-r; - .sl-bg-primary-tint { - @apply bg-brand-500/30; - } + .sl-bg-primary-tint { + @apply bg-flama-500/30; } -} \ No newline at end of file + } +} diff --git a/templates/src/styles/theme.css b/templates/src/styles/theme.css new file mode 100644 index 00000000..e0abd10d --- /dev/null +++ b/templates/src/styles/theme.css @@ -0,0 +1,98 @@ +@theme { + /* Fonts */ + --font-sans: + 'Lato', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', + 'Noto Color Emoji'; + --font-serif: 'Lato', ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif; + --font-mono: + 'Fira Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; + --font-alternative: + 'Montserrat', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', + 'Noto Color Emoji'; + + /* Colors */ + --color-*: initial; + --color-vortico: #008080; + --color-vortico-50: #00dcdc; + --color-vortico-100: #00d2d2; + --color-vortico-200: #00bdbd; + --color-vortico-300: #00a9a9; + --color-vortico-400: #009494; + --color-vortico-500: #008080; + --color-vortico-600: #007171; + --color-vortico-700: #006161; + --color-vortico-800: #005252; + --color-vortico-900: #004343; + --color-vortico-950: #003b3b; + + --color-bruma: #00bbd5; + --color-bruma-50: #ebfeff; + --color-bruma-100: #cefcff; + --color-bruma-200: #a2f7ff; + --color-bruma-300: #63effd; + --color-bruma-400: #1cdcf4; + --color-bruma-500: #00bbd5; + --color-bruma-600: #0398b7; + --color-bruma-700: #0a7994; + --color-bruma-800: #126178; + --color-bruma-900: #145165; + --color-bruma-950: #063646; + + --color-bosque: #9e744f; + --color-bosque-50: #f7f4ef; + --color-bosque-100: #ebe3d6; + --color-bosque-200: #d9c8af; + --color-bosque-300: #c2a682; + --color-bosque-400: #b0895f; + --color-bosque-500: #9e744f; + --color-bosque-600: #8a5f44; + --color-bosque-700: #6f4939; + --color-bosque-800: #5f3f34; + --color-bosque-900: #523731; + --color-bosque-950: #2f1d19; + + --color-ciclon: #00976e; + --color-ciclon-50: #ebfef6; + --color-ciclon-100: #d0fbe7; + --color-ciclon-200: #a4f6d3; + --color-ciclon-300: #6aebbd; + --color-ciclon-400: #2fd8a1; + --color-ciclon-500: #0abf8a; + --color-ciclon-600: #00976e; + --color-ciclon-700: #007c5e; + --color-ciclon-800: #03624b; + --color-ciclon-900: #04503f; + --color-ciclon-950: #012d25; + + --color-flama: #e25822; + --color-flama-50: #fdf5ef; + --color-flama-100: #fbe8d9; + --color-flama-200: #f6cdb2; + --color-flama-300: #f0ac81; + --color-flama-400: #e9804e; + --color-flama-500: #e25822; + --color-flama-600: #d54821; + --color-flama-700: #b1351d; + --color-flama-800: #8d2d1f; + --color-flama-900: #72271c; + --color-flama-950: #3d110d; + + --color-primary: #656775; + --color-primary-50: #f5f5f6; + --color-primary-100: #e5e6e8; + --color-primary-200: #cdced4; + --color-primary-300: #aaabb6; + --color-primary-400: #808290; + --color-primary-500: #656775; + --color-primary-600: #575863; + --color-primary-700: #4a4a54; + --color-primary-800: #3f3f46; + --color-primary-900: #3a3a3f; + --color-primary-950: #242428; + + /* Sizes */ + --breakpoint-3xl: 120rem; + + --container-8xl: 96rem; + --container-9xl: 120rem; +} diff --git a/templates/src/templates/react.html.eta b/templates/src/templates/react.html.eta deleted file mode 100644 index 89e44d0d..00000000 --- a/templates/src/templates/react.html.eta +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - ||@ title @|| - - -
- - - - diff --git a/templates/src/ui/components/EnvironmentTable.tsx b/templates/src/ui/components/EnvironmentTable.tsx new file mode 100644 index 00000000..1bfd35d3 --- /dev/null +++ b/templates/src/ui/components/EnvironmentTable.tsx @@ -0,0 +1,23 @@ +import { Environment } from '@/data/debug' +import { TableArrayValue as ArrayValue, TableRow as Row, Table, TableValue as Value } from '@/ui/elements' + +export default function EnvironmentTable() { + const { pythonVersion, python, platform, path } = new Environment() + + return ( + + + + + + + + + + + + + +
+ ) +} diff --git a/templates/src/components/debug/ErrorTitle.tsx b/templates/src/ui/components/ErrorTitle.tsx similarity index 83% rename from templates/src/components/debug/ErrorTitle.tsx rename to templates/src/ui/components/ErrorTitle.tsx index c997d422..b867b2c1 100644 --- a/templates/src/components/debug/ErrorTitle.tsx +++ b/templates/src/ui/components/ErrorTitle.tsx @@ -1,5 +1,3 @@ -import React from 'react' - export interface ErrorTitleProps { error: string method: string @@ -11,7 +9,7 @@ export default function ErrorTitle({ error, method, path, description }: ErrorTi return ( <>
- {error} raised at {method}{' '} + {error} raised at {method}{' '} {path}
{description &&
{description}
} diff --git a/templates/src/ui/components/ErrorTraceback.tsx b/templates/src/ui/components/ErrorTraceback.tsx new file mode 100644 index 00000000..e0a76975 --- /dev/null +++ b/templates/src/ui/components/ErrorTraceback.tsx @@ -0,0 +1,107 @@ +import React, { useEffect, useMemo, useRef, useState } from 'react' + +import { IconCircleFilled } from '@tabler/icons-react' + +import { Error } from '@/data/debug' +import { Code, Window } from '@/ui/elements' +import { html } from '@/ui/lib/codecs' + +type TFrame = Error['traceback'][number] + +function TracebackListItem({ frame, isActive }: { frame: TFrame; isActive: boolean }) { + const filename = + frame.filename.length > 35 && frame.filename.split('/').length > 2 + ? frame.filename.split('/', 1).concat(['...', frame.filename.split('/').slice(-1)[0]]) + : frame.filename.split('/') + + return ( +
+
+
+ +
+
+
+ {filename.map((value, i) => ( + + {i > 0 && /} + {value} + + ))} + : + {frame.line} +
+
+ {frame.function} +
+
+
+
+ ) +} + +function TracebackList({ + traceback, + selected, + setSelected, +}: { + traceback: TFrame[] + selected: number + setSelected(i: number): void +}) { + const itemRef = useRef(null) + const listRef = useRef(null) + + useEffect(() => { + if (itemRef.current && listRef.current) + listRef.current.scrollTo({ + top: itemRef.current.offsetTop - listRef.current.clientHeight / 2, + left: 0, + behavior: 'smooth', + }) + }, [itemRef, listRef]) + + return ( +
    + {traceback.map((frame, i) => ( +
  • setSelected(i)}> + +
  • + ))} +
+ ) +} + +export default function ErrorTraceback() { + const { traceback } = new Error() + const [selected, setSelected] = useState(traceback.length - 1) + + const code = useMemo(() => html.decode(traceback[selected].code), [selected, traceback]) + + return ( +
+
+ +
+
+ + + +
+
+ ) +} diff --git a/templates/src/ui/components/RequestTable.tsx b/templates/src/ui/components/RequestTable.tsx new file mode 100644 index 00000000..29fea2d4 --- /dev/null +++ b/templates/src/ui/components/RequestTable.tsx @@ -0,0 +1,39 @@ +import { Request } from '@/data/debug' +import { TableMapValue as MapValue, TableRow as Row, Table, TableValue as Value } from '@/ui/elements' + +export default function RequestTable() { + const { path, method, pathParams, queryParams, headers, cookies, clientHost, clientPort } = new Request() + + return ( + + + + + + + + + + + + + + + + + + + + {clientHost && ( + + + + )} + {clientPort && ( + + + + )} +
+ ) +} diff --git a/templates/src/ui/components/URLTree.tsx b/templates/src/ui/components/URLTree.tsx new file mode 100644 index 00000000..61b2c3c3 --- /dev/null +++ b/templates/src/ui/components/URLTree.tsx @@ -0,0 +1,116 @@ +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' + +import { IconChevronRight, IconCircleFilled } from '@tabler/icons-react' + +import { URLs } from '@/data/debug' + +type TApp = URLs['apps'][number] +type TEndpoint = URLs['endpoints'][number] + +function Tooltip({ data }: { data: Map }) { + return ( +
+
    + {Array.from(data.entries()) + .sort((a, b) => a[0].localeCompare(b[0])) + .filter((x) => x[1]) + .map(([k, v], i) => ( +
  • + {k}: {v} +
  • + ))} +
+
+ ) +} + +function Endpoint({ endpoint: e }: { endpoint: TEndpoint }) { + const { endpoint, file, line, module, name, path } = e + return ( +
+
+
+ +
+
{path}
+
+ +
+ ) +} + +function App({ app }: { app: TApp }) { + const { name, path, apps, endpoints } = app + const [isOpen, setIsOpen] = useState(false) + const contentRef = useRef(null) + + const countItems = useCallback( + (apps: TApp[], endpoints: TEndpoint[]): number => + endpoints.length + apps.reduce((y, x) => y + 1 + countItems(x.apps, x.endpoints), 0), + [], + ) + + const urlsLength = useMemo(() => countItems(apps, endpoints), [countItems, apps, endpoints]) + + useEffect(() => { + if (contentRef.current) contentRef.current.style.maxHeight = `${isOpen ? urlsLength * 34 : 0}px` + }, [isOpen, contentRef, urlsLength]) + + return ( +
+
+
setIsOpen(!isOpen)} + > +
+ +
+
{path}
+
+ +
+
+ +
+
+ ) +} + +function AppURLs({ apps, endpoints }: { apps: URLs['apps']; endpoints: URLs['endpoints'] }) { + const urls = [ + ...apps.map((item) => ({ + key: item.path, + node: ( +
  • + +
  • + ), + })), + ...endpoints.map((item) => ({ + key: item.path, + node: ( +
  • + +
  • + ), + })), + ].sort((a, b) => a.key.localeCompare(b.key)) + + return
      {urls.map(({ node }) => node)}
    +} + +export default function URLTree() { + const { apps, endpoints } = new URLs() + + return ( +
    + +
    + ) +} diff --git a/templates/src/ui/components/index.ts b/templates/src/ui/components/index.ts new file mode 100644 index 00000000..0df44790 --- /dev/null +++ b/templates/src/ui/components/index.ts @@ -0,0 +1,5 @@ +export { default as EnvironmentTable } from './EnvironmentTable' +export { default as ErrorTitle } from './ErrorTitle' +export { default as ErrorTraceback } from './ErrorTraceback' +export { default as RequestTable } from './RequestTable' +export { default as URLTree } from './URLTree' diff --git a/templates/src/ui/elements/ClipboardButton.tsx b/templates/src/ui/elements/ClipboardButton.tsx new file mode 100644 index 00000000..6f96be75 --- /dev/null +++ b/templates/src/ui/elements/ClipboardButton.tsx @@ -0,0 +1,33 @@ +import { useCallback, useState } from 'react' + +import { IconCheck, IconClipboardCopy } from '@tabler/icons-react' + +export interface ClipboardButtonProps { + code: string +} + +export default function ClipboardButton({ code }: ClipboardButtonProps) { + const [copied, setCopied] = useState(false) + + const onCopy = useCallback(async () => { + await navigator.clipboard.writeText(code) + setCopied(true) + setTimeout(() => setCopied(false), 3000) + }, [code, setCopied]) + + return ( +
    + +
    + ) +} diff --git a/templates/src/ui/elements/Code/Code.tsx b/templates/src/ui/elements/Code/Code.tsx new file mode 100644 index 00000000..d0c7a45a --- /dev/null +++ b/templates/src/ui/elements/Code/Code.tsx @@ -0,0 +1,32 @@ +import CodeBlock from './CodeBlock' +import CodeInline from './CodeInline' +import HighlightCode from './HighlightCode' +import PlainCode from './PlainCode' +import type { Lines } from './types' + +export interface CodeProps { + code: string + language?: string + lines?: Lines + copyButton?: boolean + selectedLine?: number + className?: string +} + +export default function Code({ code, language, lines, copyButton = true, selectedLine, className }: CodeProps) { + const isInline = lines === undefined && code.split('\n').length === 1 + + const renderedCode = language ? ( + + ) : ( + + ) + + return isInline ? ( + {renderedCode} + ) : ( + + {renderedCode} + + ) +} diff --git a/templates/src/ui/elements/Code/CodeBlock.tsx b/templates/src/ui/elements/Code/CodeBlock.tsx new file mode 100644 index 00000000..34e3b8bb --- /dev/null +++ b/templates/src/ui/elements/Code/CodeBlock.tsx @@ -0,0 +1,49 @@ +import React, { useEffect, useRef } from 'react' + +import { ClipboardButton } from '@/ui/elements' + +import LineNumbers from './LineNumbers' +import type { Lines } from './types' + +const LINE_HEIGHT = 20 + +interface CodeBlockProps { + code: string + lines?: Lines + copyButton?: boolean + children: React.ReactNode + selectedLine?: number + className?: string +} + +export default function CodeBlock({ + lines = { type: 'number' }, + copyButton = true, + code, + selectedLine, + className, + children, +}: CodeBlockProps) { + const ref = useRef(null) + + useEffect(() => { + if (ref.current && selectedLine) { + ref.current.scrollTo({ + top: selectedLine * LINE_HEIGHT - ref.current.clientHeight * 0.5, + left: 0, + behavior: 'smooth', + }) + } + }, [ref, selectedLine]) + + return ( +
    + {lines && } +
    {children}
    + {copyButton && } +
    + ) +} diff --git a/templates/src/ui/elements/Code/CodeInline.tsx b/templates/src/ui/elements/Code/CodeInline.tsx new file mode 100644 index 00000000..4e902fa2 --- /dev/null +++ b/templates/src/ui/elements/Code/CodeInline.tsx @@ -0,0 +1,10 @@ +import React from 'react' + +interface CodeInlineProps { + className?: string + children: React.ReactNode +} + +export default function CodeInline({ className, children }: CodeInlineProps) { + return {children} +} diff --git a/templates/src/ui/elements/Code/HighlightCode.tsx b/templates/src/ui/elements/Code/HighlightCode.tsx new file mode 100644 index 00000000..43fd8015 --- /dev/null +++ b/templates/src/ui/elements/Code/HighlightCode.tsx @@ -0,0 +1,38 @@ +import getHighlighter, { theme, tokenStyle } from '@/ui/lib/highlighter' + +export default function HighlightCode({ + code, + language, + selectedLine, +}: { + code: string + language: string + selectedLine?: number +}) { + const tokens = getHighlighter().codeToTokens(code, { lang: language, theme }) + + const isInline = tokens?.tokens.length === 1 + + return ( + + {tokens?.tokens.map((line, i) => ( + + {line.length === 0 ? ( +
    + ) : ( + line.map((token, j) => ( + + {token.content} + + )) + )} +
    + ))} +
    + ) +} diff --git a/templates/src/ui/elements/Code/LineNumbers.tsx b/templates/src/ui/elements/Code/LineNumbers.tsx new file mode 100644 index 00000000..9a83aef4 --- /dev/null +++ b/templates/src/ui/elements/Code/LineNumbers.tsx @@ -0,0 +1,22 @@ +import type { Lines } from './types' + +interface LineNumberProps { + type: Lines['type'] + lines?: number + token?: string +} + +export default function LineNumbers({ type, lines, token }: LineNumberProps) { + return ( + + ) +} diff --git a/templates/src/ui/elements/Code/PlainCode.tsx b/templates/src/ui/elements/Code/PlainCode.tsx new file mode 100644 index 00000000..43e84dc8 --- /dev/null +++ b/templates/src/ui/elements/Code/PlainCode.tsx @@ -0,0 +1,28 @@ +export default function PlainCode({ code, selectedLine }: { code: string; selectedLine?: number }) { + const lines = code.split('\n') + + const isInline = lines.length === 1 + + return ( + + {lines.map((line, i) => ( + + {line.length === 0 ? ( +
    + ) : ( + line.split(' ').map((token, j) => ( + + {token} + + )) + )} +
    + ))} +
    + ) +} diff --git a/templates/src/ui/elements/Code/index.ts b/templates/src/ui/elements/Code/index.ts new file mode 100644 index 00000000..4c6e6c22 --- /dev/null +++ b/templates/src/ui/elements/Code/index.ts @@ -0,0 +1,2 @@ +export { default as Code, type CodeProps } from './Code' +export type { Lines as CodeLines } from './types' diff --git a/templates/src/ui/elements/Code/types.ts b/templates/src/ui/elements/Code/types.ts new file mode 100644 index 00000000..8b164f99 --- /dev/null +++ b/templates/src/ui/elements/Code/types.ts @@ -0,0 +1,4 @@ +export interface Lines { + type: 'number' | 'token' + token?: string +} diff --git a/templates/src/ui/elements/Table/ArrayValue.tsx b/templates/src/ui/elements/Table/ArrayValue.tsx new file mode 100644 index 00000000..3562fdce --- /dev/null +++ b/templates/src/ui/elements/Table/ArrayValue.tsx @@ -0,0 +1,17 @@ +import Value from './Value' + +export interface ArrayValueProps { + array: (string | number | boolean)[] +} + +export default function ArrayValue({ array }: ArrayValueProps) { + return ( +
      + {array.map((value, i) => ( +
    • + +
    • + ))} +
    + ) +} diff --git a/templates/src/ui/elements/Table/MapValue.tsx b/templates/src/ui/elements/Table/MapValue.tsx new file mode 100644 index 00000000..f0257dae --- /dev/null +++ b/templates/src/ui/elements/Table/MapValue.tsx @@ -0,0 +1,20 @@ +import Value from './Value' + +export interface MapValueProps { + map: Map +} + +export default function MapValue({ map }: MapValueProps) { + return ( +
      + {Array.from(map).map(([key, value], i) => ( +
    • + {`${key}:`} + + + +
    • + ))} +
    + ) +} diff --git a/templates/src/ui/elements/Table/Row.tsx b/templates/src/ui/elements/Table/Row.tsx new file mode 100644 index 00000000..92e2e699 --- /dev/null +++ b/templates/src/ui/elements/Table/Row.tsx @@ -0,0 +1,16 @@ +import React from 'react' + +export interface RowProps extends React.ComponentProps<'tr'> { + header: string +} + +export default function Row({ header, children, ...props }: RowProps) { + return ( + + + {header} + + {children} + + ) +} diff --git a/templates/src/ui/elements/Table/Table.tsx b/templates/src/ui/elements/Table/Table.tsx new file mode 100644 index 00000000..775abb63 --- /dev/null +++ b/templates/src/ui/elements/Table/Table.tsx @@ -0,0 +1,9 @@ +import React from 'react' + +export default function Table({ children }: Omit, 'className'>) { + return ( + + {children} +
    + ) +} diff --git a/templates/src/ui/elements/Table/Value.tsx b/templates/src/ui/elements/Table/Value.tsx new file mode 100644 index 00000000..99af9249 --- /dev/null +++ b/templates/src/ui/elements/Table/Value.tsx @@ -0,0 +1,9 @@ +import { html } from '@/ui/lib/codecs' + +export interface ValueProps { + value: string | number | boolean +} + +export default function Value({ value }: ValueProps) { + return {html.decode(String(value))} +} diff --git a/templates/src/ui/elements/Table/index.ts b/templates/src/ui/elements/Table/index.ts new file mode 100644 index 00000000..6f460b0a --- /dev/null +++ b/templates/src/ui/elements/Table/index.ts @@ -0,0 +1,5 @@ +export { default as TableArrayValue } from './ArrayValue' +export { default as TableMapValue } from './MapValue' +export { default as TableRow } from './Row' +export { default as Table } from './Table' +export { default as TableValue } from './Value' diff --git a/templates/src/ui/elements/Window.tsx b/templates/src/ui/elements/Window.tsx new file mode 100644 index 00000000..97b132e3 --- /dev/null +++ b/templates/src/ui/elements/Window.tsx @@ -0,0 +1,79 @@ +import React, { RefObject, useCallback, useEffect, useRef, useState } from 'react' + +import { IconCircleDotFilled, IconCirclePlusFilled, IconCircleXFilled } from '@tabler/icons-react' + +export interface WindowProps extends React.ComponentProps<'div'> { + title?: string + autoScroll?: RefObject +} + +export default function Window({ title, autoScroll, className, children }: WindowProps) { + const containerRef = useRef(null) + const [state, setState] = useState<'open' | 'closed' | 'full'>('open') + + const onMinimize = useCallback(() => setState(state === 'open' ? 'closed' : 'open'), [state, setState]) + const onMaximize = useCallback(() => setState('full'), [setState]) + const onClose = useCallback(() => setState('closed'), [setState]) + + useEffect(() => { + if (containerRef.current && autoScroll?.current) + containerRef.current.scrollTo({ + top: autoScroll.current.offsetTop - containerRef.current.clientHeight / 2, + left: 0, + behavior: 'smooth', + }) + }, [autoScroll, containerRef]) + + return ( +
    + {state === 'full' && ( +
    + )} +
    +
    + {title} +
    + + + +
    +
    +
    + {children} +
    +
    +
    + ) +} diff --git a/templates/src/ui/elements/index.ts b/templates/src/ui/elements/index.ts new file mode 100644 index 00000000..189e0ca1 --- /dev/null +++ b/templates/src/ui/elements/index.ts @@ -0,0 +1,4 @@ +export * from './Code' +export * from './Table' +export { default as ClipboardButton } from './ClipboardButton' +export { default as Window } from './Window' diff --git a/templates/src/ui/icons/Flama.tsx b/templates/src/ui/icons/Flama.tsx new file mode 100644 index 00000000..f7d14025 --- /dev/null +++ b/templates/src/ui/icons/Flama.tsx @@ -0,0 +1,12 @@ +import React from 'react' + +export default function Flama({ ...props }: React.ComponentProps<'svg'>) { + return ( + + + + ) +} diff --git a/templates/src/ui/icons/Vortico.tsx b/templates/src/ui/icons/Vortico.tsx new file mode 100644 index 00000000..82aee3ef --- /dev/null +++ b/templates/src/ui/icons/Vortico.tsx @@ -0,0 +1,28 @@ +import React from 'react' + +export default function Vortico({ ...props }: React.ComponentProps<'svg'>) { + return ( + + + + + + + + ) +} diff --git a/templates/src/ui/icons/index.ts b/templates/src/ui/icons/index.ts new file mode 100644 index 00000000..2fa38025 --- /dev/null +++ b/templates/src/ui/icons/index.ts @@ -0,0 +1,2 @@ +export { default as FlamaIcon } from './Flama' +export { default as VorticoIcon } from './Vortico' diff --git a/templates/src/ui/lib/codecs/html.ts b/templates/src/ui/lib/codecs/html.ts new file mode 100644 index 00000000..7b46b22f --- /dev/null +++ b/templates/src/ui/lib/codecs/html.ts @@ -0,0 +1,5 @@ +function decode(input: string) { + return new DOMParser().parseFromString(input, 'text/html').body.textContent || '' +} + +export default { decode } diff --git a/templates/src/ui/lib/codecs/index.ts b/templates/src/ui/lib/codecs/index.ts new file mode 100644 index 00000000..c9c4a354 --- /dev/null +++ b/templates/src/ui/lib/codecs/index.ts @@ -0,0 +1 @@ +export { default as html } from './html' diff --git a/templates/src/ui/lib/highlighter.ts b/templates/src/ui/lib/highlighter.ts new file mode 100644 index 00000000..4533a056 --- /dev/null +++ b/templates/src/ui/lib/highlighter.ts @@ -0,0 +1,136 @@ +import python from '@shikijs/langs/python' +import { createHighlighterCoreSync, getTokenStyleObject, type HighlighterCore, type ThemedToken } from 'shiki/core' +import { createJavaScriptRegexEngine } from 'shiki/engine/javascript' + +export const theme = { + name: 'vortico', + settings: [ + { + scope: ['markup.changed', 'markup.deleted', 'markup.inserted', 'punctuation', 'variable', 'constant', 'source'], + settings: { + foreground: '#cdced4', // Primary light + }, + }, + { + scope: ['comment', 'punctuation.definition.comment'], + settings: { + foreground: '#575863', // Primary dark + }, + }, + { + scope: [ + 'constant.character.character-class.regexp', + 'constant.character.set.regexp', + 'constant.language', + 'constant.numeric', + 'constant.other.character-class.regexp', + 'constant.other.character-class.set.regexp', + 'constant.other.color.rgb-value', + 'constant.other.rgb-value', + 'constant.regexp', + 'constant.sha.git-rebase', + 'invalid', + 'meta.class', + 'meta.function-call.generic', + 'support.function.git-rebase', + 'token.error-token', + ], + settings: { + foreground: '#9e744f', // Bosque + }, + }, + { + scope: [ + 'keyword', + 'meta.structure.dictionary.key.python', + 'support.class', + 'support.function', + 'support.type', + 'support.type.vendored.property-name', + 'support.type.property-name', + 'storage', + ], + settings: { + foreground: '#e25822', // Flama + }, + }, + { + scope: [ + 'meta.attribute', + 'meta.definition', + 'meta.indexed-name', + 'punctuation.character.set.begin.regexp', + 'punctuation.character.set.end.regexp', + 'punctuation.definition.character-class.regexp', + 'punctuation.definition.group.regexp', + 'punctuation.definition.group.assertion.regexp', + 'punctuation.definition.template-expression.begin', + 'punctuation.definition.template-expression.end', + 'support.other.parenthesis.regexp', + ], + settings: { + foreground: '#00bbd5', // Bruma + }, + }, + { + scope: [ + 'string', + 'string.tag', + 'string.value', + 'string.regexp', + 'string.quoted', + 'punctuation.definition.string', + ], + settings: { + foreground: '#00976e', // Ciclon + }, + }, + { + scope: ['header', 'variable.language', 'variable.other.enummember', 'variable.parameter', 'entity.name.function'], + settings: { + foreground: '#008080', // Vortico + }, + }, + { + scope: [ + 'emphasis', + 'markup.bold', + 'markup.changed', + 'markup.deleted', + 'markup.heading', + 'markup.inserted', + 'markup.italic', + 'markup.strikethrough', + 'meta.template.expression', + 'punctuation.definition.quote.begin.markdown', + 'punctuation.definition.list.begin.markdown', + ], + settings: { + fontStyle: 'italic', + }, + }, + { + scope: ['strong'], + settings: { + fontStyle: 'bold', + }, + }, + ], +} + +export function tokenStyle(token: ThemedToken) { + return getTokenStyleObject(token) +} + +let highlighter: HighlighterCore + +export default function getHighlighter() { + if (highlighter === undefined) + highlighter = createHighlighterCoreSync({ + themes: [theme], + langs: [python], + engine: createJavaScriptRegexEngine(), + }) + + return highlighter +} diff --git a/templates/src/ui/logos/Flama.tsx b/templates/src/ui/logos/Flama.tsx new file mode 100644 index 00000000..aa4a0757 --- /dev/null +++ b/templates/src/ui/logos/Flama.tsx @@ -0,0 +1,10 @@ +import { FlamaIcon } from '../icons' + +export default function Flama() { + return ( +
    + + Flama +
    + ) +} diff --git a/templates/src/ui/logos/Vortico.tsx b/templates/src/ui/logos/Vortico.tsx new file mode 100644 index 00000000..d932593d --- /dev/null +++ b/templates/src/ui/logos/Vortico.tsx @@ -0,0 +1,10 @@ +import { VorticoIcon } from '../icons' + +export default function Vortico() { + return ( +
    + + Vortico +
    + ) +} diff --git a/templates/src/ui/logos/index.ts b/templates/src/ui/logos/index.ts new file mode 100644 index 00000000..ca25af61 --- /dev/null +++ b/templates/src/ui/logos/index.ts @@ -0,0 +1,2 @@ +export { default as FlamaLogo } from './Flama' +export { default as VorticoLogo } from './Vortico' diff --git a/templates/tailwind.config.js b/templates/tailwind.config.js deleted file mode 100644 index ad4f0797..00000000 --- a/templates/tailwind.config.js +++ /dev/null @@ -1,119 +0,0 @@ -import defaultTheme from 'tailwindcss/defaultTheme' - -const colors = { - vortico: { - DEFAULT: '#008080', - 50: '#00DCDC', - 100: '#00D2D2', - 200: '#00BDBD', - 300: '#00A9A9', - 400: '#009494', - 500: '#008080', - 600: '#007171', - 700: '#006161', - 800: '#005252', - 900: '#004343', - 950: '#003B3B', - }, - bruma: { - DEFAULT: '#00bbd5', - 50: '#ebfeff', - 100: '#cefcff', - 200: '#a2f7ff', - 300: '#63effd', - 400: '#1cdcf4', - 500: '#00bbd5', - 600: '#0398b7', - 700: '#0a7994', - 800: '#126178', - 900: '#145165', - 950: '#063646', - }, - bosque: { - DEFAULT: '#9e744f', - 50: '#f7f4ef', - 100: '#ebe3d6', - 200: '#d9c8af', - 300: '#c2a682', - 400: '#b0895f', - 500: '#9e744f', - 600: '#8a5f44', - 700: '#6f4939', - 800: '#5f3f34', - 900: '#523731', - 950: '#2f1d19', - }, - ciclon: { - DEFAULT: '#00976e', - 50: '#ebfef6', - 100: '#d0fbe7', - 200: '#a4f6d3', - 300: '#6aebbd', - 400: '#2fd8a1', - 500: '#0abf8a', - 600: '#00976e', - 700: '#007c5e', - 800: '#03624b', - 900: '#04503f', - 950: '#012d25', - }, - flama: { - DEFAULT: '#E25822', - 50: '#fdf5ef', - 100: '#fbe8d9', - 200: '#f6cdb2', - 300: '#f0ac81', - 400: '#e9804e', - 500: '#e25822', - 600: '#d54821', - 700: '#b1351d', - 800: '#8d2d1f', - 900: '#72271c', - 950: '#3d110d', - }, - background: { - DEFAULT: '#656775', - 50: '#f5f5f6', - 100: '#e5e6e8', - 200: '#cdced4', - 300: '#aaabb6', - 400: '#808290', - 500: '#656775', - 600: '#575863', - 700: '#4a4a54', - 800: '#3f3f46', - 900: '#3a3a3f', - 950: '#242428', - }, -} - -/** @type {import('tailwindcss').Config} */ -const config = { - darkMode: 'class', - mode: 'jit', - content: ['./src/**/*.{js,ts,jsx,tsx,html,ejs}'], - theme: { - extend: { - colors: { - brand: colors.vortico, - primary: colors.background, - flama: colors.flama, - ciclon: colors.ciclon, - bosque: colors.bosque, - bruma: colors.bruma, - vortico: colors.vortico, - }, - maxWidth: { - '8xl': '90rem', - '9xl': '120rem', - }, - }, - fontFamily: { - sans: ['Lato', ...defaultTheme.fontFamily.sans], - alternative: ['Montserrat', ...defaultTheme.fontFamily.sans], - mono: ['"Fira Mono"', ...defaultTheme.fontFamily.mono], - }, - }, -} - -export default config