2025-02-21
This commit is contained in:
parent
98131c3b78
commit
5d5918f0d7
69 changed files with 1481 additions and 305 deletions
14
.zed/settings.json
Normal file
14
.zed/settings.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"language_servers": ["!vtsls", "!deno", "!tailwindcss-language-server", "!biome", "..."],
|
||||
"languages": {
|
||||
"Vue.js": {
|
||||
"code_actions_on_format": {
|
||||
"source.fixAll.eslint": true,
|
||||
"source.organizeImports": true
|
||||
},
|
||||
"formatter": "language_server",
|
||||
"prettier": null,
|
||||
"format_on_save": "on"
|
||||
}
|
||||
}
|
||||
}
|
||||
233
bun.lock
233
bun.lock
|
|
@ -4,43 +4,50 @@
|
|||
"": {
|
||||
"name": "journal-media",
|
||||
"dependencies": {
|
||||
"@effect/platform": "^0.77.2",
|
||||
"@effect/sql-drizzle": "^0.29.2",
|
||||
"a11y-dialog": "^8.1.1",
|
||||
"drizzle-orm": "^0.39.3",
|
||||
"effect": "^3.13.2",
|
||||
"pinia": "^3.0.1",
|
||||
"sqlocal": "^0.14.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0",
|
||||
"@effect/platform": "latest",
|
||||
"@effect/sql-drizzle": "latest",
|
||||
"@unhead/vue": "latest",
|
||||
"@vueuse/core": "latest",
|
||||
"@vueuse/router": "latest",
|
||||
"a11y-dialog": "latest",
|
||||
"drizzle-orm": "latest",
|
||||
"effect": "latest",
|
||||
"pinia": "latest",
|
||||
"sqlocal": "latest",
|
||||
"unhead": "latest",
|
||||
"vue": "latest",
|
||||
"vue-router": "latest",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.2.2",
|
||||
"@types/node": "^22.13.4",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vue/eslint-config-prettier": "^10.2.0",
|
||||
"@vue/eslint-config-typescript": "^14.4.0",
|
||||
"browserlist": "^1.0.1",
|
||||
"browserslist": "^4.24.4",
|
||||
"drizzle-kit": "^0.30.4",
|
||||
"eslint": "^9.20.1",
|
||||
"eslint-plugin-perfectionist": "^4.9.0",
|
||||
"eslint-plugin-vue": "^9.32.0",
|
||||
"globals": "^15.15.0",
|
||||
"jiti": "^2.4.2",
|
||||
"lightningcss": "^1.29.1",
|
||||
"prettier": "^3.5.1",
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^6.1.1",
|
||||
"vite-plugin-vue-devtools": "^7.7.2",
|
||||
"vue-tsc": "^2.2.2",
|
||||
"@types/bun": "latest",
|
||||
"@unhead/addons": "latest",
|
||||
"@vitejs/plugin-vue": "latest",
|
||||
"@vue/eslint-config-typescript": "latest",
|
||||
"@vue/typescript-plugin": "latest",
|
||||
"browserslist": "latest",
|
||||
"drizzle-kit": "latest",
|
||||
"eslint": "latest",
|
||||
"eslint-plugin-perfectionist": "latest",
|
||||
"eslint-plugin-vue": "latest",
|
||||
"globals": "latest",
|
||||
"jiti": "latest",
|
||||
"knip": "latest",
|
||||
"lightningcss": "latest",
|
||||
"prettier": "latest",
|
||||
"prettier-plugin-pkg": "latest",
|
||||
"prettier-plugin-sh": "latest",
|
||||
"tsr": "latest",
|
||||
"typescript": "latest",
|
||||
"vite": "latest",
|
||||
"vite-plugin-vue-devtools": "latest",
|
||||
"vue-tsc": "latest",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||
|
||||
"@antfu/utils": ["@antfu/utils@0.7.10", "", {}, "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww=="],
|
||||
"@antfu/utils": ["@antfu/utils@8.1.1", "", {}, "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ=="],
|
||||
|
||||
"@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="],
|
||||
|
||||
|
|
@ -170,15 +177,15 @@
|
|||
|
||||
"@eslint/config-array": ["@eslint/config-array@0.19.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w=="],
|
||||
|
||||
"@eslint/core": ["@eslint/core@0.11.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA=="],
|
||||
"@eslint/core": ["@eslint/core@0.12.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg=="],
|
||||
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.2.0", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w=="],
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.0", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ=="],
|
||||
|
||||
"@eslint/js": ["@eslint/js@9.20.0", "", {}, "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ=="],
|
||||
"@eslint/js": ["@eslint/js@9.21.0", "", {}, "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw=="],
|
||||
|
||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
||||
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.6", "", { "dependencies": { "@eslint/core": "^0.11.0", "levn": "^0.4.1" } }, "sha512-+0TjwR1eAUdZtvv/ir1mGX+v0tUoR3VEPB8Up0LLJC+whRW0GgBBtpbOkg/a/U4Dxa6l5a3l9AJ1aWIQVyoWJA=="],
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.7", "", { "dependencies": { "@eslint/core": "^0.12.0", "levn": "^0.4.1" } }, "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g=="],
|
||||
|
||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||
|
||||
|
|
@ -186,7 +193,7 @@
|
|||
|
||||
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
||||
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.1", "", {}, "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA=="],
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="],
|
||||
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
||||
|
||||
|
|
@ -210,16 +217,14 @@
|
|||
|
||||
"@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ=="],
|
||||
|
||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@4.0.1", "", { "dependencies": { "@nodelib/fs.stat": "4.0.0", "run-parallel": "^1.2.0" } }, "sha512-vAkI715yhnmiPupY+dq+xenu5Tdf2TBQ66jLvBIcCddtz+5Q8LbMKaf9CIJJreez8fQ8fgaY+RaywQx8RJIWpw=="],
|
||||
|
||||
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
||||
|
||||
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
||||
"@nodelib/fs.walk": ["@nodelib/fs.walk@3.0.1", "", { "dependencies": { "@nodelib/fs.scandir": "4.0.1", "fastq": "^1.15.0" } }, "sha512-nIh/M6Kh3ZtOmlY00DaUYB4xeeV6F3/ts1l29iwl3/cfyY/OuCfUx+v08zgx8TKPTifXRcjjqVQ4KB2zOYSbyw=="],
|
||||
|
||||
"@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.30.0", "", {}, "sha512-4VlGgo32k2EQ2wcCY3vEU28A0O13aOtHz3Xt2/2U5FAh9EfhD6t6DqL5Z6yAnRCntbTFDU4YfbpyzSlHNWycPw=="],
|
||||
|
||||
"@pkgr/core": ["@pkgr/core@0.1.1", "", {}, "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA=="],
|
||||
|
||||
"@polka/url": ["@polka/url@1.0.0-next.28", "", {}, "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw=="],
|
||||
|
||||
"@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="],
|
||||
|
|
@ -266,6 +271,8 @@
|
|||
|
||||
"@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="],
|
||||
|
||||
"@snyk/github-codeowners": ["@snyk/github-codeowners@1.1.0", "", { "dependencies": { "commander": "^4.1.1", "ignore": "^5.1.8", "p-map": "^4.0.0" }, "bin": { "github-codeowners": "dist/cli.js" } }, "sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw=="],
|
||||
|
||||
"@sqlite.org/sqlite-wasm": ["@sqlite.org/sqlite-wasm@3.48.0-build4", "", { "bin": { "sqlite-wasm": "bin/index.js" } }, "sha512-hI6twvUkzOmyGZhQMza1gpfqErZxXRw6JEsiVjUbo7tFanVD+8Oil0Ih3l2nGzHdxPI41zFmfUQG7GHqhciKZQ=="],
|
||||
|
||||
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
||||
|
|
@ -278,6 +285,8 @@
|
|||
|
||||
"@types/node": ["@types/node@22.13.4", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg=="],
|
||||
|
||||
"@types/web-bluetooth": ["@types/web-bluetooth@0.0.20", "", {}, "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="],
|
||||
|
||||
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.24.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.24.1", "@typescript-eslint/type-utils": "8.24.1", "@typescript-eslint/utils": "8.24.1", "@typescript-eslint/visitor-keys": "8.24.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-ll1StnKtBigWIGqvYDVuDmXJHVH4zLVot1yQ4fJtLpL7qacwkxJc1T0bptqw+miBQ/QfUbhl1TcQ4accW5KUyA=="],
|
||||
|
|
@ -300,6 +309,10 @@
|
|||
|
||||
"@ungap/with-resolvers": ["@ungap/with-resolvers@0.1.0", "", {}, "sha512-g7f0IkJdPW2xhY7H4iE72DAsIyfuwEFc6JWc2tYFwKDMWWAF699vGjrM348cwQuOXgHpe1gWFe+Eiyjx/ewvvw=="],
|
||||
|
||||
"@unhead/addons": ["@unhead/addons@2.0.0-alpha.19", "", { "dependencies": { "@rollup/pluginutils": "^5.1.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17", "mlly": "^1.7.4", "ufo": "^1.5.4", "unplugin": "^2.2.0", "unplugin-ast": "^0.14.0" }, "peerDependencies": { "unhead": "2.0.0-alpha.19" } }, "sha512-nzTC9/J6SJ425YSFZoC2Hf1w3JbmGO3zvT4CsY9/RF0ByihxsIH63v84nVN/K0hAm1CeOVho53yWH1lTgcNksQ=="],
|
||||
|
||||
"@unhead/vue": ["@unhead/vue@2.0.0-alpha.19", "", { "dependencies": { "hookable": "^5.5.3", "unhead": "2.0.0-alpha.19" }, "peerDependencies": { "vue": ">=3.5.13" } }, "sha512-PEjFg2oYXKZOGnR75ANReudH+/OdRlQkE8jwf9KBFLXiuu94tdqyph3gcgUs0pHsZmgVYpwxvdkOg+lldBUpjA=="],
|
||||
|
||||
"@vitejs/plugin-vue": ["@vitejs/plugin-vue@5.2.1", "", { "peerDependencies": { "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ=="],
|
||||
|
||||
"@volar/language-core": ["@volar/language-core@2.4.11", "", { "dependencies": { "@volar/source-map": "2.4.11" } }, "sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg=="],
|
||||
|
|
@ -332,8 +345,6 @@
|
|||
|
||||
"@vue/devtools-shared": ["@vue/devtools-shared@7.7.2", "", { "dependencies": { "rfdc": "^1.4.1" } }, "sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA=="],
|
||||
|
||||
"@vue/eslint-config-prettier": ["@vue/eslint-config-prettier@10.2.0", "", { "dependencies": { "eslint-config-prettier": "^10.0.1", "eslint-plugin-prettier": "^5.2.2" }, "peerDependencies": { "eslint": ">= 8.21.0", "prettier": ">= 3.0.0" } }, "sha512-GL3YBLwv/+b86yHcNNfPJxOTtVFJ4Mbc9UU3zR+KVoG7SwGTjPT+32fXamscNumElhcpXW3mT0DgzS9w32S7Bw=="],
|
||||
|
||||
"@vue/eslint-config-typescript": ["@vue/eslint-config-typescript@14.4.0", "", { "dependencies": { "@typescript-eslint/utils": "^8.23.0", "fast-glob": "^3.3.3", "typescript-eslint": "^8.23.0", "vue-eslint-parser": "^9.4.3" }, "peerDependencies": { "eslint": "^9.10.0", "eslint-plugin-vue": "^9.28.0", "typescript": ">=4.8.4" }, "optionalPeers": ["typescript"] }, "sha512-daU+eAekEeVz3CReE4PRW25fe+OJDKwE28jHN6LimDEnuFMbJ6H4WGogEpNof276wVP6UvzOeJQfLFjB5mW29A=="],
|
||||
|
||||
"@vue/language-core": ["@vue/language-core@2.2.2", "", { "dependencies": { "@volar/language-core": "~2.4.11", "@vue/compiler-dom": "^3.5.0", "@vue/compiler-vue2": "^2.7.16", "@vue/shared": "^3.5.0", "alien-signals": "^1.0.3", "minimatch": "^9.0.3", "muggle-string": "^0.4.1", "path-browserify": "^1.0.1" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-QotO41kurE5PLf3vrNgGTk3QswO2PdUFjBwNiOi7zMmGhwb25PSTh9hD1MCgKC06AVv+8sZQvlL3Do4TTVHSiQ=="],
|
||||
|
|
@ -348,20 +359,36 @@
|
|||
|
||||
"@vue/shared": ["@vue/shared@3.5.13", "", {}, "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ=="],
|
||||
|
||||
"@vue/typescript-plugin": ["@vue/typescript-plugin@2.2.2", "", { "dependencies": { "@volar/typescript": "~2.4.11", "@vue/language-core": "2.2.2", "@vue/shared": "^3.5.0" } }, "sha512-M/fNR/M4Rt+jm7Vmv21sPoHNM7MLYC7QjW5gqmP9y6HGmIlxOubqXYIqddeEnikmEsOc3linykEAxAIVxfIvbA=="],
|
||||
|
||||
"@vueuse/core": ["@vueuse/core@12.7.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "12.7.0", "@vueuse/shared": "12.7.0", "vue": "^3.5.13" } }, "sha512-jtK5B7YjZXmkGNHjviyGO4s3ZtEhbzSgrbX+s5o+Lr8i2nYqNyHuPVOeTdM1/hZ5Tkxg/KktAuAVDDiHMraMVA=="],
|
||||
|
||||
"@vueuse/metadata": ["@vueuse/metadata@12.7.0", "", {}, "sha512-4VvTH9mrjXqFN5LYa5YfqHVRI6j7R00Vy4995Rw7PQxyCL3z0Lli86iN4UemWqixxEvYfRjG+hF9wL8oLOn+3g=="],
|
||||
|
||||
"@vueuse/router": ["@vueuse/router@12.7.0", "", { "dependencies": { "@vueuse/shared": "12.7.0", "vue": "^3.5.13" }, "peerDependencies": { "vue-router": ">=4.0.0-rc.1" } }, "sha512-Jp6dIel54oc2nh++zqjY06ipCcTT6YWDCNQ8dSSnqRwx90wIl7w7MQP7Wpp1wrDwXEoqhelfeZf2gjfrkAhq3g=="],
|
||||
|
||||
"@vueuse/shared": ["@vueuse/shared@12.7.0", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-coLlUw2HHKsm7rPN6WqHJQr18WymN4wkA/3ThFaJ4v4gWGWAQQGK+MJxLuJTBs4mojQiazlVWAKNJNpUWGRkNw=="],
|
||||
|
||||
"a11y-dialog": ["a11y-dialog@8.1.1", "", { "dependencies": { "focusable-selectors": "^0.8.0" } }, "sha512-7SBLXFwhQBnEHOaIiKUUQZ5VKJa/b1jBDvPJvlejlqX2w9cpi+iHBrdjcmd4Xd6vIdsuMHGo9Is2SWu0Hzu0zg=="],
|
||||
|
||||
"acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
|
||||
|
||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||
|
||||
"aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="],
|
||||
|
||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
||||
|
||||
"alien-signals": ["alien-signals@1.0.3", "", {}, "sha512-zQOh3wAYK5ujENxvBBR3CFGF/b6afaSzZ/c9yNhJ1ENrGHETvpUuKQsa93Qrclp0+PzTF93MaZ7scVp1uUozhA=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
|
||||
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"ast-kit": ["ast-kit@1.4.0", "", { "dependencies": { "@babel/parser": "^7.26.5", "pathe": "^2.0.2" } }, "sha512-BlGeOw73FDsX7z0eZE/wuuafxYoek2yzNJ6l6A1nsb4+z/p87TOPbHaWuN53kFKNuUXiCQa2M+xLF71IqQmRSw=="],
|
||||
|
||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"birpc": ["birpc@0.2.19", "", {}, "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ=="],
|
||||
|
|
@ -372,8 +399,6 @@
|
|||
|
||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||
|
||||
"browserlist": ["browserlist@1.0.1", "", { "dependencies": { "chalk": "^2.4.1" }, "bin": { "browserlist": "./cli.js" } }, "sha512-nYq9jiWv+qXcgrJxQzivfEc7Wo2GvAKkeRViE5L3cUJpq4SZO6NZR710I/8T+OjE5BPECbzpm8rpUkwslE3nTg=="],
|
||||
|
||||
"browserslist": ["browserslist@4.24.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" } }, "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A=="],
|
||||
|
||||
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
|
||||
|
|
@ -386,16 +411,24 @@
|
|||
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001700", "", {}, "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ=="],
|
||||
|
||||
"chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
|
||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="],
|
||||
|
||||
"clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="],
|
||||
|
||||
"coincident": ["coincident@1.2.3", "", { "dependencies": { "@ungap/structured-clone": "^1.2.0", "@ungap/with-resolvers": "^0.1.0", "gc-hook": "^0.3.1", "proxy-target": "^3.0.2" }, "optionalDependencies": { "ws": "^8.16.0" } }, "sha512-Uxz3BMTWIslzeWjuQnizGWVg0j6khbvHUQ8+5BdM7WuJEm4ALXwq3wluYoB+uF68uPBz/oUOeJnYURKyfjexlA=="],
|
||||
|
||||
"color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
|
||||
|
||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||
|
||||
"confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
|
||||
|
||||
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||
|
||||
"copy-anything": ["copy-anything@3.0.5", "", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w=="],
|
||||
|
|
@ -416,6 +449,8 @@
|
|||
|
||||
"default-browser-id": ["default-browser-id@5.0.0", "", {}, "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA=="],
|
||||
|
||||
"defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="],
|
||||
|
||||
"define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="],
|
||||
|
||||
"detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
||||
|
|
@ -424,10 +459,14 @@
|
|||
|
||||
"drizzle-orm": ["drizzle-orm@0.39.3", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-EZ8ZpYvDIvKU9C56JYLOmUskazhad+uXZCTCRN4OnRMsL+xAJ05dv1eCpAG5xzhsm1hqiuC5kAZUCS924u2DTw=="],
|
||||
|
||||
"easy-table": ["easy-table@1.2.0", "", { "dependencies": { "ansi-regex": "^5.0.1" }, "optionalDependencies": { "wcwidth": "^1.0.1" } }, "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww=="],
|
||||
|
||||
"effect": ["effect@3.13.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-/w+CPqHDJ33Wq7xC4YKAchrEEPtjvxh563xH9kDTZp99seNYBoBs87vl8DJwartEjj+KLQLP8PzoDne+XmGT2A=="],
|
||||
|
||||
"electron-to-chromium": ["electron-to-chromium@1.5.102", "", {}, "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q=="],
|
||||
|
||||
"enhanced-resolve": ["enhanced-resolve@5.18.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg=="],
|
||||
|
||||
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"error-stack-parser-es": ["error-stack-parser-es@0.1.5", "", {}, "sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg=="],
|
||||
|
|
@ -440,14 +479,10 @@
|
|||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"eslint": ["eslint@9.20.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.11.0", "@eslint/eslintrc": "^3.2.0", "@eslint/js": "9.20.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g=="],
|
||||
|
||||
"eslint-config-prettier": ["eslint-config-prettier@10.0.1", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "build/bin/cli.js" } }, "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw=="],
|
||||
"eslint": ["eslint@9.21.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.0", "@eslint/js": "9.21.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg=="],
|
||||
|
||||
"eslint-plugin-perfectionist": ["eslint-plugin-perfectionist@4.9.0", "", { "dependencies": { "@typescript-eslint/types": "^8.24.0", "@typescript-eslint/utils": "^8.24.0", "natural-orderby": "^5.0.0" }, "peerDependencies": { "eslint": ">=8.0.0" } }, "sha512-76lDfJnonOcXGW3bEXuqhEGId0LrOlvIE1yLHvK/eKMMPOc0b43KchAIR2Bdbqlg+LPXU5/Q+UzuzkO+cWHT6w=="],
|
||||
|
||||
"eslint-plugin-prettier": ["eslint-plugin-prettier@5.2.3", "", { "dependencies": { "prettier-linter-helpers": "^1.0.0", "synckit": "^0.9.1" }, "peerDependencies": { "@types/eslint": ">=8.0.0", "eslint": ">=8.0.0", "eslint-config-prettier": "*", "prettier": ">=3.0.0" }, "optionalPeers": ["@types/eslint", "eslint-config-prettier"] }, "sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw=="],
|
||||
|
||||
"eslint-plugin-vue": ["eslint-plugin-vue@9.32.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "globals": "^13.24.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", "postcss-selector-parser": "^6.0.15", "semver": "^7.6.3", "vue-eslint-parser": "^9.4.3", "xml-name-validator": "^4.0.0" }, "peerDependencies": { "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, "sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug=="],
|
||||
|
||||
"eslint-scope": ["eslint-scope@8.2.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A=="],
|
||||
|
|
@ -462,7 +497,7 @@
|
|||
|
||||
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
||||
|
||||
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||
"estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
||||
|
||||
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
|
||||
|
||||
|
|
@ -472,8 +507,6 @@
|
|||
|
||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||
|
||||
"fast-diff": ["fast-diff@1.3.0", "", {}, "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw=="],
|
||||
|
||||
"fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
|
||||
|
||||
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
|
||||
|
|
@ -512,13 +545,13 @@
|
|||
|
||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
|
||||
"globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="],
|
||||
"globals": ["globals@16.0.0", "", {}, "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A=="],
|
||||
|
||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||
|
||||
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
|
||||
|
||||
"has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
|
||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="],
|
||||
|
||||
|
|
@ -534,6 +567,8 @@
|
|||
|
||||
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
||||
|
||||
"indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="],
|
||||
|
||||
"is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="],
|
||||
|
||||
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
||||
|
|
@ -576,6 +611,8 @@
|
|||
|
||||
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
||||
|
||||
"knip": ["knip@5.44.4", "", { "dependencies": { "@nodelib/fs.walk": "3.0.1", "@snyk/github-codeowners": "1.1.0", "easy-table": "1.2.0", "enhanced-resolve": "^5.18.0", "fast-glob": "^3.3.3", "jiti": "^2.4.2", "js-yaml": "^4.1.0", "minimist": "^1.2.8", "picocolors": "^1.1.0", "picomatch": "^4.0.1", "pretty-ms": "^9.0.0", "smol-toml": "^1.3.1", "strip-json-comments": "5.0.1", "summary": "2.1.0", "zod": "^3.22.4", "zod-validation-error": "^3.0.3" }, "peerDependencies": { "@types/node": ">=18", "typescript": ">=5.0.4" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-Ryn8LwWHLId8jSK1DgtT0hmg5DbzkqAtH+Gg3vZJpmSMgGHMspej9Ag+qKTm8wsPLDjVetuEz/lIsobo0XCMvQ=="],
|
||||
|
||||
"kolorist": ["kolorist@1.8.0", "", {}, "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ=="],
|
||||
|
||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||
|
|
@ -612,14 +649,22 @@
|
|||
|
||||
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||
|
||||
"magic-string-ast": ["magic-string-ast@0.7.0", "", { "dependencies": { "magic-string": "^0.30.17" } }, "sha512-686fgAHaJY7wLTFEq7nnKqeQrhqmXB19d1HnqT35Ci7BN6hbAYLZUezTQ062uUHM7ggZEQlqJ94Ftls+KDXU8Q=="],
|
||||
|
||||
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
||||
|
||||
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
||||
|
||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||
|
||||
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
||||
|
||||
"mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="],
|
||||
|
||||
"mlly": ["mlly@1.7.4", "", { "dependencies": { "acorn": "^8.14.0", "pathe": "^2.0.1", "pkg-types": "^1.3.0", "ufo": "^1.5.4" } }, "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw=="],
|
||||
|
||||
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
|
||||
|
||||
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
|
@ -632,6 +677,8 @@
|
|||
|
||||
"multipasta": ["multipasta@0.2.5", "", {}, "sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A=="],
|
||||
|
||||
"mvdan-sh": ["mvdan-sh@0.10.1", "", {}, "sha512-kMbrH0EObaKmK3nVRKUIIya1dpASHIEusM13S4V1ViHFuxuNxCo+arxoa6j/dbV22YBGjl7UKJm9QQKJ2Crzhg=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.8", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],
|
||||
|
||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||
|
|
@ -654,6 +701,8 @@
|
|||
|
||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||
|
||||
"p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="],
|
||||
|
||||
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
||||
|
||||
"parse-ms": ["parse-ms@4.0.0", "", {}, "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw=="],
|
||||
|
|
@ -670,10 +719,12 @@
|
|||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
"picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
|
||||
|
||||
"pinia": ["pinia@3.0.1", "", { "dependencies": { "@vue/devtools-api": "^7.7.2" }, "peerDependencies": { "typescript": ">=4.4.4", "vue": "^2.7.0 || ^3.5.11" }, "optionalPeers": ["typescript"] }, "sha512-WXglsDzztOTH6IfcJ99ltYZin2mY8XZCXujkYWVIJlBjqsP6ST7zw+Aarh63E1cDVYeyUcPCxPHzJpEOmzB6Wg=="],
|
||||
|
||||
"pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
|
||||
|
||||
"postcss": ["postcss@8.5.2", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA=="],
|
||||
|
||||
"postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
|
||||
|
|
@ -682,7 +733,9 @@
|
|||
|
||||
"prettier": ["prettier@3.5.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw=="],
|
||||
|
||||
"prettier-linter-helpers": ["prettier-linter-helpers@1.0.0", "", { "dependencies": { "fast-diff": "^1.1.2" } }, "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w=="],
|
||||
"prettier-plugin-pkg": ["prettier-plugin-pkg@0.18.1", "", { "peerDependencies": { "prettier": "^3.0.3" } }, "sha512-FuUxvsYZR/8rsLH8s/jbPQmgYvv0yxW8LoIHCy6+Q7p4FBjjdP3DNKx8fMTOsc0SlEB1skB4o1LcahRceIh87A=="],
|
||||
|
||||
"prettier-plugin-sh": ["prettier-plugin-sh@0.15.0", "", { "dependencies": { "mvdan-sh": "^0.10.1", "sh-syntax": "^0.4.2" }, "peerDependencies": { "prettier": "^3.0.3" } }, "sha512-U0PikJr/yr2bzzARl43qI0mApBj0C1xdAfA04AZa6LnvIKawXHhuy2fFo6LNA7weRzGlAiNbaEFfKMFo0nZr/A=="],
|
||||
|
||||
"pretty-ms": ["pretty-ms@9.2.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg=="],
|
||||
|
||||
|
|
@ -710,6 +763,8 @@
|
|||
|
||||
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
||||
|
||||
"sh-syntax": ["sh-syntax@0.4.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-/l2UZ5fhGZLVZa16XQM9/Vq/hezGGbdHeVEA01uWjOL1+7Ek/gt6FquW0iKKws4a9AYPYvlz6RyVvjh3JxOteg=="],
|
||||
|
||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
|
@ -718,6 +773,8 @@
|
|||
|
||||
"sirv": ["sirv@3.0.1", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A=="],
|
||||
|
||||
"smol-toml": ["smol-toml@1.3.1", "", {}, "sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ=="],
|
||||
|
||||
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
|
@ -730,15 +787,17 @@
|
|||
|
||||
"strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="],
|
||||
|
||||
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||
"strip-json-comments": ["strip-json-comments@5.0.1", "", {}, "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw=="],
|
||||
|
||||
"summary": ["summary@2.1.0", "", {}, "sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw=="],
|
||||
|
||||
"superjson": ["superjson@2.2.2", "", { "dependencies": { "copy-anything": "^3.0.2" } }, "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q=="],
|
||||
|
||||
"supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],
|
||||
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
|
||||
"svg-tags": ["svg-tags@1.0.0", "", {}, "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA=="],
|
||||
|
||||
"synckit": ["synckit@0.9.2", "", { "dependencies": { "@pkgr/core": "^0.1.0", "tslib": "^2.6.2" } }, "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw=="],
|
||||
"tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
|
||||
|
||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||
|
||||
|
|
@ -748,6 +807,8 @@
|
|||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"tsr": ["tsr@1.3.4", "", { "dependencies": { "mri": "^1.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "typescript": ">=4.0.0" }, "bin": { "tsr": "dist/cli.js" } }, "sha512-VHGK2GNokLaQ2OXdL4kE8+U9Dn6EWmDEZ/HdoFCnOoyR6ZFxi0QdzshPs7ZJ1xY9lfi+pQ0hZI5fLZAHZIJ+GA=="],
|
||||
|
||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||
|
||||
"type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="],
|
||||
|
|
@ -756,12 +817,22 @@
|
|||
|
||||
"typescript-eslint": ["typescript-eslint@8.24.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.24.1", "@typescript-eslint/parser": "8.24.1", "@typescript-eslint/utils": "8.24.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-cw3rEdzDqBs70TIcb0Gdzbt6h11BSs2pS0yaq7hDWDBtCCSei1pPSUXE9qUdQ/Wm9NgFg8mKtMt1b8fTHIl1jA=="],
|
||||
|
||||
"ufo": ["ufo@1.5.4", "", {}, "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ=="],
|
||||
|
||||
"undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
|
||||
|
||||
"unhead": ["unhead@2.0.0-alpha.19", "", { "dependencies": { "hookable": "^5.5.3" } }, "sha512-MbjBinF3G61+Ecy/eQt013SCdnIdUhu14JKyDf7fAzpV0d6snC6BdPY/O+NOk4MNWpxrD05Dc8/AJ/8Vpo66IQ=="],
|
||||
|
||||
"unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="],
|
||||
|
||||
"universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
|
||||
|
||||
"unplugin": ["unplugin@2.2.0", "", { "dependencies": { "acorn": "^8.14.0", "webpack-virtual-modules": "^0.6.2" } }, "sha512-m1ekpSwuOT5hxkJeZGRxO7gXbXT3gF26NjQ7GdVHoLoF8/nopLcd/QfPigpCy7i51oFHiRJg/CyHhj4vs2+KGw=="],
|
||||
|
||||
"unplugin-ast": ["unplugin-ast@0.14.0", "", { "dependencies": { "@antfu/utils": "^8.1.0", "@babel/generator": "^7.26.5", "ast-kit": "^1.4.0", "magic-string-ast": "^0.7.0", "unplugin": "^2.1.2", "unplugin-utils": "^0.2.0" } }, "sha512-a9MPyEyrecxmaMGS7xmwYVXcdZIAPaAr+ePmPR1duTh3Bk6/QxR70udb4dkvggZzy9AuzD/7b0RVCcA/N9HmzQ=="],
|
||||
|
||||
"unplugin-utils": ["unplugin-utils@0.2.4", "", { "dependencies": { "pathe": "^2.0.2", "picomatch": "^4.0.2" } }, "sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA=="],
|
||||
|
||||
"update-browserslist-db": ["update-browserslist-db@1.1.2", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg=="],
|
||||
|
||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||
|
|
@ -790,6 +861,10 @@
|
|||
|
||||
"vue-tsc": ["vue-tsc@2.2.2", "", { "dependencies": { "@volar/typescript": "~2.4.11", "@vue/language-core": "2.2.2" }, "peerDependencies": { "typescript": ">=5.0.0" }, "bin": { "vue-tsc": "./bin/vue-tsc.js" } }, "sha512-1icPKkxAA5KTAaSwg0wVWdE48EdsH8fgvcbAiqojP4jXKl6LEM3soiW1aG/zrWrFt8Mw1ncG2vG1PvpZpVfehA=="],
|
||||
|
||||
"wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="],
|
||||
|
||||
"webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="],
|
||||
|
||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||
|
|
@ -800,10 +875,16 @@
|
|||
|
||||
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||
|
||||
"yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
|
||||
|
||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||
|
||||
"yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="],
|
||||
|
||||
"zod": ["zod@3.24.2", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="],
|
||||
|
||||
"zod-validation-error": ["zod-validation-error@3.4.0", "", { "peerDependencies": { "zod": "^3.18.0" } }, "sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ=="],
|
||||
|
||||
"@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
||||
"@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
|
@ -818,30 +899,40 @@
|
|||
|
||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"@eslint/eslintrc/strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||
|
||||
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
||||
|
||||
"@rollup/pluginutils/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
|
||||
"@nodelib/fs.scandir/@nodelib/fs.stat": ["@nodelib/fs.stat@4.0.0", "", {}, "sha512-ctr6bByzksKRCV0bavi8WoQevU6plSp2IkllIsEqaiKe2mwNNnaluhnRhcsgGZHrrHk57B3lf95MkLMO3STYcg=="],
|
||||
|
||||
"@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
|
||||
"@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||
|
||||
"@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||
|
||||
"@vue/devtools-core/nanoid": ["nanoid@5.1.0", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-zDAl/llz8Ue/EblwSYwdxGBYfj46IM1dhjVi8dyp9LQffoIGxJEAHj2oeZ4uNcgycSRcQ83CnfcZqEJzVDLcDw=="],
|
||||
|
||||
"@vue/language-core/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
|
||||
"chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
|
||||
|
||||
"eslint/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"eslint-plugin-vue/globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="],
|
||||
|
||||
"fast-glob/@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
||||
|
||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
|
||||
"node-gyp-build-optional-packages/detect-libc": ["detect-libc@2.0.3", "", {}, "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw=="],
|
||||
|
||||
"npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
|
||||
|
||||
"vite/esbuild": ["esbuild@0.24.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.24.2", "@esbuild/android-arm": "0.24.2", "@esbuild/android-arm64": "0.24.2", "@esbuild/android-x64": "0.24.2", "@esbuild/darwin-arm64": "0.24.2", "@esbuild/darwin-x64": "0.24.2", "@esbuild/freebsd-arm64": "0.24.2", "@esbuild/freebsd-x64": "0.24.2", "@esbuild/linux-arm": "0.24.2", "@esbuild/linux-arm64": "0.24.2", "@esbuild/linux-ia32": "0.24.2", "@esbuild/linux-loong64": "0.24.2", "@esbuild/linux-mips64el": "0.24.2", "@esbuild/linux-ppc64": "0.24.2", "@esbuild/linux-riscv64": "0.24.2", "@esbuild/linux-s390x": "0.24.2", "@esbuild/linux-x64": "0.24.2", "@esbuild/netbsd-arm64": "0.24.2", "@esbuild/netbsd-x64": "0.24.2", "@esbuild/openbsd-arm64": "0.24.2", "@esbuild/openbsd-x64": "0.24.2", "@esbuild/sunos-x64": "0.24.2", "@esbuild/win32-arm64": "0.24.2", "@esbuild/win32-ia32": "0.24.2", "@esbuild/win32-x64": "0.24.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA=="],
|
||||
|
||||
"vite-plugin-inspect/@antfu/utils": ["@antfu/utils@0.7.10", "", {}, "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww=="],
|
||||
|
||||
"vue-eslint-parser/eslint-scope": ["eslint-scope@7.2.2", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg=="],
|
||||
|
||||
"vue-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||
|
|
@ -898,9 +989,7 @@
|
|||
|
||||
"@vue/language-core/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
||||
|
||||
"eslint/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"eslint/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
"fast-glob/@nodelib/fs.walk/@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||
|
||||
"vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="],
|
||||
|
||||
|
|
@ -947,11 +1036,5 @@
|
|||
"vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.24.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA=="],
|
||||
|
||||
"vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="],
|
||||
|
||||
"eslint/chalk/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"eslint/chalk/supports-color/has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"eslint/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
26
cfg/.prettierignore
Executable file
26
cfg/.prettierignore
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
# Tout ce qui est traité par dprint
|
||||
*.css
|
||||
*.html
|
||||
*.js
|
||||
*.json
|
||||
*.jsonc
|
||||
*.md
|
||||
*.mjs
|
||||
*.mts
|
||||
*.ts
|
||||
*.vue
|
||||
*.yaml
|
||||
*.yml
|
||||
!package.json
|
||||
|
||||
# Cache
|
||||
.cache
|
||||
|
||||
# Compilation
|
||||
dist
|
||||
|
||||
# Jujutsu
|
||||
.jj
|
||||
|
||||
# Zed
|
||||
.zed
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
"jsonTrailingCommaFiles": [".swcrc", "biome.jsonc", "settings.json", "tsconfig.json"],
|
||||
"lineWidth": 120,
|
||||
"newLineKind": "lf",
|
||||
"preferSingleLine": true,
|
||||
"preferSingleLine": false,
|
||||
"trailingCommas": "never",
|
||||
"useTabs": false
|
||||
},
|
||||
|
|
@ -6,19 +6,10 @@ import globals from "globals";
|
|||
export default defineConfigWithVueTs(
|
||||
{
|
||||
files: ["**/*.{js,mjs,ts,mts,vue}"],
|
||||
languageOptions: {
|
||||
ecmaVersion: "latest",
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.es2025,
|
||||
},
|
||||
},
|
||||
languageOptions: { ecmaVersion: "latest", globals: { ...globals.browser, ...globals.es2025 } },
|
||||
name: "app/files-to-lint",
|
||||
},
|
||||
{
|
||||
ignores: [".cache/", "dist/", "node_modules/"],
|
||||
name: "app/files-to-ignore",
|
||||
},
|
||||
{ ignores: [".cache/", "dist/", "node_modules/"], name: "app/files-to-ignore" },
|
||||
vueTsConfigs.strictTypeChecked,
|
||||
vueTsConfigs.stylisticTypeChecked,
|
||||
vue.configs["flat/recommended"],
|
||||
|
|
@ -29,9 +20,7 @@ export default defineConfigWithVueTs(
|
|||
"vue/array-bracket-spacing": "off",
|
||||
"vue/array-element-newline": "off",
|
||||
"vue/arrow-spacing": "off",
|
||||
"vue/attributes-order": ["error", {
|
||||
alphabetical: true,
|
||||
}],
|
||||
"vue/attributes-order": ["error", { alphabetical: true }],
|
||||
"vue/block-spacing": "off",
|
||||
"vue/block-tag-newline": "off",
|
||||
"vue/brace-style": "off",
|
||||
13
cfg/knip.config.ts
Normal file
13
cfg/knip.config.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import type { KnipConfig } from "knip";
|
||||
|
||||
const config: KnipConfig = {
|
||||
entry: [
|
||||
"vite.config.mts",
|
||||
"src/main.ts",
|
||||
"src/App.vue",
|
||||
"pages/**/*.vue",
|
||||
],
|
||||
project: ["src/**/*.{ts,vue}"],
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
@ -10,14 +10,7 @@ const config = {
|
|||
htmlWhitespaceSensitivity: "ignore",
|
||||
jsxSingleQuote: false,
|
||||
objectWrap: "collapse",
|
||||
overrides: [
|
||||
{
|
||||
files: ["package.json"],
|
||||
options: {
|
||||
plugins: ["prettier-plugin-pkg"],
|
||||
},
|
||||
},
|
||||
],
|
||||
overrides: [{ files: ["package.json"], options: { plugins: ["prettier-plugin-pkg"] } }],
|
||||
plugins: ["prettier-plugin-sh"],
|
||||
printWidth: 120,
|
||||
proseWrap: "never",
|
||||
18
cspell.json
18
cspell.json
|
|
@ -1 +1,17 @@
|
|||
{ "words": ["oxlint", "lightningcss", "sqlocal", "Tmdb", "AUTOINCREMENT"] }
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
|
||||
"version": "0.2",
|
||||
"dictionaries": [
|
||||
"fr-fr"
|
||||
],
|
||||
"words": [
|
||||
"oxlint",
|
||||
"lightningcss",
|
||||
"sqlocal",
|
||||
"Tmdb",
|
||||
"AUTOINCREMENT",
|
||||
"vtsls",
|
||||
"quartary",
|
||||
"fieldset"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
1
env.d.ts
vendored
1
env.d.ts
vendored
|
|
@ -1 +0,0 @@
|
|||
/// <reference types="vite/client" />
|
||||
17
index.html
17
index.html
|
|
@ -1,13 +1,22 @@
|
|||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vite App</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||
<title>Journal Média</title>
|
||||
<link rel="preload" href="/app-loading.css" as="style">
|
||||
<link ref="preload" href="/fonts/Banquise-Regular.otf" as="font">
|
||||
<link ref="preload" href="/fonts/BerkeleyMonoVariable-Regular" as="font">
|
||||
|
||||
<link rel="stylesheet" href="/app-loading.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<div id="app">
|
||||
<div id="app-loading">
|
||||
<p>loading</p>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
89
justfile
Executable file
89
justfile
Executable file
|
|
@ -0,0 +1,89 @@
|
|||
set shell := ["fish", "-c"]
|
||||
|
||||
# Variables de chemins de configuration.
|
||||
|
||||
drizzleConfigFile := "src/db/drizzle.config.ts"
|
||||
prettierConfigFile := "cfg/prettier.config.mjs"
|
||||
prettierIgnoreFile := "cfg/.prettierignore"
|
||||
esLintConfigFile := "cfg/eslint.config.mts"
|
||||
knipConfigFile := "cfg/knip.config.ts"
|
||||
|
||||
# Variables de cache.
|
||||
|
||||
cacheFolder := ".cache"
|
||||
prettierCacheFile := "prettiercache"
|
||||
stylelintCacheFile := "stylelintcache"
|
||||
|
||||
# Variables de dossiers.
|
||||
|
||||
stylesFolder := "src/styles/"
|
||||
|
||||
###
|
||||
|
||||
# Liste toutes les recettes.
|
||||
list:
|
||||
@just --list --list-heading 'Recettes disponibles :'\n'' --unsorted
|
||||
|
||||
# Lance le mode de développement.
|
||||
dev:
|
||||
bun --bun vite dev
|
||||
|
||||
# Compile le projet.
|
||||
build:
|
||||
-bun --bun vue-tsc --build .
|
||||
bun --bun vite build
|
||||
|
||||
# Lance la prévisualisation du mode de production.
|
||||
preview:
|
||||
just build
|
||||
bun --bun vite preview
|
||||
|
||||
# Met à jour les dépendances avec bun.
|
||||
update:
|
||||
bun update --latest
|
||||
|
||||
# Affiche les dépendances obsolètes avec bun.
|
||||
outdated:
|
||||
bun outdated --latest
|
||||
|
||||
# Génère un nouveau schéma de BDD.
|
||||
db-generate-schema:
|
||||
bun drizzle-kit --config {{ drizzleConfigFile }} generate
|
||||
|
||||
# Formate avec prettier puis dprint.
|
||||
format:
|
||||
bun --bun prettier \
|
||||
--cache --cache-location "{{ cacheFolder }}/{{ prettierCacheFile }}" \
|
||||
--config "{{ prettierConfigFile }}" \
|
||||
--ignore-path ".gitignore" --ignore-path "{{ prettierIgnoreFile }}" \
|
||||
--ignore-unknown \
|
||||
--write \
|
||||
.
|
||||
dprint --config "cfg/dprint.json" fmt
|
||||
|
||||
watch-format:
|
||||
watchexec dprint --config "cfg/dprint.json" fmt
|
||||
|
||||
# Vérifie le code CSS avec stylelint.
|
||||
lint-css:
|
||||
bun --bun stylelint \
|
||||
--cache --cache-location "{{ cacheFolder }}/{{ stylelintCacheFile }}" \
|
||||
--fix \
|
||||
{{ stylesFolder }}
|
||||
|
||||
# Analyse le code TypeScript et Astro.
|
||||
lint-js fix="":
|
||||
bun --bun eslint --config "{{ esLintConfigFile }}" {{ fix }}
|
||||
|
||||
# Analyse l'orthographe et la grammaire.
|
||||
lint-spelling:
|
||||
bun --bun cspell lint *
|
||||
|
||||
# Vérifie la présence de « code mort ».
|
||||
lint-dead-code:
|
||||
bun knip-bun --config "{{ knipConfigFile }}"
|
||||
|
||||
# Vérifie tous les fichiers.
|
||||
lint-all:
|
||||
just lint-css
|
||||
just lint-js
|
||||
25
package.json
25
package.json
|
|
@ -1,40 +1,49 @@
|
|||
{
|
||||
"name": "journal-media",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build",
|
||||
"lint:eslint": "eslint . --fix"
|
||||
"dev": "vite",
|
||||
"lint:eslint": "eslint . --fix",
|
||||
"preview": "vite preview",
|
||||
"type-check": "vue-tsc --build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@effect/platform": "^0.77.2",
|
||||
"@effect/sql-drizzle": "^0.29.2",
|
||||
"@unhead/vue": "^2.0.0-alpha.19",
|
||||
"@vueuse/core": "^12.7.0",
|
||||
"@vueuse/router": "^12.7.0",
|
||||
"a11y-dialog": "^8.1.1",
|
||||
"drizzle-orm": "^0.39.3",
|
||||
"effect": "^3.13.2",
|
||||
"pinia": "^3.0.1",
|
||||
"sqlocal": "^0.14.0",
|
||||
"unhead": "^2.0.0-alpha.19",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.2.2",
|
||||
"@types/node": "^22.13.4",
|
||||
"@unhead/addons": "^2.0.0-alpha.19",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"@vue/eslint-config-typescript": "^14.4.0",
|
||||
"@vue/typescript-plugin": "^2.2.2",
|
||||
"browserslist": "^4.24.4",
|
||||
"drizzle-kit": "^0.30.4",
|
||||
"eslint": "^9.20.1",
|
||||
"eslint": "^9.21.0",
|
||||
"eslint-plugin-perfectionist": "^4.9.0",
|
||||
"eslint-plugin-vue": "^9.32.0",
|
||||
"globals": "^15.15.0",
|
||||
"globals": "^16.0.0",
|
||||
"jiti": "^2.4.2",
|
||||
"knip": "^5.44.4",
|
||||
"lightningcss": "^1.29.1",
|
||||
"prettier": "^3.5.1",
|
||||
"prettier-plugin-pkg": "^0.18.1",
|
||||
"prettier-plugin-sh": "^0.15.0",
|
||||
"tsr": "^1.3.4",
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^6.1.1",
|
||||
"vite-plugin-vue-devtools": "^7.7.2",
|
||||
|
|
|
|||
40
public/app-loading.css
Normal file
40
public/app-loading.css
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
@import url("fonts.css");
|
||||
|
||||
#app-loading {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
text-align: center;
|
||||
align-content: center;
|
||||
z-index: 100;
|
||||
background: salmon;
|
||||
font-family: Banquise;
|
||||
font-size: 2rem;
|
||||
|
||||
p {
|
||||
width: 10ch;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
p::after {
|
||||
content: "";
|
||||
animation: 2s forwards infinite loading;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
from {
|
||||
content: "";
|
||||
}
|
||||
25% {
|
||||
content: ".";
|
||||
}
|
||||
50% {
|
||||
content: "..";
|
||||
}
|
||||
75% {
|
||||
content: "...";
|
||||
}
|
||||
to {
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
9
public/favicon/favicon.svg
Executable file
9
public/favicon/favicon.svg
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||
<style>
|
||||
path { fill: #000; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #FFF; }
|
||||
}
|
||||
</style>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 749 B |
25
public/fonts.css
Normal file
25
public/fonts.css
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
@font-face {
|
||||
font-family: BRKLY;
|
||||
font-weight: 100 150;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
src: url("/fonts/BerkeleyMonoVariable-Regular.ttf") format("truetype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: BRKLY;
|
||||
font-weight: 100 150;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
src: url("/fonts/BerkeleyMonoVariable-Italic.ttf") format("truetype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Banquise;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
src:
|
||||
url("/fonts/Banquise-Regular.woff") format("woff"),
|
||||
url("/fonts/Banquise-Regular.otf") format("opentype");
|
||||
}
|
||||
BIN
public/fonts/Banquise-Regular.otf
Normal file
BIN
public/fonts/Banquise-Regular.otf
Normal file
Binary file not shown.
BIN
public/fonts/Banquise-Regular.woff
Normal file
BIN
public/fonts/Banquise-Regular.woff
Normal file
Binary file not shown.
BIN
public/fonts/BerkeleyMonoVariable-Italic.ttf
Normal file
BIN
public/fonts/BerkeleyMonoVariable-Italic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/BerkeleyMonoVariable-Regular.ttf
Normal file
BIN
public/fonts/BerkeleyMonoVariable-Regular.ttf
Normal file
Binary file not shown.
28
src/App.vue
28
src/App.vue
|
|
@ -1,7 +1,33 @@
|
|||
<script setup lang="ts">
|
||||
import "@/styles/main.css";
|
||||
import { Transition } from "vue";
|
||||
import { RouterView } from "vue-router";
|
||||
import SidebarView from "@/views/SidebarView.vue";
|
||||
import MainHeader from "./components/MainHeader.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RouterView></RouterView>
|
||||
<div class="container center with-sidebar">
|
||||
<main class="box stack">
|
||||
<MainHeader></MainHeader>
|
||||
|
||||
<RouterView v-slot="{ Component, route }">
|
||||
<Transition name="fade" mode="out-in">
|
||||
<component :is="Component" :key="route.path" />
|
||||
</Transition>
|
||||
</RouterView>
|
||||
</main>
|
||||
|
||||
<SidebarView></SidebarView>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="css">
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
|
||||
.fade-enter-from, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
<template>
|
||||
<p>Error</p>
|
||||
</template>
|
||||
53
src/components/ImposterBox.vue
Normal file
53
src/components/ImposterBox.vue
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<script setup lang="ts">
|
||||
import A11yDialog from "a11y-dialog";
|
||||
import { useTemplateRef } from "vue";
|
||||
import { watchEffect } from "vue";
|
||||
import { ref } from "vue";
|
||||
import { computed } from "vue";
|
||||
import type { ComputedRef } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
dialogId: string;
|
||||
toggled: boolean;
|
||||
}>();
|
||||
defineEmits<{
|
||||
(e: "dialog-hidden", dialogId: string): void;
|
||||
}>();
|
||||
|
||||
const dialogTitleId: ComputedRef<string> = computed(() => `${props.dialogId}-title`);
|
||||
const dialogContainer = useTemplateRef<HTMLDivElement>("dialog");
|
||||
let dialog = ref<A11yDialog>();
|
||||
|
||||
const closeDialog = () => dialog.value?.hide();
|
||||
|
||||
watchEffect(() => {
|
||||
if (dialogContainer.value) {
|
||||
dialog.value = new A11yDialog(dialogContainer.value);
|
||||
}
|
||||
if (props.toggled) {
|
||||
dialog.value?.show();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
aria-hidden="true" :aria-labelledby="dialogTitleId" class="dialog"
|
||||
:id="dialogId" ref="dialog" @hide="$emit('dialog-hidden', dialogId)"
|
||||
>
|
||||
<div class="dialog-content box" role="document">
|
||||
<header class="invert">
|
||||
<h2 :id="dialogTitleId">
|
||||
<slot name="title"></slot>
|
||||
</h2>
|
||||
<button @click="closeDialog" class="integrated" type="button">X</button>
|
||||
</header>
|
||||
|
||||
<main class="box">
|
||||
<slot name="content"></slot>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped src="@/styles/components/imposter-box.css"></style>
|
||||
|
|
@ -1,19 +1,25 @@
|
|||
<script setup lang="ts">
|
||||
import { type DiaryEntry } from "@/db/schemas/entries";
|
||||
import { ReadApi } from "@/services/read-api";
|
||||
import { Console, Effect, pipe } from "effect";
|
||||
import { RuntimeClient } from "@/services/runtime-client";
|
||||
import { Effect } from "effect";
|
||||
|
||||
const lastAddedEntry = await pipe(
|
||||
Effect.andThen(ReadApi, (api: ReadApi) =>
|
||||
pipe(
|
||||
api.getLastAddedEntry(),
|
||||
Effect.tapError(Console.warn),
|
||||
const lastAddedEntry: DiaryEntry | null = await RuntimeClient.runPromise(
|
||||
Effect.gen(function*() {
|
||||
const readApi = yield* ReadApi;
|
||||
|
||||
return yield* readApi.getLastAddedEntry().pipe(
|
||||
Effect.tapErrorCause(cause => Effect.logError(cause.toJSON())),
|
||||
Effect.orElseSucceed(() => null),
|
||||
)),
|
||||
Effect.provide(ReadApi.Default),
|
||||
Effect.runPromise,
|
||||
);
|
||||
}),
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<p>hello</p>
|
||||
|
||||
<p v-if="lastAddedEntry">
|
||||
{{ lastAddedEntry?.id }}
|
||||
</p>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
<template>
|
||||
<p>loading...</p>
|
||||
</template>
|
||||
8
src/components/MainHeader.vue
Normal file
8
src/components/MainHeader.vue
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header>
|
||||
<h1>Journal Média</h1>
|
||||
</header>
|
||||
</template>
|
||||
16
src/components/NavigationMenu.vue
Normal file
16
src/components/NavigationMenu.vue
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<script setup lang="ts">
|
||||
import { RouterLink } from "vue-router";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<aside class="box sidebar">
|
||||
<nav id="primary-navigation">
|
||||
<ul>
|
||||
<li><RouterLink to="/">Accueil</RouterLink></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<style scoped src="@/styles/components/navigation-menu.css">
|
||||
</style>
|
||||
|
|
@ -1,20 +1,5 @@
|
|||
import type { Config } from "drizzle-kit";
|
||||
|
||||
import { loadEnv } from "vite";
|
||||
|
||||
const env = loadEnv("development", process.cwd(), "");
|
||||
const DATABASE_URL = env["DATABASE_URL"];
|
||||
|
||||
// L'URL de la BDD doit être valide.
|
||||
if (!DATABASE_URL || DATABASE_URL === "") {
|
||||
throw new Error("L'URL de la base de données doit être renseignée dans le fichier de variables d'environnement.");
|
||||
}
|
||||
|
||||
const DrizzleKitConfig: Config = {
|
||||
dbCredentials: { url: DATABASE_URL },
|
||||
dialect: "sqlite",
|
||||
out: "./src/db/drizzle",
|
||||
schema: "./src/db/schema.ts",
|
||||
};
|
||||
const DrizzleKitConfig: Config = { dialect: "sqlite", out: "./src/db/drizzle", schema: "./src/db/schemas.ts" };
|
||||
|
||||
export default DrizzleKitConfig;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ CREATE TABLE `art_works` (
|
|||
`medium_type_id` integer,
|
||||
`name` text NOT NULL,
|
||||
`release_date` text(10) NOT NULL,
|
||||
FOREIGN KEY (`medium_type_id`) REFERENCES `medium_types`(`id`) ON UPDATE no action ON DELETE no action
|
||||
FOREIGN KEY (`medium_type_id`) REFERENCES `media_types`(`id`) ON UPDATE no action ON DELETE no action
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE `diary_entries` (
|
||||
|
|
@ -40,14 +40,14 @@ CREATE TABLE `genres` (
|
|||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `genres_name_unique` ON `genres` (`name`);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `genres_slug_unique` ON `genres` (`slug`);--> statement-breakpoint
|
||||
CREATE TABLE `medium_types` (
|
||||
CREATE TABLE `media_types` (
|
||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`name` text NOT NULL,
|
||||
`slug` text NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `medium_types_name_unique` ON `medium_types` (`name`);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `medium_types_slug_unique` ON `medium_types` (`slug`);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `media_types_name_unique` ON `media_types` (`name`);--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX `media_types_slug_unique` ON `media_types` (`slug`);--> statement-breakpoint
|
||||
CREATE TABLE `users` (
|
||||
`email` text NOT NULL,
|
||||
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@
|
|||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"art_works_medium_type_id_medium_types_id_fk": {
|
||||
"name": "art_works_medium_type_id_medium_types_id_fk",
|
||||
"art_works_medium_type_id_media_types_id_fk": {
|
||||
"name": "art_works_medium_type_id_media_types_id_fk",
|
||||
"tableFrom": "art_works",
|
||||
"tableTo": "medium_types",
|
||||
"tableTo": "media_types",
|
||||
"columnsFrom": ["medium_type_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "no action",
|
||||
|
|
@ -192,16 +192,16 @@
|
|||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"medium_types": {
|
||||
"name": "medium_types",
|
||||
"media_types": {
|
||||
"name": "media_types",
|
||||
"columns": {
|
||||
"id": { "name": "id", "type": "integer", "primaryKey": true, "notNull": true, "autoincrement": true },
|
||||
"name": { "name": "name", "type": "text", "primaryKey": false, "notNull": true, "autoincrement": false },
|
||||
"slug": { "name": "slug", "type": "text", "primaryKey": false, "notNull": true, "autoincrement": false }
|
||||
},
|
||||
"indexes": {
|
||||
"medium_types_name_unique": { "name": "medium_types_name_unique", "columns": ["name"], "isUnique": true },
|
||||
"medium_types_slug_unique": { "name": "medium_types_slug_unique", "columns": ["slug"], "isUnique": true }
|
||||
"media_types_name_unique": { "name": "media_types_name_unique", "columns": ["name"], "isUnique": true },
|
||||
"media_types_slug_unique": { "name": "media_types_slug_unique", "columns": ["slug"], "isUnique": true }
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
import type { Values } from "@/libs/utils/types";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import type { AnySQLiteColumn } from "drizzle-orm/sqlite-core";
|
||||
|
||||
import * as t from "drizzle-orm/sqlite-core";
|
||||
import { sqliteTable as table } from "drizzle-orm/sqlite-core";
|
||||
|
||||
import type { DIARY_ENTRY_STATES, MEDIUM_TYPES } from "./constants";
|
||||
|
||||
/**
|
||||
* Configuration de la BDD SQLite de l'application.
|
||||
*
|
||||
* Assumer ici que toute colonne :
|
||||
* - non explicitement définie comme optionnelle est obligatoire ;
|
||||
* - non explicitement définie comme unique peut contenir plusieurs fois la même valeur ;
|
||||
*/
|
||||
|
||||
export const Users = table("users", {
|
||||
email: t.text("email").notNull().unique(),
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
name: t.text("name").notNull().unique(),
|
||||
});
|
||||
export type User = InferSelectModel<typeof Users>;
|
||||
|
||||
export const MediumTypes = table("medium_types", {
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
name: t.text("name").notNull().unique(),
|
||||
slug: t.text("slug").$type<Values<typeof MEDIUM_TYPES>>().notNull().unique(),
|
||||
});
|
||||
export type MediumType = InferSelectModel<typeof MediumTypes>;
|
||||
|
||||
export const ArtWorks = table("art_works", {
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
mediumTypeId: t.integer("medium_type_id").references((): AnySQLiteColumn => MediumTypes.id),
|
||||
name: t.text("name").notNull(),
|
||||
releaseDate: t.text("release_date", { length: 10 }).notNull(),
|
||||
});
|
||||
export type ArtWork = InferSelectModel<typeof ArtWorks>;
|
||||
|
||||
export const Genres = table("genres", {
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
name: t.text("name").notNull().unique(),
|
||||
slug: t.text("slug").notNull().unique(),
|
||||
});
|
||||
export type Genre = InferSelectModel<typeof Genres>;
|
||||
|
||||
export const DiaryEntries = table("diary_entries", {
|
||||
artWorkId: t.integer("art_work_id").references((): AnySQLiteColumn => ArtWorks.id),
|
||||
dateCreated: t.text("date_created", { length: 10 }).notNull(),
|
||||
dateModified: t.text("date_modified", { length: 10 }).notNull(),
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
stateId: t.integer("state_id").references((): AnySQLiteColumn => DiaryEntriesStates.id),
|
||||
userId: t.integer("user_id").references((): AnySQLiteColumn => Users.id),
|
||||
});
|
||||
export type DiaryEntry = InferSelectModel<typeof DiaryEntries>;
|
||||
|
||||
export const Viewings = table("viewings", {
|
||||
artWorkId: t.integer("art_work_id").references((): AnySQLiteColumn => ArtWorks.id),
|
||||
date: t.text("date", { length: 10 }).notNull(),
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
userId: t.integer("user_id").references((): AnySQLiteColumn => Users.id),
|
||||
});
|
||||
export type Viewing = InferSelectModel<typeof Viewings>;
|
||||
|
||||
export const DiaryEntriesGenres = table("diary_entries_genres", {
|
||||
artWorkId: t.integer("art_work_id").references((): AnySQLiteColumn => ArtWorks.id),
|
||||
genreId: t.integer("genre_id").references((): AnySQLiteColumn => Genres.id),
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
});
|
||||
export type DiaryEntryGenre = InferSelectModel<typeof DiaryEntriesGenres>;
|
||||
|
||||
export const DiaryEntriesStates = table("diary_entries_states", {
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
state: t.text("state").$type<Values<typeof DIARY_ENTRY_STATES>>().notNull().unique(),
|
||||
});
|
||||
export type DiaryEntryState = InferSelectModel<typeof DiaryEntriesStates>;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
export const MEDIUM_TYPES = {
|
||||
export const MEDIA_TYPES = {
|
||||
DOCUMENTARY: "documentary",
|
||||
FILM: "film",
|
||||
SERIES: "series",
|
||||
40
src/db/schemas/entries.ts
Normal file
40
src/db/schemas/entries.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import type { Values } from "@/libs/utils/types";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import type { AnySQLiteColumn } from "drizzle-orm/sqlite-core";
|
||||
|
||||
import * as t from "drizzle-orm/sqlite-core";
|
||||
import { sqliteTable as table } from "drizzle-orm/sqlite-core";
|
||||
|
||||
import type { DIARY_ENTRY_STATES } from "./constants";
|
||||
|
||||
import { ArtWorks, Genres } from "./works";
|
||||
|
||||
export const DiaryEntries = table("diary_entries", {
|
||||
artWorkId: t.integer("art_work_id").references((): AnySQLiteColumn => ArtWorks.id),
|
||||
dateCreated: t.text("date_created", { length: 10 }).notNull(),
|
||||
dateModified: t.text("date_modified", { length: 10 }).notNull(),
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
stateId: t.integer("state_id").references((): AnySQLiteColumn => DiaryEntriesStates.id).notNull(),
|
||||
});
|
||||
|
||||
export const DiaryEntriesGenres = table("diary_entries_genres", {
|
||||
artWorkId: t.integer("art_work_id").references((): AnySQLiteColumn => ArtWorks.id).notNull(),
|
||||
genreId: t.integer("genre_id").references((): AnySQLiteColumn => Genres.id),
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
});
|
||||
|
||||
export const DiaryEntriesStates = table("diary_entries_states", {
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
state: t.text("state").$type<Values<typeof DIARY_ENTRY_STATES>>().notNull().unique(),
|
||||
});
|
||||
|
||||
export const Viewings = table("viewings", {
|
||||
artWorkId: t.integer("art_work_id").references((): AnySQLiteColumn => ArtWorks.id).notNull(),
|
||||
date: t.text("date", { length: 10 }).notNull(),
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
});
|
||||
|
||||
export type DiaryEntry = InferSelectModel<typeof DiaryEntries>;
|
||||
export type DiaryEntryGenre = InferSelectModel<typeof DiaryEntriesGenres>;
|
||||
export type DiaryEntryState = InferSelectModel<typeof DiaryEntriesStates>;
|
||||
export type Viewing = InferSelectModel<typeof Viewings>;
|
||||
31
src/db/schemas/works.ts
Normal file
31
src/db/schemas/works.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import type { Values } from "@/libs/utils/types";
|
||||
import type { InferSelectModel } from "drizzle-orm";
|
||||
import type { AnySQLiteColumn } from "drizzle-orm/sqlite-core";
|
||||
|
||||
import * as t from "drizzle-orm/sqlite-core";
|
||||
import { sqliteTable as table } from "drizzle-orm/sqlite-core";
|
||||
|
||||
import type { MEDIA_TYPES } from "./constants";
|
||||
|
||||
export const MediaTypes = table("media_types", {
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
name: t.text("name").notNull().unique(),
|
||||
slug: t.text("slug").$type<Values<typeof MEDIA_TYPES>>().notNull().unique(),
|
||||
});
|
||||
|
||||
export const ArtWorks = table("art_works", {
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
mediumTypeId: t.integer("medium_type_id").references((): AnySQLiteColumn => MediaTypes.id).notNull(),
|
||||
name: t.text("name").notNull(),
|
||||
releaseDate: t.text("release_date", { length: 10 }).notNull(),
|
||||
});
|
||||
|
||||
export const Genres = table("genres", {
|
||||
id: t.integer("id").primaryKey({ autoIncrement: true }),
|
||||
name: t.text("name").notNull().unique(),
|
||||
slug: t.text("slug").notNull().unique(),
|
||||
});
|
||||
|
||||
export type ArtWork = InferSelectModel<typeof ArtWorks>;
|
||||
export type Genre = InferSelectModel<typeof Genres>;
|
||||
export type MediaType = InferSelectModel<typeof MediaTypes>;
|
||||
|
|
@ -15,28 +15,33 @@ export class TmdbMovieSearchQueryParams extends Schema.Class<TmdbMovieSearchQuer
|
|||
),
|
||||
primary_release_year: Schema.NonEmptyString.pipe(Schema.length(4), Schema.optional),
|
||||
query: Schema.NonEmptyString,
|
||||
region: Schema.NonEmptyString.pipe(Schema.propertySignature, Schema.withConstructorDefault(() => "fr")),
|
||||
region: Schema.NonEmptyString.pipe(
|
||||
Schema.propertySignature,
|
||||
Schema.withConstructorDefault(() => "fr"),
|
||||
),
|
||||
year: Schema.NonEmptyString.pipe(Schema.length(4), Schema.optional),
|
||||
}) {}
|
||||
|
||||
export class TmdbMovieSearchResponse extends Schema.Class<TmdbMovieSearchResponse>("TmdbMovieSearchResponse")({
|
||||
page: Schema.NonNegativeInt,
|
||||
results: Schema.Array(Schema.Struct({
|
||||
adult: Schema.Boolean,
|
||||
backdrop_path: Schema.Union(Schema.String, Schema.Null),
|
||||
genre_ids: Schema.Array(Schema.NonNegativeInt),
|
||||
id: Schema.NonNegativeInt,
|
||||
original_language: Schema.String,
|
||||
original_title: Schema.String,
|
||||
overview: Schema.String,
|
||||
popularity: Schema.Number,
|
||||
poster_path: Schema.Union(Schema.String, Schema.Null),
|
||||
release_date: Schema.NonEmptyString.pipe(Schema.length(10)),
|
||||
title: Schema.String,
|
||||
video: Schema.Boolean,
|
||||
vote_average: Schema.Number,
|
||||
vote_count: Schema.NonNegativeInt,
|
||||
})),
|
||||
results: Schema.Array(
|
||||
Schema.Struct({
|
||||
adult: Schema.Boolean,
|
||||
backdrop_path: Schema.Union(Schema.String, Schema.Null),
|
||||
genre_ids: Schema.Array(Schema.NonNegativeInt),
|
||||
id: Schema.NonNegativeInt,
|
||||
original_language: Schema.String,
|
||||
original_title: Schema.String,
|
||||
overview: Schema.String,
|
||||
popularity: Schema.Number,
|
||||
poster_path: Schema.Union(Schema.String, Schema.Null),
|
||||
release_date: Schema.NonEmptyString.pipe(Schema.length(10)),
|
||||
title: Schema.String,
|
||||
video: Schema.Boolean,
|
||||
vote_average: Schema.Number,
|
||||
vote_count: Schema.NonNegativeInt,
|
||||
}),
|
||||
),
|
||||
total_pages: Schema.NonNegativeInt,
|
||||
total_results: Schema.NonNegativeInt,
|
||||
}) {}
|
||||
|
|
|
|||
16
src/libs/types/events.ts
Normal file
16
src/libs/types/events.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/** Événement émis au clic d'un Élément demandant l'ouverture d'une modale particulière. */
|
||||
export class DialogWantedEvent extends Event {
|
||||
/** L'ID de la modale demandée. */
|
||||
dialogId: string;
|
||||
|
||||
constructor(dialogId: string) {
|
||||
super("dialog-wanted", { bubbles: true, composed: true });
|
||||
this.dialogId = dialogId;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface GlobalEventHandlersEventMap {
|
||||
"dialog-wanted": DialogWantedEvent;
|
||||
}
|
||||
}
|
||||
7
src/libs/utils/dates.ts
Normal file
7
src/libs/utils/dates.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export const getTodayDate = (): string =>
|
||||
new Date(Date.now()).toLocaleDateString("fr-FR", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
weekday: "long",
|
||||
year: "numeric",
|
||||
});
|
||||
69
src/pages/HomePage.vue
Normal file
69
src/pages/HomePage.vue
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<script setup lang="ts">
|
||||
import ImposterBox from "@/components/ImposterBox.vue";
|
||||
import type { Ref } from "vue";
|
||||
import { onMounted, ref } from "vue";
|
||||
|
||||
const toggleDialogStateRef = (stateRef: Ref<boolean, boolean>) => () => {
|
||||
stateRef.value = !stateRef.value;
|
||||
};
|
||||
|
||||
const isAddMediaToggled = ref(false);
|
||||
const toggleAddMediaDialog = toggleDialogStateRef(isAddMediaToggled);
|
||||
|
||||
onMounted(() => {
|
||||
console.debug("HomePage.vue -- Mounted");
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="cluster" id="buttons">
|
||||
<button @click="toggleAddMediaDialog" id="add-media-button" type="button">🬤 Ajouter un média</button>
|
||||
<button id="" type="button">🬗 Rechercher une entrée</button>
|
||||
</section>
|
||||
|
||||
<section class="stack" id="last-watched-media">
|
||||
<h2>Derniers médias regardés</h2>
|
||||
</section>
|
||||
|
||||
<ImposterBox @dialog-hidden="toggleAddMediaDialog" :toggled="isAddMediaToggled" dialog-id="add-media">
|
||||
<template v-slot:title>Ajouter un média</template>
|
||||
<template v-slot:content>
|
||||
<form class="stack">
|
||||
<fieldset class="cluster">
|
||||
<legend>Type du média</legend>
|
||||
<div class="field">
|
||||
<input
|
||||
id="film" checked name="media-type"
|
||||
type="radio" value="film"
|
||||
>
|
||||
<label for="film">Film</label>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<input
|
||||
id="series" name="media-type" type="radio"
|
||||
value="series"
|
||||
>
|
||||
<label for="series">Série</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="field stack">
|
||||
<label for="media-title">Titre</label> <input id="media-title" type="text">
|
||||
</div>
|
||||
<div class="field stack">
|
||||
<label for="media-release-year">Année de sortie</label> <input id="media-release-year" type="number">
|
||||
</div>
|
||||
|
||||
<div class="cluster buttons">
|
||||
<button class="invert" type="submit">
|
||||
Rechercher
|
||||
</button>
|
||||
<button type="reset">
|
||||
Réinitialiser
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
</ImposterBox>
|
||||
</template>
|
||||
13
src/pages/NotFoundPage.vue
Normal file
13
src/pages/NotFoundPage.vue
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted } from "vue";
|
||||
// DEBUG
|
||||
onMounted(() => {
|
||||
console.debug("NotFoundPage.vue -- Mounted");
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="stack" id="404">
|
||||
<h2>404</h2>
|
||||
</section>
|
||||
</template>
|
||||
|
|
@ -1,15 +1,40 @@
|
|||
import HomeView from "@/views/HomeView.vue";
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import HomePage from "@/pages/HomePage.vue";
|
||||
import { Option, pipe, Predicate } from "effect";
|
||||
import { createRouter, createWebHistory, type Router } from "vue-router";
|
||||
|
||||
const router = createRouter({
|
||||
const siteName = "Journal Média";
|
||||
const separator = "|";
|
||||
|
||||
const generatePageTitle = (siteName: string, separator: string, pageTitle: string): string =>
|
||||
[siteName, separator, pageTitle].join(" ");
|
||||
|
||||
const router: Router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
component: HomeView,
|
||||
name: "home",
|
||||
component: HomePage,
|
||||
meta: { title: "Accueil" },
|
||||
name: "Home",
|
||||
path: "/",
|
||||
},
|
||||
{
|
||||
component: () => import("@/pages/NotFoundPage.vue"),
|
||||
meta: { title: "404" },
|
||||
name: "NotFound",
|
||||
path: "/:pathMatch(.*)*",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
router.beforeEach((to, _): void => {
|
||||
console.debug("router - to", to);
|
||||
pipe(
|
||||
Option.liftPredicate(Predicate.isString)(to.meta["title"]),
|
||||
Option.getOrElse((): string => "???"),
|
||||
(pageName: string): void => {
|
||||
document.title = generatePageTitle(siteName, separator, pageName);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
|
|||
25
src/router/typed-routes.d.ts
vendored
Normal file
25
src/router/typed-routes.d.ts
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import type { RouteRecordInfo } from "vue-router";
|
||||
|
||||
export interface RouteNamedMap {
|
||||
Home: RouteRecordInfo<
|
||||
"Home",
|
||||
"/",
|
||||
Record<never, never>,
|
||||
Record<never, never>,
|
||||
{ title: string }
|
||||
>;
|
||||
NotFound: RouteRecordInfo<
|
||||
"NotFound",
|
||||
"/:pathMatch(.*)*",
|
||||
{ path: string },
|
||||
{ path: string },
|
||||
{ title: string }
|
||||
>;
|
||||
}
|
||||
|
||||
// Last, you will need to augment the Vue Router types with this map of routes
|
||||
declare module "vue-router" {
|
||||
interface TypesConfig {
|
||||
RouteNamedMap: RouteNamedMap;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
import { drizzle } from "drizzle-orm/sqlite-proxy";
|
||||
import { drizzle, type SqliteRemoteDatabase } from "drizzle-orm/sqlite-proxy";
|
||||
import { Data, Effect } from "effect";
|
||||
import { SQLocalDrizzle } from "sqlocal/drizzle";
|
||||
|
||||
class LocalSqliteError extends Data.TaggedError("LocalSqliteError")<{ cause: unknown }> {
|
||||
}
|
||||
class LocalSqliteError extends Data.TaggedError("LocalSqliteError")<{ cause: unknown }> {}
|
||||
|
||||
export class LocalSqlite extends Effect.Service<LocalSqlite>()("LocalSqlite", {
|
||||
effect: Effect.gen(function*() {
|
||||
|
|
@ -30,13 +29,13 @@ export class LocalSqlite extends Effect.Service<LocalSqlite>()("LocalSqlite", {
|
|||
}),
|
||||
});
|
||||
|
||||
const orm = drizzle(client.driver, client.batchDriver);
|
||||
const orm: SqliteRemoteDatabase = drizzle(client.driver, client.batchDriver);
|
||||
|
||||
const query = <R>(execute: (_: typeof orm) => Promise<R>) =>
|
||||
Effect.tryPromise({
|
||||
catch: (error: unknown) => new LocalSqliteError({ cause: error }),
|
||||
try: () => execute(orm),
|
||||
});
|
||||
Effect.tryPromise({ catch: (error: unknown) => new LocalSqliteError({ cause: error }), try: () => execute(orm) });
|
||||
|
||||
yield* Effect.logDebug("--- DB ---");
|
||||
yield* Effect.tryPromise(() => client.deleteDatabaseFile());
|
||||
|
||||
return { client, orm, query };
|
||||
}),
|
||||
|
|
|
|||
14
src/services/logger.ts
Normal file
14
src/services/logger.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import type { LogLevel } from "effect/LogLevel";
|
||||
|
||||
import { Config, ConfigProvider, Effect, Layer, Logger, pipe } from "effect";
|
||||
|
||||
const EnvConfigProvider = Layer.setConfigProvider(ConfigProvider.fromMap(new Map([["LOG_LEVEL", "DEBUG"]])));
|
||||
|
||||
const LogLevelLive = pipe(
|
||||
Config.logLevel("LOG_LEVEL"),
|
||||
Effect.andThen((level: LogLevel) => Logger.minimumLogLevel(level)),
|
||||
Layer.unwrapEffect, // Convertis l'Effect en Layer
|
||||
Layer.provide(EnvConfigProvider),
|
||||
);
|
||||
|
||||
export const PrettyLogger = Layer.mergeAll(Logger.pretty, LogLevelLive);
|
||||
20
src/services/migrations.ts
Normal file
20
src/services/migrations.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import type { SQLocalDrizzle } from "sqlocal/drizzle";
|
||||
|
||||
import v0000 from "@/db/drizzle/0000_perfect_justice.sql?raw";
|
||||
import { Data, Effect } from "effect";
|
||||
|
||||
import { LocalSqlite } from "./db";
|
||||
|
||||
class MigrationsError extends Data.TaggedError("MigrationsError")<{ cause: unknown }> {}
|
||||
|
||||
const executeRawSql = (client: SQLocalDrizzle) => (sql: string) =>
|
||||
Effect.tryPromise({ catch: (error: unknown) => new MigrationsError({ cause: error }), try: () => client.sql(sql) });
|
||||
|
||||
export class Migrations extends Effect.Service<Migrations>()("Migrations", {
|
||||
dependencies: [LocalSqlite.Default],
|
||||
effect: Effect.gen(function*() {
|
||||
const db = yield* LocalSqlite;
|
||||
yield* Effect.logDebug("--- MIGRATIONS ---");
|
||||
return [yield* executeRawSql(db.client)(v0000)] as const;
|
||||
}),
|
||||
}) {}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { DiaryEntries } from "@/db/schemas";
|
||||
import { DiaryEntries, Users } from "@/db/schemas";
|
||||
import { singleResultOrFail } from "@/libs/utils/effects";
|
||||
import { desc } from "drizzle-orm";
|
||||
import { Data, Effect } from "effect";
|
||||
|
|
@ -12,11 +12,15 @@ export class ReadApi extends Effect.Service<ReadApi>()("ReadApi", {
|
|||
effect: Effect.gen(function*() {
|
||||
const { query } = yield* LocalSqlite;
|
||||
|
||||
yield* Effect.logDebug("--- READ-API ---");
|
||||
|
||||
return {
|
||||
getAllEntries: () => query(_ => _.select().from(DiaryEntries)),
|
||||
getLastAddedEntry: () =>
|
||||
query(_ => _.select().from(DiaryEntries).limit(1).orderBy(desc(DiaryEntries.dateCreated))).pipe(
|
||||
singleResultOrFail(() => new ReadApiError({ cause: "Aucune entrée n'a encore été ajoutée." })),
|
||||
),
|
||||
getUsers: () => query(_ => _.select().from(Users)),
|
||||
};
|
||||
}),
|
||||
}) {}
|
||||
|
|
|
|||
15
src/services/runtime-client.ts
Normal file
15
src/services/runtime-client.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { Layer, ManagedRuntime } from "effect";
|
||||
|
||||
import { LocalSqlite } from "./db";
|
||||
import { PrettyLogger } from "./logger";
|
||||
import { Migrations } from "./migrations";
|
||||
import { ReadApi } from "./read-api";
|
||||
|
||||
const MainLayer = Layer.mergeAll(
|
||||
// WriteApi.Default,
|
||||
LocalSqlite.Default,
|
||||
Migrations.Default,
|
||||
ReadApi.Default,
|
||||
).pipe(Layer.provide(PrettyLogger));
|
||||
|
||||
export const RuntimeClient = ManagedRuntime.make(MainLayer);
|
||||
119
src/styles/base/base.css
Executable file
119
src/styles/base/base.css
Executable file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 1. Utilise un meilleur modèle de boîte.
|
||||
* 2. Fait que seul font-size puisse influencer la taille du texte.
|
||||
* 3. Applique les schémas de couleurs.
|
||||
* 4. Utilise une indentation plus étroite.
|
||||
* 5. Permet l'usage de propriétés intrinsèques comme auto ou fit-content dans les animations.
|
||||
*/
|
||||
html {
|
||||
box-sizing: border-box; /* 1 */
|
||||
tab-size: 2; /* 4 */
|
||||
color-scheme: dark light; /* 3 */
|
||||
interpolate-size: allow-keywords; /* 6 */
|
||||
/* stylelint-disable */
|
||||
-moz-text-size-adjust: none; /* 2 */
|
||||
-webkit-text-size-adjust: none; /* 2 */
|
||||
text-size-adjust: none; /* 2 */
|
||||
block-size: 100%;
|
||||
/* stylelint-enable */
|
||||
|
||||
/* scrollbar-gutter: stable; */
|
||||
}
|
||||
|
||||
body {
|
||||
accent-color: var(--color-tertiary);
|
||||
background: var(--color-secondary);
|
||||
--webkit-font-smoothing: antialiased;
|
||||
font-family: monospace, system-ui, sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-kerning: normal;
|
||||
font-variant-ligatures: common-ligatures no-discretionary-ligatures no-historical-ligatures
|
||||
contextual;
|
||||
line-height: var(--line-height-comfortable);
|
||||
text-decoration-skip-ink: auto;
|
||||
text-rendering: geometricprecision;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Hérite le modèle de boîte de l'élément racine.
|
||||
* 2. Désactive toute marge pour partir de bases saines.
|
||||
* 3. Hérite toute propriété typographique et de couleur pour éviter des redéfinitions.
|
||||
*/
|
||||
*, *::before, *::after {
|
||||
box-sizing: inherit; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
padding: 0; /* 2 */
|
||||
font: inherit; /* 3 */
|
||||
font-feature-settings: inherit; /* 3 */
|
||||
font-variation-settings: inherit; /* 3 */
|
||||
color: inherit; /* 3 */
|
||||
letter-spacing: inherit; /* 3 */
|
||||
word-spacing: inherit; /* 3 */
|
||||
}
|
||||
|
||||
/* Utilise une couleur particulière pour l'arrière-plan des éléments sélectionnés avec le curseur. */
|
||||
*::selection {
|
||||
color: var(--color-secondary);
|
||||
background: var(--color-primary);
|
||||
}
|
||||
|
||||
/* TODO: Prendre en compte a11y-dialog */
|
||||
/* Empêche le défilement de la page quand une modale est ouverte. */
|
||||
:where(html:has(dialog:modal[open])) {
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
/* Retire les bordures et applique un modèle d'arrière-plan plus sain. */
|
||||
*:where(:not(progress, meter)) {
|
||||
background-repeat: no-repeat;
|
||||
background-origin: border-box;
|
||||
border: 0 solid transparent;
|
||||
}
|
||||
|
||||
/* Classe pour cacher visuellement tout en restant accessible par les lecteurs d'écran. */
|
||||
:where(.visually-hidden:not(:focus, :active, :focus-within)) {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
inline-size: 1px;
|
||||
block-size: 1px;
|
||||
white-space: nowrap;
|
||||
clip-path: inset(50%);
|
||||
}
|
||||
|
||||
/* Cache les éléments cachés. */
|
||||
:where([hidden]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Affiche un curseur « Désactivé » pour les éléments désactivés. */
|
||||
:where([disabled]) {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Applique des contours de focus visibles. */
|
||||
:where(:focus-visible) {
|
||||
outline: currentcolor solid 0.2rem;
|
||||
outline-offset: 0.2rem;
|
||||
}
|
||||
|
||||
:where(:focus-visible, :target) {
|
||||
scroll-margin-block: 8vh;
|
||||
}
|
||||
|
||||
/* Active une transition de page simple. */
|
||||
@view-transition {
|
||||
navigation: auto;
|
||||
}
|
||||
|
||||
/* Désactive animations et transitions pour les Utilisateurs le demandant explicitement. */
|
||||
@media (prefers-reduced-motion) {
|
||||
*, *::before, *::after {
|
||||
scroll-behavior: auto !important;
|
||||
transition: none !important;
|
||||
animation-duration: 0s !important;
|
||||
}
|
||||
|
||||
@view-transition {
|
||||
navigation: none !important;
|
||||
}
|
||||
}
|
||||
56
src/styles/base/elements.css
Normal file
56
src/styles/base/elements.css
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* Réinitialise l'apparence d'éléments interactifs. */
|
||||
:where(button, fieldset, input, select, textarea) {
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
/* Hauteur de ligne plus étroite pour les éléments interactifs. */
|
||||
:where(button, fieldset, input, label, select, textarea) {
|
||||
line-height: var(--line-height-compact);
|
||||
}
|
||||
|
||||
:where(textarea) {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
@supports (resize: block) {
|
||||
:where(textarea) {
|
||||
resize: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* Curseur de main pour les éléments interactifs cliquables. */
|
||||
:where(button, label, select) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:where(button) {
|
||||
inline-size: fit-content;
|
||||
}
|
||||
|
||||
/* Évite le dépassement des textes. */
|
||||
:where(p, h1, h2, h3, h4, h5, h6) {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* Les médias doivent occuper toute la longueur disponible au sein de leur propre bloc. */
|
||||
:where(img, picture, video, canvas, svg) {
|
||||
display: block;
|
||||
max-inline-size: 100%;
|
||||
block-size: auto;
|
||||
}
|
||||
|
||||
:where(ol, ul) {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
:where(a) {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* Empêche les marqueurs de listes de modifier la hauteur de ligne sur Firefox.
|
||||
* https://danburzo.ro/notes/moz-bullet-font
|
||||
*/
|
||||
::marker {
|
||||
line-height: 0;
|
||||
}
|
||||
39
src/styles/base/variables.css
Executable file
39
src/styles/base/variables.css
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
:root {
|
||||
/* Couleurs */
|
||||
|
||||
/* Réelles */
|
||||
--color-white: #fff;
|
||||
--color-black: #000;
|
||||
|
||||
/* Logiques */
|
||||
--color-primary: black;
|
||||
--color-secondary: salmon;
|
||||
--color-tertiary: dimgrey;
|
||||
--color-quartary: #be2727;
|
||||
|
||||
/* Typographie */
|
||||
|
||||
/* Hauteurs de ligne */
|
||||
--line-height-comfortable: 1.4;
|
||||
--line-height-compact: 1.1;
|
||||
|
||||
/* Échelles */
|
||||
--ratio: 1.4;
|
||||
--s-5: calc(var(--s-4) / var(--ratio));
|
||||
--s-4: calc(var(--s-3) / var(--ratio));
|
||||
--s-3: calc(var(--s-2) / var(--ratio));
|
||||
--s-2: calc(var(--s-1) / var(--ratio));
|
||||
--s-1: calc(var(--s0) / var(--ratio));
|
||||
--s0: 1rem;
|
||||
--s1: calc(var(--s0) * var(--ratio));
|
||||
--s2: calc(var(--s1) * var(--ratio));
|
||||
--s3: calc(var(--s2) * var(--ratio));
|
||||
--s4: calc(var(--s3) * var(--ratio));
|
||||
--s5: calc(var(--s4) * var(--ratio));
|
||||
|
||||
/* Arrière-plans à motifs */
|
||||
--bg25-secondary: repeating-conic-gradient(var(--color-tertiary) 0% 25%, transparent 0% 100%) 1px
|
||||
0.5px / 2px 2px;
|
||||
--bg75-secondary: repeating-conic-gradient(var(--color-secondary) 0% 75%, transparent 0% 100%) 1px
|
||||
0.5px / 2px 2px;
|
||||
}
|
||||
55
src/styles/components/imposter-box.css
Normal file
55
src/styles/components/imposter-box.css
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
.dialog {
|
||||
position: fixed; /* 1 */
|
||||
z-index: 2; /* 1 */
|
||||
inset: 0; /* 1 */
|
||||
display: flex; /* 2 */
|
||||
background: var(--bg25-secondary);
|
||||
margin: 0;
|
||||
|
||||
&[aria-hidden="true"] {
|
||||
display: none; /* 1 */
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
position: relative; /* 2 */
|
||||
max-inline-size: 80ch;
|
||||
margin: auto; /* 1 */
|
||||
padding: initial;
|
||||
border: 1px solid var(--color-primary);
|
||||
background-color: var(--color-secondary);
|
||||
box-shadow: 0.5rem 0.5rem 0 0 var(--color-primary);
|
||||
animation: fade-in 100ms 10ms both;
|
||||
|
||||
header {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-block-end: 1px solid var(--color-primary);
|
||||
|
||||
h2 {
|
||||
padding-inline: var(--s-1);
|
||||
font-size: var(--s1);
|
||||
}
|
||||
|
||||
button {
|
||||
padding: var(--s-1);
|
||||
font-family: Banquise, monospace;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.dialog-overlay, .dialog-content {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
3
src/styles/components/navigation-menu.css
Normal file
3
src/styles/components/navigation-menu.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[aria-current] {
|
||||
font-weight: 125;
|
||||
}
|
||||
7
src/styles/layouts/_layouts.css
Normal file
7
src/styles/layouts/_layouts.css
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
@import url("./box.css");
|
||||
@import url("./center.css");
|
||||
@import url("./cover.css");
|
||||
@import url("./cluster.css");
|
||||
@import url("./sidebar.css");
|
||||
@import url("./stack.css");
|
||||
@import url("./switcher.css");
|
||||
17
src/styles/layouts/box.css
Executable file
17
src/styles/layouts/box.css
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 1. Affiche une bordure pour les thèmes à haut contraste sans augmenter la taille de la boîte.
|
||||
*/
|
||||
.box {
|
||||
padding: var(--s0, 1rem);
|
||||
background-color: var(--color-secondary, #fff);
|
||||
outline: 0.125rem solid transparent; /* 1 */
|
||||
outline-offset: -0.125rem; /* 1 */
|
||||
|
||||
/* border: 1px solid var(--color-primary); */
|
||||
}
|
||||
|
||||
/* Inverse les couleurs de la boîte. */
|
||||
.box.invert {
|
||||
color: var(--color-secondary, #fff);
|
||||
background-color: var(--color-primary, #000);
|
||||
}
|
||||
14
src/styles/layouts/center.css
Executable file
14
src/styles/layouts/center.css
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 1. Utilise un modèle de boîte excluant les marges internes du calcul de la longueur.
|
||||
* 2. Centre l'Élément avec des marges externes automatiques en ligne et une longueur maximale.
|
||||
* 3. Assure que des espaces latéraux sont présents.
|
||||
*/
|
||||
.center {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
align-items: center;
|
||||
box-sizing: content-box; /* 1 */
|
||||
max-inline-size: var(--longueur-max-texte, 80ch); /* 2 */
|
||||
margin-inline: auto; /* 2 */
|
||||
padding-inline: var(--s0, 1rem) var(--s0, 1rem); /* 3 */
|
||||
}
|
||||
8
src/styles/layouts/cluster.css
Normal file
8
src/styles/layouts/cluster.css
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
.cluster {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
gap: var(--s0, 1rem);
|
||||
align-items: center;
|
||||
|
||||
/* justify-content: center; */
|
||||
}
|
||||
40
src/styles/layouts/cover.css
Executable file
40
src/styles/layouts/cover.css
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Cover est une disposition permettant de centrer verticalement en son sein un Élément, avec
|
||||
* potentiellement une en-tête et/ou potentiellement un pied de page à chaque extrémité.
|
||||
*
|
||||
* Un usage typique de Cover est l'affichage d'une partie introductive au sein d'une page.
|
||||
*
|
||||
* 1. Arrange les Éléments en colonne.
|
||||
* 2. Fait que la disposition ait une taille minimale fixe tout en permettant son expansion si le contenu la dépasse.
|
||||
* 3. Empêche l'Élément centrale de la disposition de toucher les bords.
|
||||
*/
|
||||
.cover {
|
||||
--cover-minimal-height: 100vb;
|
||||
--cover-container-padding: var(--s0, 1rem);
|
||||
--cover-inter-element-spacing: var(--s0, 1rem);
|
||||
|
||||
display: flex; /* 1 */
|
||||
flex-flow: column nowrap; /* 1 */
|
||||
min-block-size: var(--cover-minimal-height); /* 2 */
|
||||
padding: var(--cover-container-padding); /* 3 */
|
||||
|
||||
/* Applique un espacement inter-élément pour tout Élément supplémentaire. */
|
||||
> * {
|
||||
margin-block: var(--cover-inter-element-spacing);
|
||||
}
|
||||
|
||||
/* Pas de marge pour les Éléments aux extrémités de la disposition. */
|
||||
> :first-child:not(.cover-center) {
|
||||
margin-block-start: 0;
|
||||
}
|
||||
|
||||
/* Pas de marge pour les Éléments aux extrémités de la disposition. */
|
||||
> :last-child:not(.cover-center) {
|
||||
margin-block-end: 0;
|
||||
}
|
||||
|
||||
/* Centre verticalement l'Élément central. */
|
||||
> .cover-center {
|
||||
margin-block: auto;
|
||||
}
|
||||
}
|
||||
19
src/styles/layouts/sidebar.css
Normal file
19
src/styles/layouts/sidebar.css
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
.with-sidebar {
|
||||
--gutter: var(--s0);
|
||||
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
gap: var(--gutter, var(--s0));
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
.with-sidebar > :first-child {
|
||||
flex-basis: 0;
|
||||
flex-grow: 999;
|
||||
min-inline-size: 65%;
|
||||
}
|
||||
|
||||
.with-sidebar > :last-child {
|
||||
flex-basis: 15ch;
|
||||
flex-grow: 1;
|
||||
}
|
||||
19
src/styles/layouts/stack.css
Executable file
19
src/styles/layouts/stack.css
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
.stack {
|
||||
--space: var(--s0, 1rem);
|
||||
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.stack > * {
|
||||
margin-block: 0;
|
||||
}
|
||||
|
||||
.stack > * + * {
|
||||
margin-block-start: var(--space);
|
||||
}
|
||||
|
||||
.stack:only-child {
|
||||
block-size: 100%;
|
||||
}
|
||||
16
src/styles/layouts/switcher.css
Normal file
16
src/styles/layouts/switcher.css
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
.switcher {
|
||||
--threshold: 30rem;
|
||||
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
gap: var(--s0, 1rem);
|
||||
}
|
||||
|
||||
.switcher > *:not(.column-separator) {
|
||||
flex-basis: calc((var(--threshold) - 100%) * 999);
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.switcher > :nth-last-child(n+5), .switcher > :nth-last-child(n+5) ~ * {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
9
src/styles/main.css
Executable file
9
src/styles/main.css
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
@layer base, elements, layouts, components, themes;
|
||||
|
||||
@import url("./base/variables.css");
|
||||
@import url("./base/base.css") layer(base);
|
||||
@import url("./base/elements.css") layer(base);
|
||||
|
||||
@import url("./layouts/_layouts.css") layer(layouts);
|
||||
|
||||
@import url("./themes/default.css") layer(themes);
|
||||
1
src/styles/pages/main-layout.css
Executable file
1
src/styles/pages/main-layout.css
Executable file
|
|
@ -0,0 +1 @@
|
|||
|
||||
60
src/styles/themes/default.css
Normal file
60
src/styles/themes/default.css
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
@import url("./default/buttons.css");
|
||||
@import url("./default/headings.css");
|
||||
|
||||
body {
|
||||
font-family: BRKLY, sans-serif;
|
||||
font-weight: 100;
|
||||
background: var(--color-secondary);
|
||||
}
|
||||
|
||||
*:focus-visible {
|
||||
animation: flicker 50ms 2;
|
||||
}
|
||||
|
||||
.invert {
|
||||
font-weight: 120;
|
||||
color: var(--color-secondary);
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: Banquise, monospace;
|
||||
}
|
||||
|
||||
.container {
|
||||
--longueur-max-texte: 100ch;
|
||||
|
||||
place-content: start;
|
||||
place-items: start;
|
||||
|
||||
/* opacity: 0;
|
||||
animation: flicker 50ms 4 forwards 100ms ease-in; */
|
||||
}
|
||||
|
||||
.container > :is(main, aside) {
|
||||
margin-block-start: var(--s2);
|
||||
}
|
||||
|
||||
main > header {
|
||||
margin-block-end: var(--s2);
|
||||
}
|
||||
|
||||
#last-watched-media {
|
||||
--space: var(--s2);
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flicker {
|
||||
from, 49% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
50%, to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
54
src/styles/themes/default/buttons.css
Executable file
54
src/styles/themes/default/buttons.css
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
button {
|
||||
--button-background-color: var(--color-secondary);
|
||||
--button-border-color: var(--color-primary);
|
||||
--button-font-weight: 100;
|
||||
--button-padding: var(--s-1);
|
||||
--button-text-color: var(--color-primary);
|
||||
|
||||
padding: var(--button-padding);
|
||||
border: 1px solid var(--button-border-color);
|
||||
font-weight: var(--button-font-weight);
|
||||
color: var(--button-text-color);
|
||||
background-color: var(--button-background-color);
|
||||
box-shadow: 4px 4px 0 0 var(--color-primary);
|
||||
|
||||
&:hover {
|
||||
--button-background-color: var(--color-primary);
|
||||
--button-border-color: var(--color-secondary);
|
||||
--button-font-weight: 120;
|
||||
--button-text-color: var(--color-secondary);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateX(2px) translateY(2px);
|
||||
box-shadow: 1px 1px 0 0 var(--color-primary);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline-offset: -0.3rem;
|
||||
}
|
||||
|
||||
/* Inversion des couleurs. */
|
||||
&.invert {
|
||||
--button-background-color: var(--color-primary);
|
||||
--button-border-color: var(--color-secondary);
|
||||
--button-text-color: var(--color-secondary);
|
||||
|
||||
outline-color: var(--color-secondary);
|
||||
}
|
||||
|
||||
/* TODO: Déplacer dans un Composant. */
|
||||
/* Bouton intégré dans un ensemble. */
|
||||
&.integrated {
|
||||
border: initial;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
background: var(--bg75-secondary);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateX(2px) translateY(2px);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
src/styles/themes/default/headings.css
Executable file
12
src/styles/themes/default/headings.css
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
h1 {
|
||||
font-family: Banquise, monospace;
|
||||
font-size: var(--s3);
|
||||
font-weight: 600;
|
||||
letter-spacing: 1.5px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: Banquise, monospace;
|
||||
font-size: var(--s2);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
4
src/views/BaseView.vue
Normal file
4
src/views/BaseView.vue
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<template></template>
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { defineAsyncComponent, Suspense } from "vue";
|
||||
|
||||
const AsyncComp = defineAsyncComponent({
|
||||
delay: 0,
|
||||
loader: () => import("@/components/LastAddedEntry.vue"),
|
||||
timeout: 3000,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main>
|
||||
<Suspense>
|
||||
<AsyncComp></AsyncComp>
|
||||
<template #fallback>
|
||||
Loading...
|
||||
</template>
|
||||
</Suspense>
|
||||
</main>
|
||||
</template>
|
||||
7
src/views/SidebarView.vue
Normal file
7
src/views/SidebarView.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import NavigationMenu from "@/components/NavigationMenu.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NavigationMenu></NavigationMenu>
|
||||
</template>
|
||||
22
src/vite-env.d.ts
vendored
Normal file
22
src/vite-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
/** Le nom du fichier contenant la base de données SQLite. */
|
||||
readonly VITE_DATABASE_NAME: string;
|
||||
/** La clé API de l'application liée à un compte TMDB. */
|
||||
readonly VITE_TMDB_API_KEY: string;
|
||||
}
|
||||
|
||||
declare module "bun" {
|
||||
interface Env {
|
||||
/** Le nom du fichier contenant la base de données SQLite. */
|
||||
readonly VITE_DATABASE_NAME: string;
|
||||
/** La clé API de l'application liée à un compte TMDB. */
|
||||
readonly VITE_TMDB_API_KEY: string;
|
||||
}
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
export {};
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "vue",
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable", "DOM.AsyncIterable"],
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable", "DOM.AsyncIterable", "WebWorker"],
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"moduleResolution": "bundler",
|
||||
|
|
@ -32,11 +32,12 @@
|
|||
"noUncheckedSideEffectImports": false,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"resolveJsonModule": true,
|
||||
"paths": { "@/*": ["./src/*"] },
|
||||
"plugins": [{ "name": "@vue/typescript-plugin" }],
|
||||
"resolveJsonModule": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictNullChecks": true,
|
||||
|
|
@ -46,6 +47,6 @@
|
|||
"useUnknownInCatchVariables": true,
|
||||
"verbatimModuleSyntax": true
|
||||
},
|
||||
"exclude": ["dist/", ".cache"],
|
||||
"include": ["env.d.ts", "**/*", "**/*.vue"]
|
||||
"exclude": ["node_modules", "dist/", ".cache"],
|
||||
"include": ["src/router/typed-routes.d.ts", "src/env.d.ts", "**/*", "**/*.vue"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import unheadVite from "@unhead/addons/vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import { defineConfig } from "vite";
|
||||
import vueDevTools from "vite-plugin-vue-devtools";
|
||||
|
|
@ -8,33 +9,37 @@ export default defineConfig({
|
|||
emptyOutDir: true,
|
||||
outDir: "dist",
|
||||
reportCompressedSize: true,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
compact: true,
|
||||
format: "esm",
|
||||
validate: true,
|
||||
},
|
||||
},
|
||||
rollupOptions: { output: { compact: true, format: "esm", validate: true } },
|
||||
sourcemap: false,
|
||||
},
|
||||
cacheDir: ".cache/vite",
|
||||
clearScreen: false,
|
||||
css: {
|
||||
transformer: "lightningcss",
|
||||
},
|
||||
optimizeDeps: {
|
||||
exclude: ["sqlocal"],
|
||||
},
|
||||
css: { transformer: "lightningcss" },
|
||||
optimizeDeps: { exclude: ["sqlocal"] },
|
||||
plugins: [
|
||||
vue(),
|
||||
vueDevTools(),
|
||||
// vueDevTools(),
|
||||
{
|
||||
configureServer: server => {
|
||||
server.middlewares.use((_req, res, next) => {
|
||||
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||
res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
|
||||
res.setHeader("Access-Control-Allow-Origin", "http://localhost:4321");
|
||||
res.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
|
||||
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
|
||||
res.setHeader("Cross-Origin-Resource-Policy", "cross-origin");
|
||||
next();
|
||||
});
|
||||
},
|
||||
name: "configure-response-headers",
|
||||
},
|
||||
unheadVite(),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": Bun.fileURLToPath(new URL("./src", import.meta.url)),
|
||||
},
|
||||
},
|
||||
worker: {
|
||||
format: "es",
|
||||
},
|
||||
worker: { format: "es" },
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue