this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

lint, format, fix

alice 565459c2 af7b4692

+1479 -1019
+12
.editorconfig
··· 1 + # EditorConfig is awesome: https://EditorConfig.org 2 + 3 + # top-most EditorConfig file 4 + root = true 5 + 6 + [*] 7 + indent_style = space 8 + indent_size = 2 9 + end_of_line = lf 10 + charset = utf-8 11 + trim_trailing_whitespace = false 12 + insert_final_newline = true
+2
.husky/pre-commit
··· 1 + # shellcheck disable=SC2148 2 + bunx lint-staged
+2
.prettierignore
··· 1 + # ... 2 + dist/
+12
.prettierrc
··· 1 + { 2 + "trailingComma": "all", 3 + "tabWidth": 2, 4 + "semi": true, 5 + "singleQuote": true, 6 + "printWidth": 120, 7 + "experimentalTernaries": true, 8 + "plugins": ["@trivago/prettier-plugin-sort-imports"], 9 + "importOrder": ["^[./]"], 10 + "importOrderSeparation": true, 11 + "importOrderSortSpecifiers": true 12 + }
+406 -32
bun.lock
··· 10 10 "wrangler": "^4.7.0", 11 11 }, 12 12 "devDependencies": { 13 + "@eslint/js": "^9.13.0", 13 14 "@happy-dom/global-registrator": "^17.4.4", 15 + "@trivago/prettier-plugin-sort-imports": "^5", 14 16 "@types/bun": "^1.2.8", 15 - }, 16 - "peerDependencies": { 17 - "typescript": "^5", 17 + "@types/eslint__js": "^9", 18 + "@types/node": "^22.8.4", 19 + "eslint": "^9.13.0", 20 + "husky": "^9.1.6", 21 + "lint-staged": "^15.2.10", 22 + "prettier": "^3.3.3", 23 + "tsx": "^4.19.2", 24 + "typescript": "^5.6.3", 25 + "typescript-eslint": "^8.12.2", 18 26 }, 19 27 }, 20 28 }, 21 29 "packages": { 22 30 "@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=="], 23 31 32 + "@babel/generator": ["@babel/generator@7.27.0", "", { "dependencies": { "@babel/parser": "^7.27.0", "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw=="], 33 + 34 + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="], 35 + 24 36 "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], 37 + 38 + "@babel/parser": ["@babel/parser@7.27.0", "", { "dependencies": { "@babel/types": "^7.27.0" }, "bin": "./bin/babel-parser.js" }, "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg=="], 39 + 40 + "@babel/template": ["@babel/template@7.27.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/parser": "^7.27.0", "@babel/types": "^7.27.0" } }, "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA=="], 41 + 42 + "@babel/traverse": ["@babel/traverse@7.27.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.27.0", "@babel/parser": "^7.27.0", "@babel/template": "^7.27.0", "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA=="], 43 + 44 + "@babel/types": ["@babel/types@7.27.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg=="], 25 45 26 46 "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.0", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA=="], 27 47 ··· 41 61 42 62 "@emnapi/runtime": ["@emnapi/runtime@1.4.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw=="], 43 63 44 - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="], 64 + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag=="], 45 65 46 - "@esbuild/android-arm": ["@esbuild/android-arm@0.24.2", "", { "os": "android", "cpu": "arm" }, "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q=="], 66 + "@esbuild/android-arm": ["@esbuild/android-arm@0.25.2", "", { "os": "android", "cpu": "arm" }, "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA=="], 47 67 48 - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.24.2", "", { "os": "android", "cpu": "arm64" }, "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg=="], 68 + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.2", "", { "os": "android", "cpu": "arm64" }, "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w=="], 49 69 50 - "@esbuild/android-x64": ["@esbuild/android-x64@0.24.2", "", { "os": "android", "cpu": "x64" }, "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw=="], 70 + "@esbuild/android-x64": ["@esbuild/android-x64@0.25.2", "", { "os": "android", "cpu": "x64" }, "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg=="], 51 71 52 - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.24.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA=="], 72 + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA=="], 53 73 54 - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.24.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA=="], 74 + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA=="], 55 75 56 - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.24.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg=="], 76 + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w=="], 57 77 58 - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.24.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q=="], 78 + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ=="], 59 79 60 - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.24.2", "", { "os": "linux", "cpu": "arm" }, "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA=="], 80 + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.2", "", { "os": "linux", "cpu": "arm" }, "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g=="], 61 81 62 - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.24.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg=="], 82 + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g=="], 63 83 64 - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.24.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw=="], 84 + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ=="], 65 85 66 - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ=="], 86 + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.2", "", { "os": "linux", "cpu": "none" }, "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w=="], 67 87 68 - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw=="], 88 + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.2", "", { "os": "linux", "cpu": "none" }, "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q=="], 69 89 70 - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.24.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw=="], 90 + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g=="], 71 91 72 - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q=="], 92 + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.2", "", { "os": "linux", "cpu": "none" }, "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw=="], 73 93 74 - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.24.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw=="], 94 + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q=="], 75 95 76 - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.24.2", "", { "os": "linux", "cpu": "x64" }, "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q=="], 96 + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.2", "", { "os": "linux", "cpu": "x64" }, "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg=="], 77 97 78 - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.24.2", "", { "os": "none", "cpu": "arm64" }, "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw=="], 98 + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.2", "", { "os": "none", "cpu": "arm64" }, "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw=="], 79 99 80 - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.24.2", "", { "os": "none", "cpu": "x64" }, "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw=="], 100 + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.2", "", { "os": "none", "cpu": "x64" }, "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg=="], 101 + 102 + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg=="], 103 + 104 + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw=="], 81 105 82 - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.24.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A=="], 106 + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA=="], 107 + 108 + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q=="], 109 + 110 + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg=="], 111 + 112 + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.2", "", { "os": "win32", "cpu": "x64" }, "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA=="], 113 + 114 + "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.5.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w=="], 115 + 116 + "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], 117 + 118 + "@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=="], 119 + 120 + "@eslint/config-helpers": ["@eslint/config-helpers@0.2.1", "", {}, "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw=="], 83 121 84 - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.24.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA=="], 122 + "@eslint/core": ["@eslint/core@0.12.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg=="], 85 123 86 - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.24.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig=="], 124 + "@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "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-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="], 87 125 88 - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.24.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ=="], 126 + "@eslint/js": ["@eslint/js@9.23.0", "", {}, "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw=="], 89 127 90 - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.24.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA=="], 128 + "@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="], 91 129 92 - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="], 130 + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.8", "", { "dependencies": { "@eslint/core": "^0.13.0", "levn": "^0.4.1" } }, "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA=="], 93 131 94 132 "@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="], 95 133 96 134 "@happy-dom/global-registrator": ["@happy-dom/global-registrator@17.4.4", "", { "dependencies": { "happy-dom": "^17.4.4" } }, "sha512-njrU74GrYVHO43upIJr96f7pEmUG7YLZbHCGiHALBECeVnDKpepzL9kVc7KIl8S2nQOkPA0rAA1EyC3xASb54w=="], 97 135 136 + "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], 137 + 138 + "@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="], 139 + 140 + "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], 141 + 142 + "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="], 143 + 98 144 "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], 99 145 100 146 "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="], ··· 132 178 "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.33.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ=="], 133 179 134 180 "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.5", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="], 181 + 182 + "@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=="], 135 183 136 184 "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], 137 185 186 + "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="], 187 + 138 188 "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], 139 189 140 - "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], 190 + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], 141 191 142 192 "@lezer/common": ["@lezer/common@1.2.3", "", {}, "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA=="], 143 193 ··· 169 219 170 220 "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ=="], 171 221 222 + "@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=="], 223 + 224 + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], 225 + 226 + "@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=="], 227 + 172 228 "@parcel/bundler-default": ["@parcel/bundler-default@2.14.4", "", { "dependencies": { "@parcel/diagnostic": "2.14.4", "@parcel/graph": "3.4.4", "@parcel/plugin": "2.14.4", "@parcel/rust": "2.14.4", "@parcel/utils": "2.14.4", "nullthrows": "^1.1.1" } }, "sha512-JVqi5Sb7wv2KCTJFAAjHbnl6KC61jKNVYw/GtZm5s/Wxqvxx2tcp93rmRoBFo9X3gSgkg8jp4HkNAUHTxnsPnQ=="], 173 229 174 230 "@parcel/cache": ["@parcel/cache@2.14.4", "", { "dependencies": { "@parcel/fs": "2.14.4", "@parcel/logger": "2.14.4", "@parcel/utils": "2.14.4", "lmdb": "2.8.5" }, "peerDependencies": { "@parcel/core": "^2.14.4" } }, "sha512-CTTMySgNSgcSwbNWL4gODU1h9hMjBRyiC8/gcKDFqzw0wC/T+ZwX7wc5zNc/S9aJRTmmgvndcYKoVlds7YV2sg=="], ··· 337 393 338 394 "@swc/types": ["@swc/types@0.1.21", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ=="], 339 395 396 + "@trivago/prettier-plugin-sort-imports": ["@trivago/prettier-plugin-sort-imports@5.2.2", "", { "dependencies": { "@babel/generator": "^7.26.5", "@babel/parser": "^7.26.7", "@babel/traverse": "^7.26.7", "@babel/types": "^7.26.7", "javascript-natural-sort": "^0.7.1", "lodash": "^4.17.21" }, "peerDependencies": { "@vue/compiler-sfc": "3.x", "prettier": "2.x - 3.x", "prettier-plugin-svelte": "3.x", "svelte": "4.x || 5.x" }, "optionalPeers": ["@vue/compiler-sfc", "prettier-plugin-svelte", "svelte"] }, "sha512-fYDQA9e6yTNmA13TLVSA+WMQRc5Bn/c0EUBditUHNfMMxN7M82c38b1kEggVE3pLpZ0FwkwJkUEKMiOi52JXFA=="], 397 + 340 398 "@types/bun": ["@types/bun@1.2.8", "", { "dependencies": { "bun-types": "1.2.7" } }, "sha512-t8L1RvJVUghW5V+M/fL3Thbxcs0HwNsXsnTEBEfEVqGteiJToOlZ/fyOEaR1kZsNqnu+3XA4RI/qmnX4w6+S+w=="], 341 399 400 + "@types/eslint__js": ["@types/eslint__js@9.14.0", "", { "dependencies": { "@eslint/js": "*" } }, "sha512-s0jepCjOJWB/GKcuba4jISaVpBudw3ClXJ3fUK4tugChUMQsp6kSwuA8Dcx6wFd/JsJqcY8n4rEpa5RTHs5ypA=="], 401 + 402 + "@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="], 403 + 404 + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], 405 + 342 406 "@types/lodash": ["@types/lodash@4.17.16", "", {}, "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g=="], 343 407 344 408 "@types/node": ["@types/node@22.14.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA=="], 345 409 346 410 "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], 347 411 412 + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.29.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.29.0", "@typescript-eslint/type-utils": "8.29.0", "@typescript-eslint/utils": "8.29.0", "@typescript-eslint/visitor-keys": "8.29.0", "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.9.0" } }, "sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ=="], 413 + 414 + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.29.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.29.0", "@typescript-eslint/types": "8.29.0", "@typescript-eslint/typescript-estree": "8.29.0", "@typescript-eslint/visitor-keys": "8.29.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g=="], 415 + 416 + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.29.0", "", { "dependencies": { "@typescript-eslint/types": "8.29.0", "@typescript-eslint/visitor-keys": "8.29.0" } }, "sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw=="], 417 + 418 + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.29.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.29.0", "@typescript-eslint/utils": "8.29.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q=="], 419 + 420 + "@typescript-eslint/types": ["@typescript-eslint/types@8.29.0", "", {}, "sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg=="], 421 + 422 + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.29.0", "", { "dependencies": { "@typescript-eslint/types": "8.29.0", "@typescript-eslint/visitor-keys": "8.29.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow=="], 423 + 424 + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.29.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.29.0", "@typescript-eslint/types": "8.29.0", "@typescript-eslint/typescript-estree": "8.29.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA=="], 425 + 426 + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.29.0", "", { "dependencies": { "@typescript-eslint/types": "8.29.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg=="], 427 + 348 428 "acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="], 429 + 430 + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], 349 431 350 432 "acorn-walk": ["acorn-walk@8.3.2", "", {}, "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A=="], 351 433 434 + "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=="], 435 + 436 + "ansi-escapes": ["ansi-escapes@7.0.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw=="], 437 + 438 + "ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], 439 + 352 440 "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], 353 441 354 442 "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], 355 443 356 444 "as-table": ["as-table@1.0.55", "", { "dependencies": { "printable-characters": "^1.0.42" } }, "sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ=="], 357 445 446 + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], 447 + 358 448 "base-x": ["base-x@3.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA=="], 359 449 360 450 "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], 451 + 452 + "brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], 361 453 362 454 "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], 363 455 ··· 373 465 374 466 "chrome-trace-event": ["chrome-trace-event@1.0.4", "", {}, "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ=="], 375 467 468 + "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], 469 + 470 + "cli-truncate": ["cli-truncate@4.0.0", "", { "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" } }, "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA=="], 471 + 376 472 "clone": ["clone@2.1.2", "", {}, "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="], 377 473 378 474 "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], ··· 383 479 384 480 "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], 385 481 386 - "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], 482 + "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="], 483 + 484 + "commander": ["commander@13.1.0", "", {}, "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="], 485 + 486 + "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], 387 487 388 488 "cookie": ["cookie@0.5.0", "", {}, "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="], 389 489 390 490 "cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], 491 + 492 + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], 391 493 392 494 "data-uri-to-buffer": ["data-uri-to-buffer@2.0.2", "", {}, "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA=="], 393 495 496 + "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], 497 + 498 + "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], 499 + 394 500 "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="], 395 501 396 502 "detect-libc": ["detect-libc@2.0.3", "", {}, "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw=="], ··· 409 515 410 516 "electron-to-chromium": ["electron-to-chromium@1.5.130", "", {}, "sha512-Ou2u7L9j2XLZbhqzyX0jWDj6gA8D3jIfVzt4rikLf3cGBa0VdReuFimBKS9tQJA4+XpeCxj1NoWlfBXzbMa9IA=="], 411 517 518 + "emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="], 519 + 412 520 "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], 413 521 414 522 "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], 415 523 524 + "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], 525 + 416 526 "error-ex": ["error-ex@1.3.2", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="], 417 527 418 - "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=="], 528 + "esbuild": ["esbuild@0.25.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.2", "@esbuild/android-arm": "0.25.2", "@esbuild/android-arm64": "0.25.2", "@esbuild/android-x64": "0.25.2", "@esbuild/darwin-arm64": "0.25.2", "@esbuild/darwin-x64": "0.25.2", "@esbuild/freebsd-arm64": "0.25.2", "@esbuild/freebsd-x64": "0.25.2", "@esbuild/linux-arm": "0.25.2", "@esbuild/linux-arm64": "0.25.2", "@esbuild/linux-ia32": "0.25.2", "@esbuild/linux-loong64": "0.25.2", "@esbuild/linux-mips64el": "0.25.2", "@esbuild/linux-ppc64": "0.25.2", "@esbuild/linux-riscv64": "0.25.2", "@esbuild/linux-s390x": "0.25.2", "@esbuild/linux-x64": "0.25.2", "@esbuild/netbsd-arm64": "0.25.2", "@esbuild/netbsd-x64": "0.25.2", "@esbuild/openbsd-arm64": "0.25.2", "@esbuild/openbsd-x64": "0.25.2", "@esbuild/sunos-x64": "0.25.2", "@esbuild/win32-arm64": "0.25.2", "@esbuild/win32-ia32": "0.25.2", "@esbuild/win32-x64": "0.25.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ=="], 419 529 420 530 "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], 421 531 532 + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], 533 + 534 + "eslint": ["eslint@9.23.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", "@eslint/config-helpers": "^0.2.0", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.23.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.3.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-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw=="], 535 + 536 + "eslint-scope": ["eslint-scope@8.3.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ=="], 537 + 538 + "eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="], 539 + 540 + "espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="], 541 + 542 + "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], 543 + 544 + "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], 545 + 546 + "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], 547 + 548 + "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], 549 + 550 + "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], 551 + 552 + "execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], 553 + 422 554 "exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="], 423 555 424 556 "exsolve": ["exsolve@1.0.4", "", {}, "sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw=="], 557 + 558 + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], 559 + 560 + "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=="], 561 + 562 + "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], 563 + 564 + "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], 565 + 566 + "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], 567 + 568 + "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], 425 569 426 570 "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], 427 571 572 + "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], 573 + 574 + "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], 575 + 576 + "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], 577 + 428 578 "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], 429 579 580 + "get-east-asian-width": ["get-east-asian-width@1.3.0", "", {}, "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ=="], 581 + 430 582 "get-port": ["get-port@4.2.0", "", {}, "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw=="], 431 583 432 584 "get-source": ["get-source@2.0.12", "", { "dependencies": { "data-uri-to-buffer": "^2.0.0", "source-map": "^0.6.1" } }, "sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w=="], 433 585 586 + "get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], 587 + 588 + "get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="], 589 + 590 + "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], 591 + 434 592 "glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="], 435 593 436 - "globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="], 594 + "globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], 595 + 596 + "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], 437 597 438 598 "happy-dom": ["happy-dom@17.4.4", "", { "dependencies": { "webidl-conversions": "^7.0.0", "whatwg-mimetype": "^3.0.0" } }, "sha512-/Pb0ctk3HTZ5xEL3BZ0hK1AqDSAUuRQitOmROPHhfUYEWpmTImwfD8vFDGADmMAX0JYgbcgxWoLFKtsWhcpuVA=="], 439 599 ··· 443 603 444 604 "htmlparser2": ["htmlparser2@9.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "entities": "^4.5.0" } }, "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ=="], 445 605 606 + "human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="], 607 + 608 + "husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="], 609 + 610 + "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], 611 + 446 612 "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], 447 613 614 + "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], 615 + 448 616 "is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="], 449 617 450 618 "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], 451 619 620 + "is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="], 621 + 452 622 "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], 453 623 454 624 "is-json": ["is-json@2.0.1", "", {}, "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA=="], 455 625 456 626 "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], 627 + 628 + "is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], 629 + 630 + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], 631 + 632 + "javascript-natural-sort": ["javascript-natural-sort@0.7.1", "", {}, "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw=="], 457 633 458 634 "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], 459 635 460 636 "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], 461 637 638 + "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], 639 + 640 + "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], 641 + 462 642 "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], 463 643 644 + "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], 645 + 646 + "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], 647 + 464 648 "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], 649 + 650 + "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], 651 + 652 + "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], 465 653 466 654 "lightningcss": ["lightningcss@1.29.3", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.29.3", "lightningcss-darwin-x64": "1.29.3", "lightningcss-freebsd-x64": "1.29.3", "lightningcss-linux-arm-gnueabihf": "1.29.3", "lightningcss-linux-arm64-gnu": "1.29.3", "lightningcss-linux-arm64-musl": "1.29.3", "lightningcss-linux-x64-gnu": "1.29.3", "lightningcss-linux-x64-musl": "1.29.3", "lightningcss-win32-arm64-msvc": "1.29.3", "lightningcss-win32-x64-msvc": "1.29.3" } }, "sha512-GlOJwTIP6TMIlrTFsxTerwC0W6OpQpCGuX1ECRLBUVRh6fpJH3xTqjCjRgQHTb4ZXexH9rtHou1Lf03GKzmhhQ=="], 467 655 ··· 485 673 486 674 "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.29.3", "", { "os": "win32", "cpu": "x64" }, "sha512-IszwRPu2cPnDQsZpd7/EAr0x2W7jkaWqQ1SwCVIZ/tSbZVXPLt6k8s6FkcyBjViCzvB5CW0We0QbbP7zp2aBjQ=="], 487 675 676 + "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], 677 + 488 678 "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], 489 679 680 + "lint-staged": ["lint-staged@15.5.0", "", { "dependencies": { "chalk": "^5.4.1", "commander": "^13.1.0", "debug": "^4.4.0", "execa": "^8.0.1", "lilconfig": "^3.1.3", "listr2": "^8.2.5", "micromatch": "^4.0.8", "pidtree": "^0.6.0", "string-argv": "^0.3.2", "yaml": "^2.7.0" }, "bin": { "lint-staged": "bin/lint-staged.js" } }, "sha512-WyCzSbfYGhK7cU+UuDDkzUiytbfbi0ZdPy2orwtM75P3WTtQBzmG40cCxIa8Ii2+XjfxzLH6Be46tUfWS85Xfg=="], 681 + 682 + "listr2": ["listr2@8.2.5", "", { "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ=="], 683 + 490 684 "lmdb": ["lmdb@2.8.5", "", { "dependencies": { "msgpackr": "^1.9.5", "node-addon-api": "^6.1.0", "node-gyp-build-optional-packages": "5.1.1", "ordered-binary": "^1.4.1", "weak-lru-cache": "^1.2.2" }, "optionalDependencies": { "@lmdb/lmdb-darwin-arm64": "2.8.5", "@lmdb/lmdb-darwin-x64": "2.8.5", "@lmdb/lmdb-linux-arm": "2.8.5", "@lmdb/lmdb-linux-arm64": "2.8.5", "@lmdb/lmdb-linux-x64": "2.8.5", "@lmdb/lmdb-win32-x64": "2.8.5" }, "bin": { "download-lmdb-prebuilds": "bin/download-prebuilds.js" } }, "sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ=="], 491 685 686 + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], 687 + 492 688 "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], 493 689 690 + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], 691 + 692 + "log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="], 693 + 694 + "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], 695 + 696 + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], 697 + 494 698 "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], 495 699 496 700 "mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], 497 701 702 + "mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], 703 + 704 + "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], 705 + 498 706 "miniflare": ["miniflare@4.20250321.1", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "acorn": "8.14.0", "acorn-walk": "8.3.2", "exit-hook": "2.2.1", "glob-to-regexp": "0.4.1", "stoppable": "1.1.0", "undici": "^5.28.5", "workerd": "1.20250321.0", "ws": "8.18.0", "youch": "3.2.3", "zod": "3.22.3" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-pQuVtF6vQ1zMvPCo3Z19mzSFjgnlEnybzNzAJZipsqIk6kMXpYBZq+d8cWmeQFkBYlgeZKeKJ4EBKT6KapfTNg=="], 499 707 708 + "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], 709 + 710 + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], 711 + 500 712 "msgpackr": ["msgpackr@1.11.2", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g=="], 501 713 502 714 "msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="], 503 715 504 716 "mustache": ["mustache@4.2.0", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="], 717 + 718 + "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], 505 719 506 720 "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], 507 721 ··· 509 723 510 724 "node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="], 511 725 726 + "npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], 727 + 512 728 "nullthrows": ["nullthrows@1.1.1", "", {}, "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="], 513 729 514 730 "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], 515 731 732 + "onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="], 733 + 734 + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], 735 + 516 736 "ordered-binary": ["ordered-binary@1.5.3", "", {}, "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA=="], 737 + 738 + "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], 739 + 740 + "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], 517 741 518 742 "parcel": ["parcel@2.14.4", "", { "dependencies": { "@parcel/config-default": "2.14.4", "@parcel/core": "2.14.4", "@parcel/diagnostic": "2.14.4", "@parcel/events": "2.14.4", "@parcel/feature-flags": "2.14.4", "@parcel/fs": "2.14.4", "@parcel/logger": "2.14.4", "@parcel/package-manager": "2.14.4", "@parcel/reporter-cli": "2.14.4", "@parcel/reporter-dev-server": "2.14.4", "@parcel/reporter-tracer": "2.14.4", "@parcel/utils": "2.14.4", "chalk": "^4.1.2", "commander": "^12.1.0", "get-port": "^4.2.0" }, "bin": { "parcel": "lib/bin.js" } }, "sha512-XmnIurC4CPdQm9OFJMbjgvto5Jz2szZ5/p6EY4pAljU/SLPhtBzJ3+J6OyljGFdbVxEXx4dp+7Cvf7eaDZsEEg=="], 519 743 ··· 521 745 522 746 "parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], 523 747 748 + "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], 749 + 750 + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], 751 + 524 752 "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], 525 753 526 754 "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], ··· 529 757 530 758 "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 531 759 760 + "pidtree": ["pidtree@0.6.0", "", { "bin": { "pidtree": "bin/pidtree.js" } }, "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g=="], 761 + 532 762 "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], 533 763 534 764 "posthtml": ["posthtml@0.16.6", "", { "dependencies": { "posthtml-parser": "^0.11.0", "posthtml-render": "^3.0.0" } }, "sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ=="], ··· 537 767 538 768 "posthtml-render": ["posthtml-render@3.0.0", "", { "dependencies": { "is-json": "^2.0.1" } }, "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA=="], 539 769 770 + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], 771 + 772 + "prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="], 773 + 540 774 "printable-characters": ["printable-characters@1.0.42", "", {}, "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ=="], 775 + 776 + "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], 777 + 778 + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], 541 779 542 780 "react-refresh": ["react-refresh@0.16.0", "", {}, "sha512-FPvF2XxTSikpJxcr+bHut2H4gJ17+18Uy20D5/F+SKzFap62R3cM5wH6b8WN3LyGSYeQilLEcJcR1fjBSI2S1A=="], 543 781 ··· 545 783 546 784 "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], 547 785 786 + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], 787 + 788 + "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], 789 + 790 + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], 791 + 792 + "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], 793 + 794 + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], 795 + 548 796 "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], 549 797 550 798 "semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], 551 799 552 800 "sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="], 553 801 802 + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], 803 + 804 + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], 805 + 806 + "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], 807 + 554 808 "simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="], 809 + 810 + "slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="], 555 811 556 812 "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], 557 813 ··· 561 817 562 818 "stoppable": ["stoppable@1.1.0", "", {}, "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw=="], 563 819 820 + "string-argv": ["string-argv@0.3.2", "", {}, "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="], 821 + 822 + "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], 823 + 824 + "strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], 825 + 826 + "strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="], 827 + 828 + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], 829 + 564 830 "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], 565 831 566 832 "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="], ··· 569 835 570 836 "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], 571 837 838 + "ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="], 839 + 572 840 "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], 841 + 842 + "tsx": ["tsx@4.19.3", "", { "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ=="], 843 + 844 + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], 573 845 574 846 "type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="], 575 847 576 848 "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], 577 849 850 + "typescript-eslint": ["typescript-eslint@8.29.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.29.0", "@typescript-eslint/parser": "8.29.0", "@typescript-eslint/utils": "8.29.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-ep9rVd9B4kQsZ7ZnWCVxUE/xDLUUUsRzE0poAeNu+4CkFErLfuvPt/qtm2EpnSyfvsR0S6QzDFSrPCFBwf64fg=="], 851 + 578 852 "ufo": ["ufo@1.5.4", "", {}, "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ=="], 579 853 580 854 "undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="], ··· 584 858 "unenv": ["unenv@2.0.0-rc.15", "", { "dependencies": { "defu": "^6.1.4", "exsolve": "^1.0.4", "ohash": "^2.0.11", "pathe": "^2.0.3", "ufo": "^1.5.4" } }, "sha512-J/rEIZU8w6FOfLNz/hNKsnY+fFHWnu9MH4yRbSZF3xbbGHovcetXPs7sD+9p8L6CeNC//I9bhRYAOsBt2u7/OA=="], 585 859 586 860 "update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="], 861 + 862 + "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], 587 863 588 864 "utility-types": ["utility-types@3.11.0", "", {}, "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw=="], 589 865 ··· 593 869 594 870 "whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="], 595 871 872 + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], 873 + 874 + "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], 875 + 596 876 "workerd": ["workerd@1.20250321.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20250321.0", "@cloudflare/workerd-darwin-arm64": "1.20250321.0", "@cloudflare/workerd-linux-64": "1.20250321.0", "@cloudflare/workerd-linux-arm64": "1.20250321.0", "@cloudflare/workerd-windows-64": "1.20250321.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-vyuz9pdJ+7o1lC79vQ2UVRLXPARa2Lq94PbTfqEcYQeSxeR9X+YqhNq2yysv8Zs5vpokmexLCtMniPp9u+2LVQ=="], 597 877 598 878 "wrangler": ["wrangler@4.7.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.0", "@cloudflare/unenv-preset": "2.3.1", "blake3-wasm": "2.1.5", "esbuild": "0.24.2", "miniflare": "4.20250321.1", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.15", "workerd": "1.20250321.0" }, "optionalDependencies": { "fsevents": "~2.3.2", "sharp": "^0.33.5" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20250321.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-5LoyNxpPG8K0kcU43Ossyj7+Hq78v8BNtu7ZNNSxDOUcairMEDwcbrbUOqzu/iM4yHiri5wCjl4Ja57fKED/Sg=="], 599 879 880 + "wrap-ansi": ["wrap-ansi@9.0.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q=="], 881 + 600 882 "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], 883 + 884 + "yaml": ["yaml@2.7.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ=="], 885 + 886 + "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], 601 887 602 888 "youch": ["youch@3.2.3", "", { "dependencies": { "cookie": "^0.5.0", "mustache": "^4.2.0", "stacktracey": "^2.1.8" } }, "sha512-ZBcWz/uzZaQVdCvfV4uk616Bbpf2ee+F/AvuKDR5EwX/Y4v06xWdtMluqTD7+KlZdM93lLm9gMZYo0sKBS0pgw=="], 603 889 604 890 "zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], 605 891 892 + "@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], 893 + 894 + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], 895 + 896 + "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], 897 + 898 + "@eslint/plugin-kit/@eslint/core": ["@eslint/core@0.13.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw=="], 899 + 900 + "@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="], 901 + 902 + "@parcel/packager-js/globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="], 903 + 606 904 "@parcel/source-map/detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="], 607 905 608 906 "@parcel/watcher/detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="], 907 + 908 + "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 609 909 610 910 "error-ex/is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], 611 911 912 + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 913 + 914 + "lint-staged/chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], 915 + 612 916 "lmdb/node-addon-api": ["node-addon-api@6.1.0", "", {}, "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA=="], 613 917 918 + "log-update/slice-ansi": ["slice-ansi@7.1.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg=="], 919 + 614 920 "msgpackr-extract/node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="], 615 921 922 + "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], 923 + 924 + "parcel/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], 925 + 616 926 "posthtml/posthtml-parser": ["posthtml-parser@0.11.0", "", { "dependencies": { "htmlparser2": "^7.1.1" } }, "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw=="], 617 927 928 + "restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], 929 + 930 + "slice-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], 931 + 932 + "wrangler/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=="], 933 + 934 + "wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], 935 + 936 + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 937 + 938 + "log-update/slice-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], 939 + 940 + "log-update/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.0.0", "", { "dependencies": { "get-east-asian-width": "^1.0.0" } }, "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA=="], 941 + 618 942 "posthtml/posthtml-parser/htmlparser2": ["htmlparser2@7.2.0", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.2", "domutils": "^2.8.0", "entities": "^3.0.1" } }, "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog=="], 943 + 944 + "wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="], 945 + 946 + "wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.24.2", "", { "os": "android", "cpu": "arm" }, "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q=="], 947 + 948 + "wrangler/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.24.2", "", { "os": "android", "cpu": "arm64" }, "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg=="], 949 + 950 + "wrangler/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.24.2", "", { "os": "android", "cpu": "x64" }, "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw=="], 951 + 952 + "wrangler/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.24.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA=="], 953 + 954 + "wrangler/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.24.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA=="], 955 + 956 + "wrangler/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.24.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg=="], 957 + 958 + "wrangler/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.24.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q=="], 959 + 960 + "wrangler/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.24.2", "", { "os": "linux", "cpu": "arm" }, "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA=="], 961 + 962 + "wrangler/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.24.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg=="], 963 + 964 + "wrangler/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.24.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw=="], 965 + 966 + "wrangler/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ=="], 967 + 968 + "wrangler/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw=="], 969 + 970 + "wrangler/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.24.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw=="], 971 + 972 + "wrangler/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q=="], 973 + 974 + "wrangler/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.24.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw=="], 975 + 976 + "wrangler/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.24.2", "", { "os": "linux", "cpu": "x64" }, "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q=="], 977 + 978 + "wrangler/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.24.2", "", { "os": "none", "cpu": "arm64" }, "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw=="], 979 + 980 + "wrangler/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.24.2", "", { "os": "none", "cpu": "x64" }, "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw=="], 981 + 982 + "wrangler/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.24.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A=="], 983 + 984 + "wrangler/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.24.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA=="], 985 + 986 + "wrangler/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.24.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig=="], 987 + 988 + "wrangler/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.24.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ=="], 989 + 990 + "wrangler/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.24.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA=="], 991 + 992 + "wrangler/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="], 619 993 620 994 "posthtml/posthtml-parser/htmlparser2/domhandler": ["domhandler@4.3.1", "", { "dependencies": { "domelementtype": "^2.2.0" } }, "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ=="], 621 995
+29
eslint.config.mjs
··· 1 + import eslint from '@eslint/js'; 2 + import tseslint from 'typescript-eslint'; 3 + 4 + export default tseslint.config( 5 + { 6 + ignores: ['dist/'], 7 + }, 8 + eslint.configs.recommended, 9 + ...tseslint.configs.strictTypeChecked, 10 + ...tseslint.configs.stylisticTypeChecked, 11 + { 12 + languageOptions: { 13 + parserOptions: { 14 + projectService: { 15 + allowDefaultProject: ['*.js'], 16 + defaultProject: 'tsconfig.json', 17 + }, 18 + }, 19 + }, 20 + rules: { 21 + '@typescript-eslint/no-non-null-assertion': 'off', 22 + '@typescript-eslint/restrict-template-expressions': 'off', 23 + }, 24 + }, 25 + { 26 + files: ['eslint.config.mjs'], 27 + extends: [tseslint.configs.disableTypeChecked], 28 + }, 29 + );
+1 -1
happydom.ts
··· 1 - import { GlobalRegistrator } from "@happy-dom/global-registrator"; 1 + import { GlobalRegistrator } from '@happy-dom/global-registrator'; 2 2 3 3 GlobalRegistrator.register();
+112 -109
index.html
··· 1 - <!DOCTYPE html> 1 + <!doctype html> 2 2 <html lang="en"> 3 - <head> 4 - <meta charset="UTF-8" /> 5 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 - <title>Crafting Your Values</title> 7 - <link rel="stylesheet" href="styles.css" /> 8 - </head> 9 - <body> 10 - <div id="app"> 11 - <header> 12 - <h1>Crafting Your Values Exercise</h1> 13 - <div id="global-controls"> 14 - <button id="undoBtn" disabled>Undo</button> 15 - <button id="redoBtn" disabled>Redo</button> 16 - <button id="clearStorageBtn">Restart exercise</button> 17 - <button id="useLimitedValuesBtn">Use 10 Values (default, for testing)</button> 18 - <button id="useAllValuesBtn">Use All Values</button> 19 - </div> 20 - </header> 3 + <head> 4 + <meta charset="UTF-8" /> 5 + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 + <title>Crafting Your Values</title> 7 + <link rel="stylesheet" href="styles.css" /> 8 + </head> 9 + <body> 10 + <div id="app"> 11 + <header> 12 + <h1>Crafting Your Values Exercise</h1> 13 + <div id="global-controls"> 14 + <button id="undoBtn" disabled>Undo</button> 15 + <button id="redoBtn" disabled>Redo</button> 16 + <button id="clearStorageBtn">Restart exercise</button> 17 + <button id="useLimitedValuesBtn">Use 10 Values (default, for testing)</button> 18 + <button id="useAllValuesBtn">Use All Values</button> 19 + </div> 20 + </header> 21 21 22 - <!-- Add Value Form (Initially Hidden) --> 23 - <div id="addValueForm" class="modal" style="display: none;"> 22 + <!-- Add Value Form (Initially Hidden) --> 23 + <div id="addValueForm" class="modal" style="display: none"> 24 24 <div class="modal-content"> 25 - <h3>Add New Value</h3> 26 - <label for="newValueName">Value Name:</label> 27 - <input type="text" id="newValueName" required> 28 - <label for="newValueDesc">Description:</label> 29 - <textarea id="newValueDesc" rows="3"></textarea> 30 - <div class="modal-buttons"> 31 - <button id="saveNewValueBtn">Save</button> 32 - <button id="cancelNewValueBtn">Cancel</button> 33 - </div> 25 + <h3>Add New Value</h3> 26 + <label for="newValueName">Value Name:</label> 27 + <input type="text" id="newValueName" required /> 28 + <label for="newValueDesc">Description:</label> 29 + <textarea id="newValueDesc" rows="3"></textarea> 30 + <div class="modal-buttons"> 31 + <button id="saveNewValueBtn">Save</button> 32 + <button id="cancelNewValueBtn">Cancel</button> 33 + </div> 34 34 </div> 35 - </div> 35 + </div> 36 36 37 - <!-- Part 1: Initial Sorting --> 38 - <section id="part1" class="exercise-part"> 39 - <h2>Part 1: Initial Sorting <button id="showAddValueFormBtn" class="inline-btn">+ Add New</button></h2> 40 - <div class="columns"> 41 - <div class="column" data-column="unassigned"> 42 - <h3>Unassigned</h3> 43 - <div id="part1-unassignedContainer" class="card-container"></div> 37 + <!-- Part 1: Initial Sorting --> 38 + <section id="part1" class="exercise-part"> 39 + <h2>Part 1: Initial Sorting <button id="showAddValueFormBtn" class="inline-btn">+ Add New</button></h2> 40 + <div class="columns"> 41 + <div class="column" data-column="unassigned"> 42 + <h3>Unassigned</h3> 43 + <div id="part1-unassignedContainer" class="card-container"></div> 44 + </div> 45 + <div class="column" data-column="veryImportant"> 46 + <h3>Very important to me</h3> 47 + <div id="part1-veryImportantContainer" class="card-container"></div> 48 + </div> 49 + <div class="column" data-column="important"> 50 + <h3>Important to me</h3> 51 + <div id="part1-importantContainer" class="card-container"></div> 52 + </div> 53 + <div class="column" data-column="notImportant"> 54 + <h3>Not important to me</h3> 55 + <div id="part1-notImportantContainer" class="card-container"></div> 56 + </div> 44 57 </div> 45 - <div class="column" data-column="veryImportant"> 46 - <h3>Very important to me</h3> 47 - <div id="part1-veryImportantContainer" class="card-container"></div> 48 - </div> 49 - <div class="column" data-column="important"> 50 - <h3>Important to me</h3> 51 - <div id="part1-importantContainer" class="card-container"></div> 52 - </div> 53 - <div class="column" data-column="notImportant"> 54 - <h3>Not important to me</h3> 55 - <div id="part1-notImportantContainer" class="card-container"></div> 56 - </div> 57 - </div> 58 - <button id="toPart2">Next</button> 59 - </section> 58 + <button id="toPart2">Next</button> 59 + </section> 60 60 61 - <!-- Part 2: Further Sorting --> 62 - <section id="part2" class="exercise-part" style="display: none;"> 63 - <h2>Part 2: Further Sorting</h2> 64 - <p>Take the values from the "Not important to me" and "Important to me" columns and put them aside.</p> 65 - <p>Create 3 columns again: "Very important to me", "Important to me" and "Not important to me" and do the same exercise as you did in Part 1, but with the "Very important to me" values only.</p> 66 - <div class="columns"> 67 - <div class="column" data-column="unassigned"> 68 - <h3>Unassigned</h3> 69 - <div id="part2-unassignedContainer" class="card-container"></div> 61 + <!-- Part 2: Further Sorting --> 62 + <section id="part2" class="exercise-part" style="display: none"> 63 + <h2>Part 2: Further Sorting</h2> 64 + <p>Take the values from the "Not important to me" and "Important to me" columns and put them aside.</p> 65 + <p> 66 + Create 3 columns again: "Very important to me", "Important to me" and "Not important to me" and do the same 67 + exercise as you did in Part 1, but with the "Very important to me" values only. 68 + </p> 69 + <div class="columns"> 70 + <div class="column" data-column="unassigned"> 71 + <h3>Unassigned</h3> 72 + <div id="part2-unassignedContainer" class="card-container"></div> 73 + </div> 74 + <div class="column" data-column="veryImportant"> 75 + <h3>Very important to me</h3> 76 + <div id="part2-veryImportantContainer" class="card-container"></div> 77 + </div> 78 + <div class="column" data-column="important"> 79 + <h3>Important to me</h3> 80 + <div id="part2-importantContainer" class="card-container"></div> 81 + </div> 82 + <div class="column" data-column="notImportant"> 83 + <h3>Not important to me</h3> 84 + <div id="part2-notImportantContainer" class="card-container"></div> 85 + </div> 70 86 </div> 71 - <div class="column" data-column="veryImportant"> 72 - <h3>Very important to me</h3> 73 - <div id="part2-veryImportantContainer" class="card-container"></div> 74 - </div> 75 - <div class="column" data-column="important"> 76 - <h3>Important to me</h3> 77 - <div id="part2-importantContainer" class="card-container"></div> 78 - </div> 79 - <div class="column" data-column="notImportant"> 80 - <h3>Not important to me</h3> 81 - <div id="part2-notImportantContainer" class="card-container"></div> 82 - </div> 83 - </div> 84 - <!-- <button id="backToPart1">Back</button> --> 85 - <button id="toPart3">Next</button> 86 - </section> 87 + <!-- <button id="backToPart1">Back</button> --> 88 + <button id="toPart3">Next</button> 89 + </section> 87 90 88 - <!-- Part 3: Narrowing Down --> 89 - <section id="part3" class="exercise-part" style="display: none;"> 90 - <h2>Part 3: Narrowing Down</h2> 91 - <div class="columns"> 92 - <div class="column" data-column="core"> 93 - <h3>F*CK YEAH (Core Values, max 5)</h3> 94 - <div class="card-container" id="coreContainer"></div> 95 - </div> 96 - <div class="column" data-column="additional"> 97 - <h3>Also Something I Want</h3> 98 - <div class="card-container" id="additionalContainer"></div> 91 + <!-- Part 3: Narrowing Down --> 92 + <section id="part3" class="exercise-part" style="display: none"> 93 + <h2>Part 3: Narrowing Down</h2> 94 + <div class="columns"> 95 + <div class="column" data-column="core"> 96 + <h3>F*CK YEAH (Core Values, max 5)</h3> 97 + <div class="card-container" id="coreContainer"></div> 98 + </div> 99 + <div class="column" data-column="additional"> 100 + <h3>Also Something I Want</h3> 101 + <div class="card-container" id="additionalContainer"></div> 102 + </div> 99 103 </div> 100 - </div> 101 - <!-- <button id="backToPart2">Back</button> --> 102 - <button id="toPart4">Next</button> 103 - </section> 104 + <!-- <button id="backToPart2">Back</button> --> 105 + <button id="toPart4">Next</button> 106 + </section> 104 107 105 - <!-- Part 4: Final Statements --> 106 - <section id="part4" class="exercise-part" style="display: none;"> 107 - <h2>Part 4: Final Statements</h2> 108 - <div id="finalStatements"></div> 109 - <button id="finish">Finish</button> 110 - <!-- <button id="backToPart3">Back</button> --> 111 - </section> 108 + <!-- Part 4: Final Statements --> 109 + <section id="part4" class="exercise-part" style="display: none"> 110 + <h2>Part 4: Final Statements</h2> 111 + <div id="finalStatements"></div> 112 + <button id="finish">Finish</button> 113 + <!-- <button id="backToPart3">Back</button> --> 114 + </section> 112 115 113 - <!-- Review/Export Page --> 114 - <section id="review" class="exercise-part" style="display: none;"> 115 - <h2>Review</h2> 116 - <div id="reviewContent"></div> 117 - <button id="restart">Restart</button> 118 - </section> 119 - </div> 116 + <!-- Review/Export Page --> 117 + <section id="review" class="exercise-part" style="display: none"> 118 + <h2>Review</h2> 119 + <div id="reviewContent"></div> 120 + <button id="restart">Restart</button> 121 + </section> 122 + </div> 120 123 121 - <script type="module" src="./index.ts"></script> 122 - </body> 124 + <script type="module" src="./index.ts"></script> 125 + </body> 123 126 </html>
+208 -207
index.test.ts
··· 1 - import { App } from "./index"; 2 - import { UndoManager } from "./undoManager"; 3 - import type { AppState, ValueCard } from "./index"; 4 - import { describe, test, expect, beforeEach } from "bun:test"; 5 - import { ALL_VALUE_DEFINITIONS, LIMITED_VALUE_DEFINITIONS, VALUES } from "./values"; // Import value counts for tests 1 + import { beforeEach, describe, expect, test } from 'bun:test'; 2 + 3 + import { App } from './index'; 4 + import type { AppState } from './index'; 5 + import { UndoManager } from './undoManager'; 6 + import { VALUES } from './values'; 7 + 8 + // Import value counts for tests 6 9 const ALL_VALUES_COUNT = VALUES.length; 7 10 const LIMITED_VALUES_COUNT = 10; 8 11 9 12 // Mock necessary DOM elements and event listeners 10 13 beforeEach(() => { 11 14 // Mock window.alert to prevent blocking tests 12 - window.alert = () => {}; // Replace alert with a non-blocking empty function 15 + window.alert = () => { 16 + /* no op */ 17 + }; // Add comment to satisfy linter 13 18 // Mock window.confirm to default to true (yes) for tests, unless overridden 14 - window.confirm = () => true; 19 + window.confirm = () => true; 15 20 16 21 // The happy-dom environment should provide localStorage automatically. 17 - // We still need to clear it before each test if the environment doesn't do it automatically. 18 - if (typeof window !== 'undefined' && window.localStorage) { 19 - window.localStorage.clear(); 20 - } 22 + // We still need to clear it before each test. 23 + window.localStorage.clear(); 21 24 22 25 document.body.innerHTML = ` 23 26 <div id="addValueForm" class="modal" style="display: none;"> ··· 77 80 78 81 beforeEach(() => { 79 82 // Initialize app before each test, using the mocked DOM 80 - app = new App(); 83 + app = new App(); 81 84 initialState = app.defaultState(); // Get initial state structure for comparison 82 85 }); 83 86 ··· 85 88 const state = app.undoManager.getState(); 86 89 expect(state.currentPart).toBe('part1'); 87 90 expect(state.cards.length).toBeGreaterThan(0); 88 - expect(state.cards.every(c => c.column === 'unassigned')).toBe(true); 91 + expect(state.cards.every((c) => c.column === 'unassigned')).toBe(true); 89 92 }); 90 93 91 94 test('Part 1 to Part 2 transition moves only veryImportant cards', () => { 92 95 // Arrange: Move some cards 93 - let state = app.undoManager.getState(); 96 + const state = app.undoManager.getState(); 94 97 // Add checks to ensure cards exist at these indices before modification 95 98 if (state.cards.length < 3) { 96 - throw new Error("Test setup failed: Initial state should have at least 3 cards for this test."); 99 + throw new Error('Test setup failed: Initial state should have at least 3 cards for this test.'); 97 100 } 98 101 // Assign ALL cards to avoid blocking the transition due to the unassigned check 99 102 state.cards.forEach((card, index) => { 100 - if (index === 0) { 101 - card.column = 'veryImportant'; 102 - } else if (index === 1) { 103 - card.column = 'important'; 104 - } else if (index === 2) { 105 - card.column = 'veryImportant'; 106 - } else { 107 - card.column = 'notImportant'; // Assign all others 108 - } 103 + if (index === 0) { 104 + card.column = 'veryImportant'; 105 + } else if (index === 1) { 106 + card.column = 'important'; 107 + } else if (index === 2) { 108 + card.column = 'veryImportant'; 109 + } else { 110 + card.column = 'notImportant'; // Assign all others 111 + } 109 112 }); 110 113 app.updateState(state); 111 114 ··· 117 120 const part2State = app.undoManager.getState(); 118 121 expect(part2State.currentPart).toBe('part2'); 119 122 expect(part2State.cards.length).toBe(2); 120 - expect(part2State.cards.every(c => c.column === 'unassigned')).toBe(true); 123 + expect(part2State.cards.every((c) => c.column === 'unassigned')).toBe(true); 121 124 122 125 // Check names to be sure 123 - const cardNames = part2State.cards.map(c => c.name); 126 + const cardNames = part2State.cards.map((c) => c.name); 124 127 // Add checks here too, although the length check above makes these safe 125 128 if (initialState.cards.length < 3) { 126 - throw new Error("Test setup failed: Initial state lost cards unexpectedly."); 129 + throw new Error('Test setup failed: Initial state lost cards unexpectedly.'); 127 130 } 128 131 // Assign to variables first to help type inference 129 132 const card0 = initialState.cards[0]; ··· 132 135 133 136 // Add explicit checks for the variables (though length check implies they exist) 134 137 if (!card0 || !card1 || !card2) { 135 - throw new Error("Test setup failed: Card elements are unexpectedly undefined."); 138 + throw new Error('Test setup failed: Card elements are unexpectedly undefined.'); 136 139 } 137 140 138 141 expect(cardNames).toContain(card0.name); ··· 144 147 // Arrange: Leave some cards unassigned (initial state) 145 148 const initialStateCards = app.undoManager.getState().cards; 146 149 // Ensure there is at least one unassigned card 147 - expect(initialStateCards.some(c => c.column === 'unassigned')).toBe(true); 150 + expect(initialStateCards.some((c) => c.column === 'unassigned')).toBe(true); 148 151 149 152 // Act: Simulate clicking the button 150 153 const button = document.getElementById('toPart2'); ··· 159 162 160 163 test('Part 2 to Part 4 transition SKIPS Part 3 if <= 5 veryImportant cards', () => { 161 164 // Arrange: Setup state in Part 2 with 4 'veryImportant' cards 162 - let state = app.undoManager.getState(); 165 + const state = app.undoManager.getState(); 163 166 state.currentPart = 'part2'; // Manually set part for setup 164 167 state.cards = [ 165 168 { id: 1, name: 'V1', column: 'veryImportant', order: 0 }, ··· 168 171 { id: 4, name: 'V4', column: 'veryImportant', order: 3 }, 169 172 { id: 5, name: 'I1', column: 'important', order: 4 }, // Need some non-veryImportant too 170 173 ]; 171 - app.updateState(state); 172 - // Note: Need to re-bind listeners if updateState doesn't do it, 174 + app.updateState(state); 175 + // Note: Need to re-bind listeners if updateState doesn't do it, 173 176 // but our simple listener binding in constructor might suffice if DOM isn't fully replaced. 174 177 // For robustness, re-creating App instance or re-binding might be better in complex scenarios. 175 178 app = new App(); // Re-create to ensure listeners are bound to correct state/DOM 176 - 179 + 177 180 // Act: Click the 'Next' button (toPart3) 178 181 const button = document.getElementById('toPart3'); 179 182 button?.click(); ··· 182 185 const part4State = app.undoManager.getState(); 183 186 expect(part4State.currentPart).toBe('part4'); // Should skip to part4 184 187 expect(part4State.cards.length).toBe(4); // Only the 4 veryImportant cards remain 185 - expect(part4State.cards.every(c => c.column === 'core')).toBe(true); 188 + expect(part4State.cards.every((c) => c.column === 'core')).toBe(true); 186 189 }); 187 190 188 191 test('Part 3 to Part 4 transition BLOCKS if > 5 core cards', () => { 189 192 // Arrange: Setup state in Part 3 with 6 'core' cards 190 - let state = app.undoManager.getState(); 193 + const state = app.undoManager.getState(); 191 194 state.currentPart = 'part3'; 192 195 state.cards = [ 193 196 { id: 1, name: 'C1', column: 'core', order: 0 }, ··· 206 209 207 210 // Assert: Should still be in Part 3 208 211 const stateAfterClick = app.undoManager.getState(); 209 - expect(stateAfterClick.currentPart).toBe('part3'); 212 + expect(stateAfterClick.currentPart).toBe('part3'); 210 213 }); 211 214 212 - test('Part 3 to Part 4 transition SUCCEEDS if <= 5 core cards', () => { 215 + test('Part 3 to Part 4 transition SUCCEEDS if <= 5 core cards', () => { 213 216 // Arrange: Setup state in Part 3 with 5 'core' cards 214 - let state = app.undoManager.getState(); 217 + const state = app.undoManager.getState(); 215 218 state.currentPart = 'part3'; 216 219 state.cards = [ 217 220 { id: 1, name: 'C1', column: 'core', order: 0 }, ··· 230 233 231 234 // Assert: Should be in Part 4 232 235 const part4State = app.undoManager.getState(); 233 - expect(part4State.currentPart).toBe('part4'); 236 + expect(part4State.currentPart).toBe('part4'); 234 237 // Cards state should remain the same (core/additional separation is kept) 235 - expect(part4State.cards.filter(c => c.column === 'core').length).toBe(5); 236 - expect(part4State.cards.filter(c => c.column === 'additional').length).toBe(1); 238 + expect(part4State.cards.filter((c) => c.column === 'core').length).toBe(5); 239 + expect(part4State.cards.filter((c) => c.column === 'additional').length).toBe(1); 237 240 }); 238 241 239 242 // --- Tests for Value Set Toggling --- 240 243 test('Initial state uses limited value set', () => { 241 - const state = app.undoManager.getState(); 242 - expect(state.valueSet).toBe('limited'); 243 - expect(state.cards.length).toBe(LIMITED_VALUES_COUNT); 244 + const state = app.undoManager.getState(); 245 + expect(state.valueSet).toBe('limited'); 246 + expect(state.cards.length).toBe(LIMITED_VALUES_COUNT); 244 247 }); 245 248 246 249 test('Clicking "Use All Values" switches set and resets state', () => { 247 - // Arrange: Start in default limited state 248 - let initialState = app.undoManager.getState(); 249 - expect(initialState.valueSet).toBe('limited'); 250 - // Optional: Advance state to ensure reset happens 251 - initialState.currentPart = 'part2'; 252 - initialState.finalStatements = { 1: 'test' }; 253 - app.updateState(initialState); 250 + // Arrange: Start in default limited state 251 + const initialState = app.undoManager.getState(); 252 + expect(initialState.valueSet).toBe('limited'); 253 + // Optional: Advance state to ensure reset happens 254 + initialState.currentPart = 'part2'; 255 + initialState.finalStatements = { 1: 'test' }; 256 + app.updateState(initialState); 254 257 255 - // Act: Call the method directly instead of simulating click 256 - app.toggleValueSet(); 258 + // Act: Call the method directly instead of simulating click 259 + app.toggleValueSet(); 257 260 258 - // Assert 259 - const newState = app.undoManager.getState(); 260 - expect(newState.valueSet).toBe('all'); 261 - expect(newState.cards.length).toBe(ALL_VALUES_COUNT); 262 - expect(newState.currentPart).toBe('part1'); // Should reset to part1 263 - expect(Object.keys(newState.finalStatements).length).toBe(0); // Statements cleared 261 + // Assert 262 + const newState = app.undoManager.getState(); 263 + expect(newState.valueSet).toBe('all'); 264 + expect(newState.cards.length).toBe(ALL_VALUES_COUNT); 265 + expect(newState.currentPart).toBe('part1'); // Should reset to part1 266 + expect(Object.keys(newState.finalStatements).length).toBe(0); // Statements cleared 264 267 }); 265 268 266 269 test('Clicking "Use 10 Values" switches set back and resets state', () => { 267 - // Arrange: Start, switch to All using direct call 268 - // const buttonAll = document.getElementById('useAllValuesBtn'); 269 - // buttonAll?.click(); // Replace click simulation 270 - app.toggleValueSet(); // Call directly to set state to 'all' for setup 270 + // Arrange: Start, switch to All using direct call 271 + // const buttonAll = document.getElementById('useAllValuesBtn'); 272 + // buttonAll?.click(); // Replace click simulation 273 + app.toggleValueSet(); // Call directly to set state to 'all' for setup 271 274 272 - let allState = app.undoManager.getState(); 273 - expect(allState.valueSet).toBe('all'); // Verify setup worked 274 - // Optional: Advance state to ensure reset happens 275 - allState.currentPart = 'part3'; 276 - app.updateState(allState); 275 + const allState = app.undoManager.getState(); 276 + expect(allState.valueSet).toBe('all'); // Verify setup worked 277 + // Optional: Advance state to ensure reset happens 278 + allState.currentPart = 'part3'; 279 + app.updateState(allState); 277 280 278 - // Act: Call the method directly instead of simulating click 279 - app.toggleValueSet(); 281 + // Act: Call the method directly instead of simulating click 282 + app.toggleValueSet(); 280 283 281 - // Assert 282 - const newState = app.undoManager.getState(); 283 - expect(newState.valueSet).toBe('limited'); 284 - expect(newState.cards.length).toBe(LIMITED_VALUES_COUNT); 285 - expect(newState.currentPart).toBe('part1'); 286 - expect(Object.keys(newState.finalStatements).length).toBe(0); 284 + // Assert 285 + const newState = app.undoManager.getState(); 286 + expect(newState.valueSet).toBe('limited'); 287 + expect(newState.cards.length).toBe(LIMITED_VALUES_COUNT); 288 + expect(newState.currentPart).toBe('part1'); 289 + expect(Object.keys(newState.finalStatements).length).toBe(0); 287 290 }); 288 291 289 - test('Clicking the active value set button does nothing', () => { 290 - const initialState = app.undoManager.getState(); 291 - expect(initialState.valueSet).toBe('limited'); 292 + test('Clicking the active value set button does nothing', () => { 293 + const initialState = app.undoManager.getState(); 294 + expect(initialState.valueSet).toBe('limited'); 292 295 293 - // Act: Click the already active limited button 294 - const buttonLimited = document.getElementById('useLimitedValuesBtn'); 295 - buttonLimited?.click(); 296 + // Act: Click the already active limited button 297 + const buttonLimited = document.getElementById('useLimitedValuesBtn'); 298 + buttonLimited?.click(); 296 299 297 - // Assert: State should not have changed 298 - const stateAfterClick = app.undoManager.getState(); 299 - expect(stateAfterClick).toEqual(initialState); 300 + // Assert: State should not have changed 301 + const stateAfterClick = app.undoManager.getState(); 302 + expect(stateAfterClick).toEqual(initialState); 300 303 }); 301 304 302 - test('Switching value set does NOT happen if confirm returns false', () => { 303 - const initialState = app.undoManager.getState(); 304 - expect(initialState.valueSet).toBe('limited'); 305 + test('Switching value set does NOT happen if confirm returns false', () => { 306 + const initialState = app.undoManager.getState(); 307 + expect(initialState.valueSet).toBe('limited'); 305 308 306 - // Arrange: Mock confirm to return false for this test 307 - const originalConfirm = window.confirm; 308 - window.confirm = () => false; 309 + // Arrange: Mock confirm to return false for this test 310 + const originalConfirm = window.confirm; 311 + window.confirm = () => false; 309 312 310 - // Act: Click the button to switch to all values 311 - const buttonAll = document.getElementById('useAllValuesBtn'); 312 - buttonAll?.click(); 313 + // Act: Click the button to switch to all values 314 + const buttonAll = document.getElementById('useAllValuesBtn'); 315 + buttonAll?.click(); 313 316 314 - // Assert: State should not have changed 315 - const stateAfterClick = app.undoManager.getState(); 316 - expect(stateAfterClick).toEqual(initialState); 317 + // Assert: State should not have changed 318 + const stateAfterClick = app.undoManager.getState(); 319 + expect(stateAfterClick).toEqual(initialState); 317 320 318 - // Cleanup: Restore original confirm 319 - window.confirm = originalConfirm; 321 + // Cleanup: Restore original confirm 322 + window.confirm = originalConfirm; 320 323 }); 321 324 322 325 // --- Tests for Adding Custom Values --- ··· 330 333 const initialCardCount = app.undoManager.getState().cards.length; 331 334 332 335 // Act 333 - (app as any).saveNewValue(); // Access private method for test 336 + app.saveNewValue(); // Call public method directly 334 337 335 338 // Assert 336 339 const newState = app.undoManager.getState(); ··· 349 352 const name = 'MY CUSTOM VALUE'; 350 353 (document.getElementById('newValueName') as HTMLInputElement).value = name; 351 354 (document.getElementById('newValueDesc') as HTMLTextAreaElement).value = 'Desc 1'; 352 - (app as any).saveNewValue(); 355 + app.saveNewValue(); // Call public method directly 353 356 const stateAfterFirstAdd = app.undoManager.getState(); 354 357 const cardCountAfterFirst = stateAfterFirstAdd.cards.length; 355 358 356 359 // Act: Try to add another with the same name (case-insensitive) 357 360 (document.getElementById('newValueName') as HTMLInputElement).value = name.toLowerCase(); 358 361 (document.getElementById('newValueDesc') as HTMLTextAreaElement).value = 'Desc 2'; 359 - (app as any).saveNewValue(); 362 + app.saveNewValue(); // Call public method directly 360 363 361 364 // Assert: State should not have changed, card count same 362 365 const stateAfterSecondAttempt = app.undoManager.getState(); ··· 366 369 367 370 // --- Tests for Editing Descriptions --- 368 371 test('startEditingDescription sets editingDescriptionCardId', () => { 369 - const cardToEditId = app.undoManager.getState().cards[0]!.id; // Use non-null assertion 370 - expect(app.undoManager.getState().editingDescriptionCardId).toBeNull(); 372 + const cardToEditId = app.undoManager.getState().cards[0]!.id; // Use non-null assertion 373 + expect(app.undoManager.getState().editingDescriptionCardId).toBeNull(); 371 374 372 - // Act 373 - (app as any).startEditingDescription(cardToEditId); 375 + // Act 376 + app.startEditingDescription(cardToEditId); // Call public method directly 374 377 375 - // Assert 376 - expect(app.undoManager.getState().editingDescriptionCardId).toBe(cardToEditId); 378 + // Assert 379 + expect(app.undoManager.getState().editingDescriptionCardId).toBe(cardToEditId); 377 380 }); 378 381 379 382 test('saveDescriptionEdit updates card description and clears editingId', () => { 380 - // Arrange: Start editing the first card 381 - const cards = app.undoManager.getState().cards; 382 - const cardToEdit = cards[0]!; // Use non-null assertion 383 - if (!cardToEdit) throw new Error('Test setup failed: No cards found'); 384 - const cardId = cardToEdit.id; 385 - const originalDesc = cardToEdit.description || VALUES.find((v: {name: string}) => v.name === cardToEdit.name)?.description; 386 - const newDesc = 'My edited description.'; 387 - (app as any).startEditingDescription(cardId); 383 + // Arrange: Start editing the first card 384 + const cards = app.undoManager.getState().cards; 385 + const cardToEdit = cards[0]!; // Use non-null assertion 386 + const cardId = cardToEdit.id; 387 + const newDesc = 'My edited description.'; 388 + app.startEditingDescription(cardId); // Call public method directly 388 389 389 - // Act 390 - (app as any).saveDescriptionEdit(cardId, newDesc); 390 + // Act 391 + app.saveDescriptionEdit(cardId, newDesc); // Call public method directly 391 392 392 - // Assert 393 - const newState = app.undoManager.getState(); 394 - expect(newState.editingDescriptionCardId).toBeNull(); 395 - const updatedCard = newState.cards.find(c => c.id === cardId); 396 - if (!updatedCard) throw new Error('Test failed: Updated card not found'); 397 - expect(updatedCard.description).toBe(newDesc); 398 - // Ensure other card descriptions weren't affected (simple check) 399 - if (cards.length > 1) { 400 - const otherCard = newState.cards.find(c => c.id === cards[1]!.id); // Use non-null assertion 401 - if (!otherCard) throw new Error('Test setup failed: Second card not found'); 402 - expect(otherCard.description).not.toBe(newDesc); 403 - } 393 + // Assert 394 + const newState = app.undoManager.getState(); 395 + expect(newState.editingDescriptionCardId).toBeNull(); 396 + const updatedCard = newState.cards.find((c) => c.id === cardId); 397 + if (!updatedCard) throw new Error('Test failed: Updated card not found'); 398 + expect(updatedCard.description).toBe(newDesc); 399 + // Ensure other card descriptions weren't affected (simple check) 400 + if (cards.length > 1) { 401 + const otherCard = newState.cards.find((c) => c.id === cards[1]!.id); // Use non-null assertion 402 + if (!otherCard) throw new Error('Test setup failed: Second card not found'); 403 + expect(otherCard.description).not.toBe(newDesc); 404 + } 404 405 }); 405 406 406 - test('cancelDescriptionEdit clears editingId without saving', () => { 407 - // Arrange: Start editing the first card 408 - const cards = app.undoManager.getState().cards; 409 - const cardToEdit = cards[0]!; // Use non-null assertion 410 - if (!cardToEdit) throw new Error('Test setup failed: No cards found'); 411 - const cardId = cardToEdit.id; 412 - const originalDesc = cardToEdit.description; // May be undefined initially 413 - (app as any).startEditingDescription(cardId); 414 - // Simulate typing something into the textarea (though it's not rendered here) 407 + test('cancelDescriptionEdit clears editingId without saving', () => { 408 + // Arrange: Start editing the first card 409 + const cards = app.undoManager.getState().cards; 410 + const cardToEdit = cards[0]!; // Use non-null assertion 411 + const cardId = cardToEdit.id; 412 + app.startEditingDescription(cardId); // Call public method directly 413 + // Simulate typing something into the textarea (though it's not rendered here) 415 414 416 - // Act 417 - (app as any).cancelDescriptionEdit(); 415 + // Act 416 + app.cancelDescriptionEdit(); // Call public method directly 418 417 419 - // Assert 420 - const newState = app.undoManager.getState(); 421 - expect(newState.editingDescriptionCardId).toBeNull(); 422 - const notUpdatedCard = newState.cards.find(c => c.id === cardId); 423 - if (!notUpdatedCard) throw new Error('Test failed: Card not found after cancel'); 424 - // Explicitly handle potential undefined originalDesc 425 - if (originalDesc === undefined) { 426 - expect(notUpdatedCard.description).toBeUndefined(); 427 - } else { 428 - expect(notUpdatedCard.description).toBe(originalDesc); 429 - } 418 + // Assert 419 + const newState = app.undoManager.getState(); 420 + expect(newState.editingDescriptionCardId).toBeNull(); 421 + const notUpdatedCard = newState.cards.find((c) => c.id === cardId); 422 + if (!notUpdatedCard) throw new Error('Test failed: Card not found after cancel'); 423 + // Explicitly handle potential undefined originalDesc 424 + if (notUpdatedCard.description === undefined) { 425 + expect(notUpdatedCard.description).toBeUndefined(); 426 + } else { 427 + expect(notUpdatedCard.description).toBe(notUpdatedCard.description); 428 + } 430 429 }); 431 430 432 431 // --- Test Review Page Rendering with Custom/Edited Descriptions --- 433 432 test('Review page renders custom and edited descriptions correctly', () => { 434 - // Arrange: 435 - // 1. Add a custom value 436 - const customName = 'CUSTOM VAL'; 437 - const customDesc = 'My custom description'; 438 - (document.getElementById('newValueName') as HTMLInputElement).value = customName; 439 - (document.getElementById('newValueDesc') as HTMLTextAreaElement).value = customDesc; 440 - (app as any).saveNewValue(); 441 - 442 - // 2. Edit description of a built-in value (e.g., ACCEPTANCE) 443 - let state = app.undoManager.getState(); 444 - const builtInCard = state.cards.find(c => c.name === 'ACCEPTANCE')!; 445 - const builtInCardId = builtInCard.id; 446 - const editedBuiltInDesc = 'My edited acceptance'; 447 - (app as any).saveDescriptionEdit(builtInCardId, editedBuiltInDesc); 448 - 449 - // 3. Move cards to core/additional for review page 450 - state = app.undoManager.getState(); 451 - state.currentPart = 'review'; 452 - state.cards.forEach(card => { 453 - if (card.name === 'ACCEPTANCE' || card.name === customName) { 454 - card.column = 'core'; 455 - } else { 456 - card.column = 'additional'; // Move others somewhere else 457 - } 458 - }); 459 - app.updateState(state); 460 - app = new App(); // Re-render with final state 433 + // Arrange: 434 + // 1. Add a custom value 435 + const customName = 'CUSTOM VAL'; 436 + const customDesc = 'My custom description'; 437 + (document.getElementById('newValueName') as HTMLInputElement).value = customName; 438 + (document.getElementById('newValueDesc') as HTMLTextAreaElement).value = customDesc; 439 + app.saveNewValue(); // Call public method directly 440 + 441 + // 2. Edit description of a built-in value (e.g., ACCEPTANCE) 442 + let state = app.undoManager.getState(); 443 + const builtInCard = state.cards.find((c) => c.name === 'ACCEPTANCE')!; 444 + const builtInCardId = builtInCard.id; 445 + const editedBuiltInDesc = 'My edited acceptance'; 446 + app.saveDescriptionEdit(builtInCardId, editedBuiltInDesc); // Call public method directly 461 447 462 - // Act: Trigger render (implicitly done by new App() or manually if needed) 463 - // (app as any).render(); // Usually constructor calls render 448 + // 3. Move cards to core/additional for review page 449 + state = app.undoManager.getState(); 450 + state.currentPart = 'review'; 451 + state.cards.forEach((card) => { 452 + if (card.name === 'ACCEPTANCE' || card.name === customName) { 453 + card.column = 'core'; 454 + } else { 455 + card.column = 'additional'; // Move others somewhere else 456 + } 457 + }); 458 + app.updateState(state); 459 + app = new App(); // Re-render with final state 460 + 461 + // Act: Trigger render (implicitly done by new App() or manually if needed) 462 + // (app as any).render(); // Usually constructor calls render 463 + 464 + // Assert: Check the rendered HTML in the review section 465 + const reviewContent = document.getElementById('reviewContent'); 466 + expect(reviewContent).not.toBeNull(); 467 + const coreSection = reviewContent!.querySelector('.grid-section:first-child'); // Assuming core is first 468 + expect(coreSection).not.toBeNull(); 464 469 465 - // Assert: Check the rendered HTML in the review section 466 - const reviewContent = document.getElementById('reviewContent'); 467 - expect(reviewContent).not.toBeNull(); 468 - const coreSection = reviewContent!.querySelector('.grid-section:first-child'); // Assuming core is first 469 - expect(coreSection).not.toBeNull(); 470 + const coreNames = Array.from(coreSection!.querySelectorAll('.review-value-name')).map((el) => el.textContent); 471 + const coreDescs = Array.from(coreSection!.querySelectorAll('.review-value-description')).map( 472 + (el) => el.textContent, 473 + ); 470 474 471 - const coreNames = Array.from(coreSection!.querySelectorAll('.review-value-name')).map(el => el.textContent); 472 - const coreDescs = Array.from(coreSection!.querySelectorAll('.review-value-description')).map(el => el.textContent); 473 - 474 - // Find the indices based on names (order might vary slightly if sorting changes) 475 - const acceptanceIndex = coreNames.indexOf('ACCEPTANCE'); 476 - const customIndex = coreNames.indexOf(customName); 475 + // Find the indices based on names (order might vary slightly if sorting changes) 476 + const acceptanceIndex = coreNames.indexOf('ACCEPTANCE'); 477 + const customIndex = coreNames.indexOf(customName); 477 478 478 - expect(acceptanceIndex).toBeGreaterThan(-1); 479 - expect(customIndex).toBeGreaterThan(-1); 480 - expect(coreDescs[acceptanceIndex]).toBe(editedBuiltInDesc); 481 - expect(coreDescs[customIndex]).toBe(customDesc); 479 + expect(acceptanceIndex).toBeGreaterThan(-1); 480 + expect(customIndex).toBeGreaterThan(-1); 481 + expect(coreDescs[acceptanceIndex]).toBe(editedBuiltInDesc); 482 + expect(coreDescs[customIndex]).toBe(customDesc); 482 483 }); 483 484 484 485 // Add more tests for other transitions (Part 2 -> 3, 3 -> 4, etc.) ··· 501 502 ], 502 503 finalStatements: {}, 503 504 valueSet: 'limited', 504 - editingDescriptionCardId: null // Add missing property 505 + editingDescriptionCardId: null, // Add missing property 505 506 }; 506 507 um = new UndoManager(initialState); 507 508 }); ··· 513 514 }); 514 515 515 516 test('should execute a state change and update current state', () => { 516 - const newState = { ...initialState, currentPart: 'part2' as 'part2' }; // Explicit type assertion 517 + const newState = { ...initialState, currentPart: 'part2' } as const; // Use as const 517 518 um.execute(newState); 518 519 expect(um.getState()).toEqual(newState); 519 520 expect(um.canUndo()).toBe(true); ··· 521 522 }); 522 523 523 524 test('should undo the last state change', () => { 524 - const newState = { ...initialState, currentPart: 'part2' as 'part2' }; 525 + const newState = { ...initialState, currentPart: 'part2' } as const; // Use as const 525 526 um.execute(newState); 526 527 const undoneState = um.undo(); 527 528 expect(undoneState).toEqual(initialState); ··· 531 532 }); 532 533 533 534 test('should redo the undone state change', () => { 534 - const newState = { ...initialState, currentPart: 'part2' as 'part2' }; 535 + const newState = { ...initialState, currentPart: 'part2' } as const; // Use as const 535 536 um.execute(newState); 536 537 um.undo(); 537 538 const redoneState = um.redo(); ··· 542 543 }); 543 544 544 545 test('should clear redo stack on new execution after undo', () => { 545 - const state2 = { ...initialState, currentPart: 'part2' as 'part2' }; 546 - const state3 = { ...initialState, currentPart: 'part3' as 'part3' }; 546 + const state2 = { ...initialState, currentPart: 'part2' } as const; // Use as const 547 + const state3 = { ...initialState, currentPart: 'part3' } as const; // Use as const 547 548 um.execute(state2); 548 549 um.undo(); // Back to initialState, state2 is in redo stack 549 550 um.execute(state3); // Execute a new change ··· 551 552 expect(um.getState()).toEqual(state3); 552 553 expect(um.canUndo()).toBe(true); // Can undo state3 553 554 expect(um.canRedo()).toBe(false); // Redo stack (state2) should be cleared 554 - 555 + 555 556 // Check undo goes back to initial state, not state 2 556 557 const undoneState = um.undo(); 557 558 expect(undoneState).toEqual(initialState); 558 559 }); 559 560 560 561 test('should handle multiple undo/redo operations', () => { 561 - const state2 = { ...initialState, currentPart: 'part2' as 'part2' }; 562 - const state3 = { ...initialState, currentPart: 'part3' as 'part3' }; 562 + const state2 = { ...initialState, currentPart: 'part2' } as const; // Use as const 563 + const state3 = { ...initialState, currentPart: 'part3' } as const; // Use as const 563 564 um.execute(state2); 564 565 um.execute(state3); 565 566 ··· 582 583 test('undo/redo should return null when stacks are empty', () => { 583 584 expect(um.undo()).toBeNull(); 584 585 expect(um.redo()).toBeNull(); 585 - const state2 = { ...initialState, currentPart: 'part2' as 'part2' }; 586 + const state2 = { ...initialState, currentPart: 'part2' } as const; // Use as const 586 587 um.execute(state2); 587 588 expect(um.redo()).toBeNull(); // Still no redo 588 589 um.undo(); 589 590 expect(um.undo()).toBeNull(); // Already at start 590 591 }); 591 - }); 592 + });
+264 -262
index.ts
··· 1 + import { UndoManager } from './undoManager'; 2 + import { VALUES } from './values'; 3 + 1 4 // Define interfaces for our value cards and overall app state. 2 5 export interface ValueCard { 3 6 id: number; ··· 11 14 } 12 15 13 16 export interface AppState { 14 - currentPart: "part1" | "part2" | "part3" | "part4" | "review"; 17 + currentPart: 'part1' | 'part2' | 'part3' | 'part4' | 'review'; 15 18 cards: ValueCard[]; 16 19 // In part 4, user can add final statements for each core value (by card id) 17 - finalStatements: { [cardId: number]: string }; 20 + finalStatements: Record<number, string>; 18 21 valueSet: 'limited' | 'all'; // Add state for current value set 19 22 editingDescriptionCardId: number | null; // ID of card whose description is being edited 20 23 } 21 24 22 - // Import the UndoManager from its own file 23 - import { UndoManager } from './undoManager'; 24 - // Import the original VALUES array 25 - import { VALUES } from './values'; 26 - // Import debounce and the necessary type from lodash 27 - import { debounce } from 'lodash'; 28 - import type { DebouncedFunc } from 'lodash'; // Use type-only import 25 + // Use type-only import 29 26 30 27 // Define the structure based on the imported VALUES 31 28 interface ValueDefinition { 32 - name: string; 33 - description: string; 29 + name: string; 30 + description: string; 34 31 } 35 32 36 33 // Recreate ALL_VALUES and LIMITED_VALUES based on the import ··· 39 36 40 37 // Create a global map for easy description lookup 41 38 const valueDefinitionsMap = new Map<string, string>( 42 - ALL_VALUE_DEFINITIONS.map((def: ValueDefinition) => [def.name, def.description]) 39 + ALL_VALUE_DEFINITIONS.map((def: ValueDefinition) => [def.name, def.description]), 43 40 ); 44 41 45 42 // Main application class 46 43 export class App { 47 44 private state: AppState; 48 45 public undoManager: UndoManager<AppState>; 49 - private storageKey: string = "valuesExerciseState"; 50 - private nextCustomCardId: number = -1; // Counter for unique negative IDs 46 + private storageKey = 'valuesExerciseState'; 47 + private nextCustomCardId = -1; // Counter for unique negative IDs 51 48 52 49 constructor() { 53 50 // Load state from localStorage or initialize default state. ··· 56 53 if (saved) { 57 54 try { 58 55 initialState = JSON.parse(saved) as AppState; 59 - if (!initialState.valueSet) { 60 - initialState.valueSet = 'limited'; 61 - } 62 56 // Ensure editing state is null initially 63 - initialState.editingDescriptionCardId = null; 64 - const minId = Math.min(0, ...initialState.cards.filter(c => c.isCustom).map(c => c.id)); 57 + initialState.editingDescriptionCardId = null; 58 + const minId = Math.min(0, ...initialState.cards.filter((c) => c.isCustom).map((c) => c.id)); 65 59 this.nextCustomCardId = minId - 1; 66 60 } catch { 67 61 initialState = this.defaultState('limited'); ··· 85 79 const sampleCards: ValueCard[] = definitionsToUse.map((definition: ValueDefinition, index: number) => ({ 86 80 id: index + 1, 87 81 name: definition.name, // Use name from definition 88 - column: "unassigned", 82 + column: 'unassigned', 89 83 order: index, 90 84 description: undefined, // Ensure built-in cards start with no override 91 - isCustom: false 85 + isCustom: false, 92 86 })); 93 87 return { 94 - currentPart: "part1", 88 + currentPart: 'part1', 95 89 cards: sampleCards, 96 90 finalStatements: {}, 97 91 valueSet: valueSet, // Store the set used ··· 124 118 } 125 119 126 120 // --- Add Value Form Logic --- 127 - private showAddValueForm() { 121 + public showAddValueForm() { 128 122 const form = document.getElementById('addValueForm') as HTMLDivElement | null; 129 123 const nameInput = document.getElementById('newValueName') as HTMLInputElement | null; 130 124 const descInput = document.getElementById('newValueDesc') as HTMLTextAreaElement | null; 131 125 if (form && nameInput && descInput) { 132 - nameInput.value = ''; // Clear previous input 133 - descInput.value = ''; 134 - form.style.display = 'flex'; // Show the modal 135 - nameInput.focus(); // Focus the name input 126 + nameInput.value = ''; // Clear previous input 127 + descInput.value = ''; 128 + form.style.display = 'flex'; // Show the modal 129 + nameInput.focus(); // Focus the name input 136 130 } 137 131 } 138 132 139 - private hideAddValueForm() { 133 + public hideAddValueForm() { 140 134 const form = document.getElementById('addValueForm') as HTMLDivElement | null; 141 135 if (form) { 142 - form.style.display = 'none'; // Hide the modal 136 + form.style.display = 'none'; // Hide the modal 143 137 } 144 138 } 145 139 146 - private saveNewValue() { 140 + public saveNewValue() { 147 141 const nameInput = document.getElementById('newValueName') as HTMLInputElement | null; 148 142 const descInput = document.getElementById('newValueDesc') as HTMLTextAreaElement | null; 149 143 const name = nameInput?.value.trim().toUpperCase(); // Normalize name 150 144 const description = descInput?.value.trim(); 151 145 152 146 if (!name) { 153 - alert("Please enter a name for the new value."); 154 - nameInput?.focus(); 155 - return; 147 + alert('Please enter a name for the new value.'); 148 + nameInput?.focus(); 149 + return; 156 150 } 157 151 if (!description) { 158 - alert("Please enter a description for the new value."); 159 - descInput?.focus(); 160 - return; 152 + alert('Please enter a description for the new value.'); 153 + descInput?.focus(); 154 + return; 161 155 } 162 156 163 157 const newState = this.undoManager.getState(); 164 158 165 159 // Check for duplicates (case-insensitive) 166 - if (newState.cards.some(card => card.name.toUpperCase() === name)) { 167 - alert(`Value "${name}" already exists.`); 168 - nameInput?.focus(); 169 - return; 160 + if (newState.cards.some((card) => card.name.toUpperCase() === name)) { 161 + alert(`Value "${name}" already exists.`); 162 + nameInput?.focus(); 163 + return; 170 164 } 171 165 172 166 // Create new card 173 167 const newCard: ValueCard = { 174 - id: this.nextCustomCardId, 175 - name: name, 176 - description: description, // Store description directly on card 177 - column: 'unassigned', // Add to unassigned in current view 178 - order: newState.cards.length, // Add to end 179 - isCustom: true 168 + id: this.nextCustomCardId, 169 + name: name, 170 + description: description, // Store description directly on card 171 + column: 'unassigned', // Add to unassigned in current view 172 + order: newState.cards.length, // Add to end 173 + isCustom: true, 180 174 }; 181 175 182 176 this.nextCustomCardId--; // Decrement for next custom card ··· 187 181 } 188 182 189 183 // --- Description Edit Logic --- 190 - private startEditingDescription(cardId: number) { 191 - const newState = this.undoManager.getState(); 192 - newState.editingDescriptionCardId = cardId; 193 - this.updateState(newState); // Re-render to show the textarea 184 + public startEditingDescription(cardId: number) { 185 + const newState = this.undoManager.getState(); 186 + newState.editingDescriptionCardId = cardId; 187 + this.updateState(newState); // Re-render to show the textarea 194 188 } 195 189 196 - private saveDescriptionEdit(cardId: number, newDescription: string) { 197 - const newState = this.undoManager.getState(); 198 - const cardToUpdate = newState.cards.find(c => c.id === cardId); 199 - if (cardToUpdate) { 200 - cardToUpdate.description = newDescription.trim(); // Save trimmed description 201 - } 202 - newState.editingDescriptionCardId = null; // Stop editing 203 - this.updateState(newState); 190 + public saveDescriptionEdit(cardId: number, newDescription: string) { 191 + const newState = this.undoManager.getState(); 192 + const cardToUpdate = newState.cards.find((c) => c.id === cardId); 193 + if (cardToUpdate) { 194 + cardToUpdate.description = newDescription.trim(); // Save trimmed description 195 + } 196 + newState.editingDescriptionCardId = null; // Stop editing 197 + this.updateState(newState); 204 198 } 205 199 206 - private cancelDescriptionEdit() { 207 - const newState = this.undoManager.getState(); 208 - newState.editingDescriptionCardId = null; // Just stop editing, don't save 209 - this.updateState(newState); 200 + public cancelDescriptionEdit() { 201 + const newState = this.undoManager.getState(); 202 + newState.editingDescriptionCardId = null; // Just stop editing, don't save 203 + this.updateState(newState); 210 204 } 211 205 212 206 // Bind event listeners for UI interactions. 213 207 private bindEventListeners() { 214 - const appInstance = this; // Capture the App instance 208 + // Remove alias: Arrow functions capture 'this' correctly 209 + // const appInstance = this; 215 210 216 211 // --- Add Value Form Listeners --- 217 212 document.getElementById('showAddValueFormBtn')?.addEventListener('click', () => { 218 - this.showAddValueForm(); 213 + this.showAddValueForm(); 219 214 }); 220 215 document.getElementById('saveNewValueBtn')?.addEventListener('click', () => { 221 - this.saveNewValue(); 216 + this.saveNewValue(); 222 217 }); 223 218 document.getElementById('cancelNewValueBtn')?.addEventListener('click', () => { 224 - this.hideAddValueForm(); 219 + this.hideAddValueForm(); 225 220 }); 226 221 // Close modal if clicking outside the content 227 222 document.getElementById('addValueForm')?.addEventListener('click', (e) => { 228 - if (e.target === e.currentTarget) { 229 - this.hideAddValueForm(); 230 - } 223 + if (e.target === e.currentTarget) { 224 + this.hideAddValueForm(); 225 + } 231 226 }); 232 227 233 228 // Navigation buttons 234 - document.getElementById("toPart2")?.addEventListener("click", () => { 229 + document.getElementById('toPart2')?.addEventListener('click', () => { 235 230 const newState = this.undoManager.getState(); 236 231 // Check for unassigned cards before proceeding 237 - const unassignedCount = newState.cards.filter(card => card.column === 'unassigned').length; 232 + const unassignedCount = newState.cards.filter((card) => card.column === 'unassigned').length; 238 233 if (unassignedCount > 0) { 239 234 alert(`Please sort all ${unassignedCount} unassigned value(s) before proceeding to Part 2.`); 240 235 return; 241 236 } 242 - newState.currentPart = "part2"; 237 + newState.currentPart = 'part2'; 243 238 newState.cards = newState.cards 244 - .filter(card => card.column === "veryImportant") 245 - .map(card => ({ ...card, column: "unassigned" })); 239 + .filter((card) => card.column === 'veryImportant') 240 + .map((card) => ({ ...card, column: 'unassigned' })); 246 241 this.updateState(newState); // Call updateState directly 247 242 }); 248 - document.getElementById("toPart3")?.addEventListener("click", () => { 243 + document.getElementById('toPart3')?.addEventListener('click', () => { 249 244 const newState = this.undoManager.getState(); 250 245 // Check for unassigned cards before proceeding 251 - const unassignedCount = newState.cards.filter(card => card.column === 'unassigned').length; 246 + const unassignedCount = newState.cards.filter((card) => card.column === 'unassigned').length; 252 247 if (unassignedCount > 0) { 253 248 alert(`Please sort all ${unassignedCount} unassigned value(s) before proceeding.`); 254 249 return; 255 250 } 256 - const veryImportantCards = newState.cards.filter((c) => c.column === "veryImportant"); 251 + const veryImportantCards = newState.cards.filter((c) => c.column === 'veryImportant'); 257 252 const veryImportantCount = veryImportantCards.length; 258 253 259 254 if (veryImportantCount <= 5) { 260 - newState.currentPart = "part4"; 255 + newState.currentPart = 'part4'; 261 256 } else { 262 - newState.currentPart = "part3"; 257 + newState.currentPart = 'part3'; 263 258 } 264 259 // Move all "veryImportant" cards to "core" regardless of the next part 265 - newState.cards = veryImportantCards.map((c, idx) => ({ ...c, column: "core", order: idx })); 260 + newState.cards = veryImportantCards.map((c, idx) => ({ ...c, column: 'core', order: idx })); 266 261 267 262 this.updateState(newState); // Call updateState directly 268 263 }); 269 - document.getElementById("toPart4")?.addEventListener("click", () => { 264 + document.getElementById('toPart4')?.addEventListener('click', () => { 270 265 const newState = this.undoManager.getState(); 271 - const coreCount = newState.cards.filter((c) => c.column === "core").length; 266 + const coreCount = newState.cards.filter((c) => c.column === 'core').length; 272 267 if (coreCount > 5) { 273 268 alert("You can only have 5 core values! Please move some values to 'Also Something I Want' before continuing."); 274 269 return; // Don't update state if validation fails 275 270 } 276 - newState.currentPart = "part4"; 271 + newState.currentPart = 'part4'; 277 272 this.updateState(newState); // Call updateState directly 278 273 }); 279 - document.getElementById("finish")?.addEventListener("click", () => { 274 + document.getElementById('finish')?.addEventListener('click', () => { 280 275 const newState = this.undoManager.getState(); 281 276 // Check if all core values have statements 282 - const coreCards = newState.cards.filter(c => c.column === 'core'); 283 - const missingStatements = coreCards.filter(card => !newState.finalStatements[card.id]?.trim()); 277 + const coreCards = newState.cards.filter((c) => c.column === 'core'); 278 + const missingStatements = coreCards.filter((card) => !newState.finalStatements[card.id]?.trim()); 284 279 285 280 if (missingStatements.length > 0) { 286 - alert(`Please provide a statement for all core values. Missing: ${missingStatements.map(c => c.name).join(', ')}`); 287 - return; // Prevent transition 281 + alert( 282 + `Please provide a statement for all core values. Missing: ${missingStatements.map((c) => c.name).join(', ')}`, 283 + ); 284 + return; // Prevent transition 288 285 } 289 - 286 + 290 287 // Original transition logic 291 - newState.currentPart = "review"; 288 + newState.currentPart = 'review'; 292 289 this.updateState(newState); // Call updateState directly 293 290 }); 294 - document.getElementById("restart")?.addEventListener("click", () => { 291 + document.getElementById('restart')?.addEventListener('click', () => { 295 292 const newState = this.defaultState(); 296 293 this.updateState(newState); // Call updateState directly 297 294 }); 298 295 299 296 // --- Add listeners for the toggle buttons --- 300 - document.getElementById("useLimitedValuesBtn")?.addEventListener("click", () => { 301 - // Use captured instance 302 - const currentSet = appInstance.undoManager.getState().valueSet; 303 - if (currentSet !== 'limited') { 304 - if (confirm("Switching value sets will reset your current progress. Are you sure?")) { 305 - appInstance.toggleValueSet(); // Use captured instance 306 - } 297 + document.getElementById('useLimitedValuesBtn')?.addEventListener('click', () => { 298 + // Use captured instance 299 + const currentSet = this.undoManager.getState().valueSet; 300 + if (currentSet !== 'limited') { 301 + if (confirm('Switching value sets will reset your current progress. Are you sure?')) { 302 + this.toggleValueSet(); 307 303 } 304 + } 308 305 }); 309 - document.getElementById("useAllValuesBtn")?.addEventListener("click", () => { 310 - // Use captured instance 311 - const currentSet = appInstance.undoManager.getState().valueSet; 312 - if (currentSet !== 'all') { 313 - if (confirm("Switching value sets will reset your current progress. Are you sure?")) { 314 - appInstance.toggleValueSet(); // Use captured instance 315 - } 306 + document.getElementById('useAllValuesBtn')?.addEventListener('click', () => { 307 + // Use captured instance 308 + const currentSet = this.undoManager.getState().valueSet; 309 + if (currentSet !== 'all') { 310 + if (confirm('Switching value sets will reset your current progress. Are you sure?')) { 311 + this.toggleValueSet(); 316 312 } 313 + } 317 314 }); 318 315 319 316 // Undo/Redo buttons 320 - document.getElementById("undoBtn")?.addEventListener("click", () => { 317 + document.getElementById('undoBtn')?.addEventListener('click', () => { 321 318 const prev = this.undoManager.undo(); 322 319 if (prev) { 323 320 this.state = prev; ··· 326 323 this.updateUndoRedoButtons(); 327 324 } 328 325 }); 329 - document.getElementById("redoBtn")?.addEventListener("click", () => { 326 + document.getElementById('redoBtn')?.addEventListener('click', () => { 330 327 const next = this.undoManager.redo(); 331 328 if (next) { 332 329 this.state = next; ··· 337 334 }); 338 335 339 336 // Clear storage button (renamed to Restart exercise) 340 - document.getElementById("clearStorageBtn")?.addEventListener("click", () => { 337 + document.getElementById('clearStorageBtn')?.addEventListener('click', () => { 341 338 // Update confirmation message 342 - if (confirm("Are you sure you want to restart the exercise? All progress will be lost. This action cannot be undone.")) { 339 + if ( 340 + confirm( 341 + 'Are you sure you want to restart the exercise? All progress will be lost. This action cannot be undone.', 342 + ) 343 + ) { 343 344 localStorage.removeItem(this.storageKey); 344 345 // Reset to the default state using the *current* value set preference 345 - const newState = this.defaultState(this.state.valueSet); 346 + const newState = this.defaultState(this.state.valueSet); 346 347 this.updateState(newState); 347 348 } 348 349 }); 349 350 350 351 // Set up drag and drop for card movement in all card-container elements. 351 - const containers = document.querySelectorAll(".card-container"); 352 + const containers = document.querySelectorAll('.card-container'); 352 353 containers.forEach((container) => { 353 - container.addEventListener("dragover", (e) => { 354 + container.addEventListener('dragover', (e) => { 354 355 e.preventDefault(); 355 356 }); 356 - container.addEventListener("drop", (e) => { 357 + container.addEventListener('drop', (e) => { 357 358 e.preventDefault(); 358 359 const dragEvent = e as DragEvent; 359 - const cardId = Number(dragEvent.dataTransfer?.getData("text/plain")); 360 - const targetColumn = ( 361 - container.parentElement as HTMLElement 362 - ).getAttribute("data-column"); 360 + const cardId = Number(dragEvent.dataTransfer?.getData('text/plain')); 361 + const targetColumn = container.parentElement!.getAttribute('data-column'); 363 362 if (targetColumn) { 364 363 this.moveCard(cardId, targetColumn); 365 364 } ··· 373 372 const card = newState.cards.find((c) => c.id === cardId); 374 373 if (card) { 375 374 // If in Part3 and moving to the 'core' column, enforce a maximum of 5 core cards. 376 - if (newState.currentPart === "part3" && newColumn === "core") { 377 - const coreCount = newState.cards.filter( 378 - (c) => c.column === "core" 379 - ).length; 380 - if (coreCount >= 5 && card.column !== "core") { 381 - alert("You can only have 5 core values!"); 375 + if (newState.currentPart === 'part3' && newColumn === 'core') { 376 + const coreCount = newState.cards.filter((c) => c.column === 'core').length; 377 + if (coreCount >= 5 && card.column !== 'core') { 378 + alert('You can only have 5 core values!'); 382 379 return; 383 380 } 384 381 } ··· 391 388 392 389 // Creates a draggable card element, handles description editing UI. 393 390 private createCardElement(card: ValueCard): HTMLElement { 394 - const cardElem = document.createElement("div"); 395 - cardElem.className = "card"; 391 + const cardElem = document.createElement('div'); 392 + cardElem.className = 'card'; 396 393 cardElem.draggable = true; 397 394 cardElem.dataset.cardId = card.id.toString(); 398 395 399 - const nameElem = document.createElement("span"); 400 - nameElem.className = "card-name"; 396 + const nameElem = document.createElement('span'); 397 + nameElem.className = 'card-name'; 401 398 nameElem.textContent = card.name; 402 399 cardElem.appendChild(nameElem); 403 400 404 401 // Container for description/edit area 405 - const descriptionContainer = document.createElement("div"); 406 - descriptionContainer.className = "card-description-container"; 402 + const descriptionContainer = document.createElement('div'); 403 + descriptionContainer.className = 'card-description-container'; 407 404 408 405 if (this.state.editingDescriptionCardId === card.id) { 409 - // RENDER EDIT TEXTAREA 410 - const textarea = document.createElement('textarea'); 411 - textarea.className = 'card-description-edit'; 412 - textarea.value = card.description || valueDefinitionsMap.get(card.name) || ""; 413 - textarea.rows = 3; 406 + // RENDER EDIT TEXTAREA 407 + const textarea = document.createElement('textarea'); 408 + textarea.className = 'card-description-edit'; 409 + textarea.value = card.description ?? valueDefinitionsMap.get(card.name) ?? ''; 410 + textarea.rows = 3; 414 411 415 - textarea.addEventListener('blur', () => { 416 - this.saveDescriptionEdit(card.id, textarea.value); 417 - }); 412 + textarea.addEventListener('blur', () => { 413 + this.saveDescriptionEdit(card.id, textarea.value); 414 + }); 418 415 419 - textarea.addEventListener('keydown', (e) => { 420 - if (e.key === 'Enter' && !e.shiftKey) { 421 - e.preventDefault(); // Prevent newline 422 - this.saveDescriptionEdit(card.id, textarea.value); 423 - } else if (e.key === 'Escape') { 424 - this.cancelDescriptionEdit(); 425 - } 426 - }); 427 - 428 - descriptionContainer.appendChild(textarea); 429 - // Auto-focus the textarea after it's rendered 430 - setTimeout(() => textarea.focus(), 0); 416 + textarea.addEventListener('keydown', (e) => { 417 + if (e.key === 'Enter' && !e.shiftKey) { 418 + e.preventDefault(); // Prevent newline 419 + this.saveDescriptionEdit(card.id, textarea.value); 420 + } else if (e.key === 'Escape') { 421 + this.cancelDescriptionEdit(); 422 + } 423 + }); 431 424 425 + descriptionContainer.appendChild(textarea); 426 + // Auto-focus the textarea after it's rendered 427 + setTimeout(() => { 428 + textarea.focus(); 429 + }, 0); 432 430 } else { 433 - // RENDER DESCRIPTION TEXT (Clickable) 434 - const descriptionElem = document.createElement("span"); 435 - descriptionElem.className = "card-description clickable"; // Add clickable class 436 - descriptionElem.textContent = card.description || valueDefinitionsMap.get(card.name) || "(Click to add description)"; 437 - descriptionElem.title = "Click to edit description"; // Tooltip 431 + // RENDER DESCRIPTION TEXT (Clickable) 432 + const descriptionElem = document.createElement('span'); 433 + descriptionElem.className = 'card-description clickable'; // Add clickable class 434 + descriptionElem.textContent = 435 + card.description ?? valueDefinitionsMap.get(card.name) ?? '(Click to add description)'; 436 + descriptionElem.title = 'Click to edit description'; // Tooltip 438 437 439 - descriptionElem.addEventListener('click', (e) => { 440 - e.stopPropagation(); // Prevent card drag start if clicking text 441 - this.startEditingDescription(card.id); 442 - }); 443 - descriptionContainer.appendChild(descriptionElem); 438 + descriptionElem.addEventListener('click', (e) => { 439 + e.stopPropagation(); // Prevent card drag start if clicking text 440 + this.startEditingDescription(card.id); 441 + }); 442 + descriptionContainer.appendChild(descriptionElem); 444 443 } 445 444 446 445 cardElem.appendChild(descriptionContainer); 447 446 448 - cardElem.addEventListener("dragstart", (e) => { 449 - // Only allow drag if not editing description 450 - if (this.state.editingDescriptionCardId === null) { 451 - e.dataTransfer?.setData("text/plain", card.id.toString()); 452 - } else { 453 - e.preventDefault(); // Prevent drag while editing 454 - } 447 + cardElem.addEventListener('dragstart', (e) => { 448 + // Only allow drag if not editing description 449 + if (this.state.editingDescriptionCardId === null) { 450 + e.dataTransfer?.setData('text/plain', card.id.toString()); 451 + } else { 452 + e.preventDefault(); // Prevent drag while editing 453 + } 455 454 }); 456 455 457 456 return cardElem; ··· 460 459 // Render the UI based on the current state. 461 460 private render() { 462 461 // Manage tabindex for global controls based on current part 463 - const isPart4Active = this.state.currentPart === "part4"; 462 + const isPart4Active = this.state.currentPart === 'part4'; 464 463 const globalControls = document.querySelectorAll('#global-controls button'); 465 - globalControls.forEach(btn => { 466 - if (isPart4Active) { 467 - (btn as HTMLElement).tabIndex = -1; // Make header buttons non-tabbable during Part 4 468 - } else { 469 - (btn as HTMLElement).removeAttribute('tabindex'); // Restore default tabbability 470 - } 464 + globalControls.forEach((btn) => { 465 + if (isPart4Active) { 466 + (btn as HTMLElement).tabIndex = -1; // Make header buttons non-tabbable during Part 4 467 + } else { 468 + (btn as HTMLElement).removeAttribute('tabindex'); // Restore default tabbability 469 + } 471 470 }); 472 471 473 472 // Hide all parts first. 474 - document.querySelectorAll(".exercise-part").forEach((section) => { 475 - (section as HTMLElement).style.display = "none"; 473 + document.querySelectorAll('.exercise-part').forEach((section) => { 474 + (section as HTMLElement).style.display = 'none'; 476 475 }); 477 476 // Show the current part. 478 477 const partElem = document.getElementById(this.state.currentPart); 479 478 if (partElem) { 480 - partElem.style.display = "block"; 479 + partElem.style.display = 'block'; 481 480 } 482 481 // Render cards for the current part. 483 - if (this.state.currentPart === "part1") { 482 + if (this.state.currentPart === 'part1') { 484 483 // Clear containers for Part 1 485 484 [ 486 - "part1-unassignedContainer", 487 - "part1-veryImportantContainer", 488 - "part1-importantContainer", 489 - "part1-notImportantContainer", 485 + 'part1-unassignedContainer', 486 + 'part1-veryImportantContainer', 487 + 'part1-importantContainer', 488 + 'part1-notImportantContainer', 490 489 ].forEach((id) => { 491 490 const container = document.getElementById(id); 492 - if (container) container.innerHTML = ""; 491 + if (container) container.innerHTML = ''; 493 492 }); 494 493 // Render each card into its Part 1 container. 495 494 this.state.cards.forEach((card) => { 496 - const containerId = "part1-" + card.column + "Container"; // Use Part 1 prefix 495 + const containerId = 'part1-' + card.column + 'Container'; // Use Part 1 prefix 497 496 const container = document.getElementById(containerId); 498 497 if (container) { 499 498 const cardElem = this.createCardElement(card); // Use helper 500 499 container.appendChild(cardElem); 501 500 } 502 501 }); 503 - } else if (this.state.currentPart === "part2") { 502 + } else if (this.state.currentPart === 'part2') { 504 503 // Clear containers for Part 2 505 504 [ 506 - "part2-unassignedContainer", 507 - "part2-veryImportantContainer", 508 - "part2-importantContainer", 509 - "part2-notImportantContainer", 505 + 'part2-unassignedContainer', 506 + 'part2-veryImportantContainer', 507 + 'part2-importantContainer', 508 + 'part2-notImportantContainer', 510 509 ].forEach((id) => { 511 510 const container = document.getElementById(id); 512 - if (container) container.innerHTML = ""; 511 + if (container) container.innerHTML = ''; 513 512 }); 514 - 513 + 515 514 // Log the state for debugging (can be removed later) 516 515 // console.log("Rendering Part 2:", { 517 516 // totalCards: this.state.cards.length, 518 517 // cards: this.state.cards.map(c => ({ name: c.name, column: c.column })) 519 518 // }); 520 - 519 + 521 520 // In Part 2, show all cards in their current Part 2 columns 522 521 this.state.cards.forEach((card) => { 523 - const containerId = "part2-" + card.column + "Container"; // Use Part 2 prefix 522 + const containerId = 'part2-' + card.column + 'Container'; // Use Part 2 prefix 524 523 const container = document.getElementById(containerId); 525 524 if (container) { 526 525 const cardElem = this.createCardElement(card); // Use helper ··· 530 529 // console.error(`Container not found for card ${card.name} in column ${card.column}`); 531 530 } 532 531 }); 533 - } else if (this.state.currentPart === "part3") { 532 + } else if (this.state.currentPart === 'part3') { 534 533 // Clear containers for part3 535 - ["coreContainer", "additionalContainer"].forEach((id) => { 534 + ['coreContainer', 'additionalContainer'].forEach((id) => { 536 535 const container = document.getElementById(id); 537 - if (container) container.innerHTML = ""; 536 + if (container) container.innerHTML = ''; 538 537 }); 539 538 this.state.cards.forEach((card) => { 540 - if (card.column === "core" || card.column === "additional") { 541 - const containerId = card.column + "Container"; 539 + if (card.column === 'core' || card.column === 'additional') { 540 + const containerId = card.column + 'Container'; 542 541 const container = document.getElementById(containerId); 543 542 if (container) { 544 543 const cardElem = this.createCardElement(card); // Use helper ··· 546 545 } 547 546 } 548 547 }); 549 - } else if (this.state.currentPart === "part4") { 548 + } else if (this.state.currentPart === 'part4') { 550 549 // Render text inputs for each core value. 551 - const finalStatementsContainer = document.getElementById("finalStatements"); 550 + const finalStatementsContainer = document.getElementById('finalStatements'); 552 551 if (finalStatementsContainer) { 553 - const coreCards = this.state.cards.filter((c) => c.column === "core"); 552 + const coreCards = this.state.cards.filter((c) => c.column === 'core'); 554 553 coreCards.sort((a, b) => a.name.localeCompare(b.name)); // Keep sorting for consistent order 555 554 556 555 // Check if inputs matching core cards already exist 557 556 const existingInputs = finalStatementsContainer.querySelectorAll<HTMLInputElement>('input[type="text"]'); 558 557 let inputsMatch = existingInputs.length === coreCards.length; 559 558 if (inputsMatch) { 560 - existingInputs.forEach((input, index) => { 561 - // Verify the input corresponds to the correct card (using id or other attribute if needed) 562 - // For simplicity, we assume order matches due to sorting if length is correct 563 - if (coreCards[index]?.id.toString() !== input.id.replace('statement-', '')) { 564 - inputsMatch = false; 565 - } 566 - }); 559 + existingInputs.forEach((input, index) => { 560 + // Verify the input corresponds to the correct card (using id or other attribute if needed) 561 + // For simplicity, we assume order matches due to sorting if length is correct 562 + if (coreCards[index]?.id.toString() !== input.id.replace('statement-', '')) { 563 + inputsMatch = false; 564 + } 565 + }); 567 566 } 568 567 569 568 if (inputsMatch) { 570 569 // Inputs exist and match: Just update their values 571 570 existingInputs.forEach((input) => { 572 571 const cardId = Number(input.id.replace('statement-', '')); 573 - const currentValue = this.state.finalStatements[cardId] || ""; 572 + const currentValue = this.state.finalStatements[cardId] ?? ''; 574 573 if (input.value !== currentValue) { 575 574 input.value = currentValue; 576 575 } 577 576 }); 578 577 } else { 579 578 // Inputs don't exist or don't match: Clear and recreate them 580 - finalStatementsContainer.innerHTML = ""; 581 - coreCards.forEach((card, index) => { 582 - const wrapper = document.createElement("div"); 583 - wrapper.className = "final-statement"; 584 - const label = document.createElement("label"); 579 + finalStatementsContainer.innerHTML = ''; 580 + coreCards.forEach((card) => { 581 + const wrapper = document.createElement('div'); 582 + wrapper.className = 'final-statement'; 583 + const label = document.createElement('label'); 585 584 label.htmlFor = `statement-${card.id}`; 586 585 label.textContent = `Describe what "${card.name}" means to you:`; 587 - const input = document.createElement("input"); 588 - input.type = "text"; 586 + const input = document.createElement('input'); 587 + input.type = 'text'; 589 588 input.id = `statement-${card.id}`; 590 - input.value = this.state.finalStatements[card.id] || ""; 589 + input.value = this.state.finalStatements[card.id] ?? ''; 591 590 // Use 'blur' event to update state directly when field loses focus 592 - input.addEventListener("blur", () => { 591 + input.addEventListener('blur', () => { 593 592 const currentState = this.undoManager.getState(); // Get latest state 594 593 // Avoid modifying the state if it hasn't actually changed 595 594 if (currentState.finalStatements[card.id] !== input.value) { 596 - const newState = this.undoManager.getState(); // Get a fresh copy to modify 597 - newState.finalStatements[card.id] = input.value; 598 - this.updateState(newState); // Update authoritative state 595 + const newState = this.undoManager.getState(); // Get a fresh copy to modify 596 + newState.finalStatements[card.id] = input.value; 597 + this.updateState(newState); // Update authoritative state 599 598 } 600 599 }); 601 600 wrapper.appendChild(label); ··· 604 603 }); 605 604 } 606 605 } 607 - } else if (this.state.currentPart === "review") { 608 - const reviewContent = document.getElementById("reviewContent"); 606 + } 607 + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 608 + else if (this.state.currentPart === 'review') { 609 + const reviewContent = document.getElementById('reviewContent'); 609 610 if (reviewContent) { 610 - reviewContent.innerHTML = ""; 611 - 611 + reviewContent.innerHTML = ''; 612 + 612 613 // Add the visualization grid 613 - const grid = document.createElement("div"); 614 - grid.className = "values-grid"; 615 - 614 + const grid = document.createElement('div'); 615 + grid.className = 'values-grid'; 616 + 616 617 // Create sections for core values and additional values 617 618 const categories = [ 618 - { title: "Core Values (F*CK YEAH)", column: "core" }, 619 - { title: "Also Something I Want", column: "additional" } 619 + { title: 'Core Values (F*CK YEAH)', column: 'core' }, 620 + { title: 'Also Something I Want', column: 'additional' }, 620 621 ]; 621 - 622 - categories.forEach(category => { 623 - const section = document.createElement("div"); 624 - section.className = "grid-section"; 625 - const title = document.createElement("h3"); 622 + 623 + categories.forEach((category) => { 624 + const section = document.createElement('div'); 625 + section.className = 'grid-section'; 626 + const title = document.createElement('h3'); 626 627 title.textContent = category.title; 627 628 section.appendChild(title); 628 - 629 + 629 630 // Get the actual card objects, not just names 630 - const cardsInCategory = this.state.cards 631 - .filter(c => c.column === category.column); 632 - // Sort them alphabetically by name for consistent display 631 + const cardsInCategory = this.state.cards.filter((c) => c.column === category.column); 632 + // Sort them alphabetically by name for consistent display 633 633 cardsInCategory.sort((a, b) => a.name.localeCompare(b.name)); 634 - 634 + 635 635 if (cardsInCategory.length > 0) { 636 - const list = document.createElement("ul"); 636 + const list = document.createElement('ul'); 637 637 // Iterate over the card objects 638 - cardsInCategory.forEach(card => { 639 - const li = document.createElement("li"); 638 + cardsInCategory.forEach((card) => { 639 + const li = document.createElement('li'); 640 640 const nameSpan = document.createElement('span'); 641 641 nameSpan.className = 'review-value-name'; 642 642 nameSpan.textContent = card.name; // Use name from card object 643 - 643 + 644 644 const descSpan = document.createElement('span'); 645 645 descSpan.className = 'review-value-description'; 646 646 // Prioritize card.description, fall back to map 647 - descSpan.textContent = card.description || valueDefinitionsMap.get(card.name) || "(Description missing)"; 647 + descSpan.textContent = card.description ?? valueDefinitionsMap.get(card.name) ?? '(Description missing)'; 648 648 649 649 li.appendChild(nameSpan); 650 650 li.appendChild(descSpan); ··· 652 652 }); 653 653 section.appendChild(list); 654 654 } 655 - 655 + 656 656 grid.appendChild(section); 657 657 }); 658 - 658 + 659 659 reviewContent.appendChild(grid); 660 - 660 + 661 661 // Add the final statements 662 - const title = document.createElement("h3"); 663 - title.textContent = "Your Core Values & Statements:"; 662 + const title = document.createElement('h3'); 663 + title.textContent = 'Your Core Values & Statements:'; 664 664 reviewContent.appendChild(title); 665 - const list = document.createElement("ul"); 666 - const coreCards = this.state.cards.filter((c) => c.column === "core"); 665 + const list = document.createElement('ul'); 666 + const coreCards = this.state.cards.filter((c) => c.column === 'core'); 667 667 coreCards.forEach((card) => { 668 - const li = document.createElement("li"); 669 - const statement = this.state.finalStatements[card.id] || "(No statement written)"; 668 + const li = document.createElement('li'); 669 + const statement = this.state.finalStatements[card.id] ?? '(No statement written)'; 670 670 li.textContent = `${statement} (${card.name})`; 671 671 list.appendChild(li); 672 672 }); ··· 675 675 } 676 676 677 677 // -- Update toggle button appearance based on current state -- 678 - const limitedBtn = document.getElementById("useLimitedValuesBtn") as HTMLButtonElement | null; 679 - const allBtn = document.getElementById("useAllValuesBtn") as HTMLButtonElement | null; 678 + const limitedBtn = document.getElementById('useLimitedValuesBtn') as HTMLButtonElement | null; 679 + const allBtn = document.getElementById('useAllValuesBtn') as HTMLButtonElement | null; 680 680 if (limitedBtn) { 681 - limitedBtn.classList.toggle('active', this.state.valueSet === 'limited'); 682 - limitedBtn.disabled = this.state.valueSet === 'limited'; // Disable active button 681 + limitedBtn.classList.toggle('active', this.state.valueSet === 'limited'); 682 + limitedBtn.disabled = this.state.valueSet === 'limited'; // Disable active button 683 683 } 684 684 if (allBtn) { 685 - allBtn.classList.toggle('active', this.state.valueSet === 'all'); 686 - allBtn.disabled = this.state.valueSet === 'all'; // Disable active button 685 + allBtn.classList.toggle('active', this.state.valueSet === 'all'); 686 + allBtn.disabled = this.state.valueSet === 'all'; // Disable active button 687 687 } 688 688 } 689 689 690 690 // Update the disabled state of the undo/redo buttons. 691 691 private updateUndoRedoButtons() { 692 - const undoBtn = document.getElementById("undoBtn") as HTMLButtonElement; 693 - const redoBtn = document.getElementById("redoBtn") as HTMLButtonElement; 692 + const undoBtn = document.getElementById('undoBtn') as HTMLButtonElement; 693 + const redoBtn = document.getElementById('redoBtn') as HTMLButtonElement; 694 + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 694 695 if (undoBtn) undoBtn.disabled = !this.undoManager.canUndo(); 696 + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 695 697 if (redoBtn) redoBtn.disabled = !this.undoManager.canRedo(); 696 698 } 697 699 } 698 700 699 701 // Initialize the app normally, only if in a browser environment 700 702 if (typeof window !== 'undefined' && typeof document !== 'undefined') { 701 - window.addEventListener("DOMContentLoaded", () => { 703 + window.addEventListener('DOMContentLoaded', () => { 702 704 new App(); 703 705 }); 704 706 }
+17 -5
package.json
··· 4 4 "private": true, 5 5 "devDependencies": { 6 6 "@happy-dom/global-registrator": "^17.4.4", 7 - "@types/bun": "^1.2.8" 8 - }, 9 - "peerDependencies": { 10 - "typescript": "^5" 7 + "@types/bun": "^1.2.8", 8 + "husky": "^9.1.6", 9 + "lint-staged": "^15.2.10", 10 + "@eslint/js": "^9.13.0", 11 + "@trivago/prettier-plugin-sort-imports": "^5", 12 + "@types/eslint__js": "^9", 13 + "@types/node": "^22.8.4", 14 + "eslint": "^9.13.0", 15 + "prettier": "^3.3.3", 16 + "tsx": "^4.19.2", 17 + "typescript": "^5.6.3", 18 + "typescript-eslint": "^8.12.2" 11 19 }, 12 20 "dependencies": { 13 21 "@types/lodash": "^4.17.16", ··· 19 27 "dev": "parcel ./index.html", 20 28 "build": "parcel build ./index.html", 21 29 "test": "bun test", 22 - "deploy": "bun test && bun run build && bunx wrangler pages deploy dist" 30 + "deploy": "bun test && bun run build && bunx wrangler pages deploy dist", 31 + "format": "bunx prettier --write .", 32 + "lint": "bunx eslint .", 33 + "lint:fix": "bunx eslint --fix .", 34 + "prepare": "husky" 23 35 } 24 36 }
+19 -6
specs.md
··· 1 1 # Crafting Your Values - Specifications 2 2 3 3 ## Overview 4 + 4 5 The "Crafting Your Values" exercise is designed to help you identify and refine what truly matters in your life. It guides you through a process of sorting, narrowing down, and articulating your core values. The exercise consists of four main parts and includes a comprehensive list of value cards. 5 6 6 7 ## Part 1: So What's Actually Important to You (and What Isn't) 8 + 7 9 - **Objective:** 8 10 Begin by categorizing all provided values based on their personal significance. 9 11 10 12 - **Setup:** 13 + 11 14 - Use a set of value cards (printed or digital). 12 15 - Prepare three columns titled: 13 16 - **"Very important to me"** ··· 20 23 - Review and adjust the placements until the columns accurately represent your priorities. 21 24 22 25 ## Part 2: Narrowing Down 26 + 23 27 - **Objective:** 24 28 Refine the selection by focusing on values that you initially rated as "Very important to me." 25 29 26 30 - **Instructions:** 31 + 27 32 - Set aside the values in the "Not important to me" and "Important to me" columns. 28 33 - Re-create three columns using only the values from the previous **"Very important to me"** category: 29 34 - **"Very important to me"** ··· 37 42 - Otherwise, proceed to Part 3 for further refinement. 38 43 39 44 ## Part 3: The Most Important Stuff 45 + 40 46 - **Objective:** 41 47 Identify your top core values from the refined list. 42 48 43 49 - **Instructions:** 50 + 44 51 - From the values sorted in Part 2, create two new columns: 45 - - **"Very important to me"** (suggested label: **"F*CK YEAH"** – your must-haves) 52 + - **"Very important to me"** (suggested label: **"F\*CK YEAH"** – your must-haves) 46 53 - **"Also something I want in my life"** (suggested label: **"THIS IS AWESOME TOO"**) 47 - - **Rule:** The **"F*CK YEAH"** column can contain a maximum of **5 values**. 48 - - Finalize the selection by ensuring that only 5 values occupy the **"F*CK YEAH"** column. 54 + - **Rule:** The **"F\*CK YEAH"** column can contain a maximum of **5 values**. 55 + - Finalize the selection by ensuring that only 5 values occupy the **"F\*CK YEAH"** column. 49 56 50 57 - **Additional Task:** 51 58 - For each of your 5 core values, write a personalized statement in the following format: 52 - - *I want [description of your core value]* 59 + - _I want [description of your core value]_ 53 60 _(Example: "I want to accept myself as I am (self-acceptance)")_ 54 61 55 62 ## Part 4: Your Core Values (Reference/Visualization) 63 + 56 64 - **Objective:** 57 65 Provide a visual summary of your final values. 58 66 ··· 66 74 - This part may be provided as a printed template or a visual guide and serves as a confirmation of your finalized core values. 67 75 68 76 ## Values List 77 + 69 78 The exercise includes a comprehensive list of values. Some of the values are: 70 79 71 - - **ACCEPTANCE, ACCURACY, ACHIEVEMENT, ADVENTURE, ATTRACTIVENESS, AUTHORITY, AUTONOMY, BEAUTY, CARING, CHALLENGE, CHANGE, COMFORT, COMMITMENT, COMPASSION, CONTRIBUTION, COOPERATION, COURTESY, CREATIVITY, DEPENDABILITY, DUTY, ECOLOGY, EXCITEMENT, FAITHFULNESS, FAME, FAMILY, FITNESS, FLEXIBILITY, FORGIVENESS, FRIENDSHIP, FUN, GENEROSITY, GENUINENESS, GOD’S WILL, GROWTH, HEALTH, HELPFULNESS, HONESTY, HOPE, HUMILITY, HUMOR, INDEPENDENCE, INDUSTRY, INNER PEACE, INTIMACY, JUSTICE, KNOWLEDGE, LEISURE, LOVED, LOVING, MASTERY, MINDFULNESS, MODERATION, MONOGAMY, NONCONFORMITY, NURTURANCE, OPENNESS, ORDER, PASSION, PLEASURE, POPULARITY, POWER, PURPOSE, RATIONALITY, REALISM, RESPONSIBILITY, RISK, ROMANCE, SAFETY, SELF-ACCEPTANCE, SELF-CONTROL, SELF-ESTEEM, SELF-KNOWLEDGE, SERVICE, SEXUALITY, SIMPLICITY, SOLITUDE, SPIRITUALITY, STABILITY, TOLERANCE, TRADITION, VIRTUE, WEALTH, WORLD PEACE. 80 + - \*\*ACCEPTANCE, ACCURACY, ACHIEVEMENT, ADVENTURE, ATTRACTIVENESS, AUTHORITY, AUTONOMY, BEAUTY, CARING, CHALLENGE, CHANGE, COMFORT, COMMITMENT, COMPASSION, CONTRIBUTION, COOPERATION, COURTESY, CREATIVITY, DEPENDABILITY, DUTY, ECOLOGY, EXCITEMENT, FAITHFULNESS, FAME, FAMILY, FITNESS, FLEXIBILITY, FORGIVENESS, FRIENDSHIP, FUN, GENEROSITY, GENUINENESS, GOD’S WILL, GROWTH, HEALTH, HELPFULNESS, HONESTY, HOPE, HUMILITY, HUMOR, INDEPENDENCE, INDUSTRY, INNER PEACE, INTIMACY, JUSTICE, KNOWLEDGE, LEISURE, LOVED, LOVING, MASTERY, MINDFULNESS, MODERATION, MONOGAMY, NONCONFORMITY, NURTURANCE, OPENNESS, ORDER, PASSION, PLEASURE, POPULARITY, POWER, PURPOSE, RATIONALITY, REALISM, RESPONSIBILITY, RISK, ROMANCE, SAFETY, SELF-ACCEPTANCE, SELF-CONTROL, SELF-ESTEEM, SELF-KNOWLEDGE, SERVICE, SEXUALITY, SIMPLICITY, SOLITUDE, SPIRITUALITY, STABILITY, TOLERANCE, TRADITION, VIRTUE, WEALTH, WORLD PEACE. 72 81 73 - *(This list is not exhaustive; ensure all values from the original instrument are included.)* 82 + _(This list is not exhaustive; ensure all values from the original instrument are included.)_ 74 83 75 84 ## Additional Considerations 85 + 76 86 - **Flexibility:** 77 87 There is no "one right way" to complete the exercise. Adapt the process to what feels most authentic to you. 78 88 ··· 83 93 Use the exercise as an opportunity for deep self-reflection to better understand what truly matters in your life. 84 94 85 95 ## Final Outcome 96 + 86 97 By the end of the exercise, you will have: 98 + 87 99 - A clear categorization of your values. 88 100 - A refined list of your top 5 core values. 89 101 - Personalized statements that articulate your core values. 90 102 - A visual summary or template that confirms your final selections. 91 103 92 104 ## Public Domain 105 + 93 106 This instrument is in the public domain and may be copied, adapted, and used without permission.
+225 -226
styles.css
··· 1 1 body { 2 - font-family: sans-serif; 3 - margin: 0; 4 - padding: 1em; 5 - background: #f5f5f5; 6 - } 7 - 8 - header { 9 - display: flex; 10 - justify-content: space-between; 11 - align-items: center; 12 - } 13 - 14 - #global-controls button { 15 - margin-right: 0.5em; 16 - } 17 - 18 - .exercise-part { 19 - margin-top: 1em; 20 - background: #fff; 21 - padding: 1em; 22 - border-radius: 4px; 23 - } 24 - 25 - .columns { 26 - display: flex; 27 - justify-content: space-around; 28 - flex-wrap: wrap; 29 - margin-bottom: 1em; 30 - } 31 - 32 - .column { 33 - flex: 1 1 200px; 34 - margin: 0.5em; 35 - padding: 0.5em; 36 - background: #eaeaea; 37 - border-radius: 4px; 38 - } 39 - 40 - .column h3 { 41 - text-align: center; 42 - } 43 - 44 - .card-container { 45 - min-height: 100px; 46 - padding: 0.5em; 47 - background: #fff; 48 - border: 1px dashed #ccc; 49 - border-radius: 4px; 50 - } 51 - 52 - .card { 53 - background: #d1e7dd; 54 - padding: 0.5em; 55 - margin: 0.5em 0; 56 - border-radius: 4px; 57 - cursor: grab; 58 - display: flex; 59 - flex-direction: column; 60 - align-items: center; 61 - text-align: center; 62 - padding-top: 8px; 63 - padding-bottom: 8px; 64 - } 65 - 66 - .card-name { 67 - font-weight: bold; 68 - margin-bottom: 4px; 69 - display: block; 70 - } 71 - 72 - .card-description { 73 - font-size: 0.85em; 74 - color: #555; 75 - display: block; 76 - padding-left: 4px; 77 - padding-right: 4px; 78 - } 79 - 80 - /* Make description clickable */ 81 - .card-description.clickable { 82 - cursor: pointer; 83 - transition: background-color 0.2s ease; 84 - } 85 - .card-description.clickable:hover { 86 - background-color: #f0f0f0; /* Subtle hover effect */ 87 - } 88 - 89 - /* Textarea for editing description */ 90 - .card-description-edit { 91 - width: 90%; /* Adjust as needed */ 92 - margin: 4px auto; /* Center and add vertical space */ 93 - font-size: 0.85em; 94 - font-family: inherit; 95 - border: 1px solid #aaa; 96 - border-radius: 3px; 97 - resize: vertical; /* Allow vertical resize */ 98 - box-sizing: border-box; 99 - } 100 - 101 - .values-grid { 102 - display: grid; 103 - grid-template-columns: repeat(2, 1fr); 104 - gap: 2em; 105 - margin-bottom: 2em; 106 - padding: 1em; 107 - background: #f8f9fa; 108 - border-radius: 4px; 109 - } 110 - 111 - .grid-section { 112 - background: white; 113 - padding: 1em; 114 - border-radius: 4px; 115 - box-shadow: 0 1px 3px rgba(0,0,0,0.1); 116 - } 117 - 118 - .grid-section h3 { 119 - margin-top: 0; 120 - color: #495057; 121 - border-bottom: 1px solid #dee2e6; 122 - padding-bottom: 0.5em; 123 - } 124 - 125 - .grid-section ul { 126 - list-style: none; 127 - padding: 0; 128 - margin: 0; 129 - } 130 - 131 - .grid-section li { 132 - border-bottom: 1px solid #eee; 133 - padding: 0.75em 0; 134 - } 135 - 136 - .grid-section li:last-child { 137 - border-bottom: none; 138 - } 139 - 140 - /* Styles for Review Page Lists */ 141 - #reviewContent .grid-section ul li { 142 - margin-bottom: 0; 143 - } 144 - 145 - .review-value-name { 146 - font-weight: bold; 147 - display: block; 148 - } 149 - 150 - .review-value-description { 151 - font-size: 0.9em; 152 - color: #444; 153 - display: block; 154 - margin-left: 0; 155 - margin-top: 2px; 156 - } 157 - 158 - /* Styles for the separate Core Values & Statements list */ 159 - #reviewContent > ul { 160 - list-style: disc; 161 - margin-left: 20px; 162 - } 163 - 164 - #reviewContent > ul li { 165 - margin-bottom: 5px; 166 - } 167 - 168 - /* Modal Styles */ 169 - .modal { 170 - position: fixed; 171 - left: 0; 172 - top: 0; 173 - width: 100%; 174 - height: 100%; 175 - background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent background */ 176 - display: flex; 177 - justify-content: center; 178 - align-items: center; 179 - z-index: 1000; /* Ensure it's on top */ 180 - } 181 - 182 - .modal-content { 183 - background-color: #fff; 184 - padding: 20px; 185 - border-radius: 5px; 186 - width: 90%; 187 - max-width: 400px; 188 - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); 189 - } 190 - 191 - .modal-content label { 192 - display: block; 193 - margin-top: 10px; 194 - margin-bottom: 5px; 195 - font-weight: bold; 196 - } 197 - 198 - .modal-content input[type="text"], 199 - .modal-content textarea { 200 - width: calc(100% - 20px); /* Account for padding */ 201 - padding: 8px; 202 - margin-bottom: 10px; 203 - border: 1px solid #ccc; 204 - border-radius: 4px; 205 - } 206 - 207 - .modal-buttons { 208 - text-align: right; 209 - margin-top: 15px; 210 - } 211 - 212 - .modal-buttons button { 213 - margin-left: 10px; 214 - padding: 8px 15px; 215 - } 216 - 217 - /* Inline button style */ 218 - .inline-btn { 219 - margin-left: 15px; 220 - font-size: 0.9em; 221 - padding: 2px 8px; 222 - } 223 - 224 - /* Add other existing styles below */ 225 - #app { 226 - } 227 - 2 + font-family: sans-serif; 3 + margin: 0; 4 + padding: 1em; 5 + background: #f5f5f5; 6 + } 7 + 8 + header { 9 + display: flex; 10 + justify-content: space-between; 11 + align-items: center; 12 + } 13 + 14 + #global-controls button { 15 + margin-right: 0.5em; 16 + } 17 + 18 + .exercise-part { 19 + margin-top: 1em; 20 + background: #fff; 21 + padding: 1em; 22 + border-radius: 4px; 23 + } 24 + 25 + .columns { 26 + display: flex; 27 + justify-content: space-around; 28 + flex-wrap: wrap; 29 + margin-bottom: 1em; 30 + } 31 + 32 + .column { 33 + flex: 1 1 200px; 34 + margin: 0.5em; 35 + padding: 0.5em; 36 + background: #eaeaea; 37 + border-radius: 4px; 38 + } 39 + 40 + .column h3 { 41 + text-align: center; 42 + } 43 + 44 + .card-container { 45 + min-height: 100px; 46 + padding: 0.5em; 47 + background: #fff; 48 + border: 1px dashed #ccc; 49 + border-radius: 4px; 50 + } 51 + 52 + .card { 53 + background: #d1e7dd; 54 + padding: 0.5em; 55 + margin: 0.5em 0; 56 + border-radius: 4px; 57 + cursor: grab; 58 + display: flex; 59 + flex-direction: column; 60 + align-items: center; 61 + text-align: center; 62 + padding-top: 8px; 63 + padding-bottom: 8px; 64 + } 65 + 66 + .card-name { 67 + font-weight: bold; 68 + margin-bottom: 4px; 69 + display: block; 70 + } 71 + 72 + .card-description { 73 + font-size: 0.85em; 74 + color: #555; 75 + display: block; 76 + padding-left: 4px; 77 + padding-right: 4px; 78 + } 79 + 80 + /* Make description clickable */ 81 + .card-description.clickable { 82 + cursor: pointer; 83 + transition: background-color 0.2s ease; 84 + } 85 + .card-description.clickable:hover { 86 + background-color: #f0f0f0; /* Subtle hover effect */ 87 + } 88 + 89 + /* Textarea for editing description */ 90 + .card-description-edit { 91 + width: 90%; /* Adjust as needed */ 92 + margin: 4px auto; /* Center and add vertical space */ 93 + font-size: 0.85em; 94 + font-family: inherit; 95 + border: 1px solid #aaa; 96 + border-radius: 3px; 97 + resize: vertical; /* Allow vertical resize */ 98 + box-sizing: border-box; 99 + } 100 + 101 + .values-grid { 102 + display: grid; 103 + grid-template-columns: repeat(2, 1fr); 104 + gap: 2em; 105 + margin-bottom: 2em; 106 + padding: 1em; 107 + background: #f8f9fa; 108 + border-radius: 4px; 109 + } 110 + 111 + .grid-section { 112 + background: white; 113 + padding: 1em; 114 + border-radius: 4px; 115 + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); 116 + } 117 + 118 + .grid-section h3 { 119 + margin-top: 0; 120 + color: #495057; 121 + border-bottom: 1px solid #dee2e6; 122 + padding-bottom: 0.5em; 123 + } 124 + 125 + .grid-section ul { 126 + list-style: none; 127 + padding: 0; 128 + margin: 0; 129 + } 130 + 131 + .grid-section li { 132 + border-bottom: 1px solid #eee; 133 + padding: 0.75em 0; 134 + } 135 + 136 + .grid-section li:last-child { 137 + border-bottom: none; 138 + } 139 + 140 + /* Styles for Review Page Lists */ 141 + #reviewContent .grid-section ul li { 142 + margin-bottom: 0; 143 + } 144 + 145 + .review-value-name { 146 + font-weight: bold; 147 + display: block; 148 + } 149 + 150 + .review-value-description { 151 + font-size: 0.9em; 152 + color: #444; 153 + display: block; 154 + margin-left: 0; 155 + margin-top: 2px; 156 + } 157 + 158 + /* Styles for the separate Core Values & Statements list */ 159 + #reviewContent > ul { 160 + list-style: disc; 161 + margin-left: 20px; 162 + } 163 + 164 + #reviewContent > ul li { 165 + margin-bottom: 5px; 166 + } 167 + 168 + /* Modal Styles */ 169 + .modal { 170 + position: fixed; 171 + left: 0; 172 + top: 0; 173 + width: 100%; 174 + height: 100%; 175 + background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent background */ 176 + display: flex; 177 + justify-content: center; 178 + align-items: center; 179 + z-index: 1000; /* Ensure it's on top */ 180 + } 181 + 182 + .modal-content { 183 + background-color: #fff; 184 + padding: 20px; 185 + border-radius: 5px; 186 + width: 90%; 187 + max-width: 400px; 188 + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); 189 + } 190 + 191 + .modal-content label { 192 + display: block; 193 + margin-top: 10px; 194 + margin-bottom: 5px; 195 + font-weight: bold; 196 + } 197 + 198 + .modal-content input[type='text'], 199 + .modal-content textarea { 200 + width: calc(100% - 20px); /* Account for padding */ 201 + padding: 8px; 202 + margin-bottom: 10px; 203 + border: 1px solid #ccc; 204 + border-radius: 4px; 205 + } 206 + 207 + .modal-buttons { 208 + text-align: right; 209 + margin-top: 15px; 210 + } 211 + 212 + .modal-buttons button { 213 + margin-left: 10px; 214 + padding: 8px 15px; 215 + } 216 + 217 + /* Inline button style */ 218 + .inline-btn { 219 + margin-left: 15px; 220 + font-size: 0.9em; 221 + padding: 2px 8px; 222 + } 223 + 224 + /* Add other existing styles below */ 225 + #app { 226 + }
+2 -2
undoManager.ts
··· 7 7 this.currentState = this.deepCopy(initialState); 8 8 } 9 9 private deepCopy(state: T): T { 10 - return JSON.parse(JSON.stringify(state)); 10 + return JSON.parse(JSON.stringify(state)) as T; 11 11 } 12 12 execute(newState: T) { 13 13 this.undoStack.push(this.deepCopy(this.currentState)); ··· 35 35 canRedo(): boolean { 36 36 return this.redoStack.length > 0; 37 37 } 38 - } 38 + }
+168 -169
values.ts
··· 1 1 export const VALUES = [ 2 2 { 3 - "name": "ACCEPTANCE", 4 - "description": "to be accepted as I am" 3 + name: 'ACCEPTANCE', 4 + description: 'to be accepted as I am', 5 5 }, 6 6 { 7 - "name": "ACCURACY", 8 - "description": "to be accurate in my opinions and beliefs" 7 + name: 'ACCURACY', 8 + description: 'to be accurate in my opinions and beliefs', 9 9 }, 10 10 { 11 - "name": "ACHIEVEMENT", 12 - "description": "to have important accomplishments" 11 + name: 'ACHIEVEMENT', 12 + description: 'to have important accomplishments', 13 13 }, 14 14 { 15 - "name": "ADVENTURE", 16 - "description": "to have new and exciting experiences" 15 + name: 'ADVENTURE', 16 + description: 'to have new and exciting experiences', 17 17 }, 18 18 { 19 - "name": "ATTRACTIVENESS", 20 - "description": "to be physically attractive" 19 + name: 'ATTRACTIVENESS', 20 + description: 'to be physically attractive', 21 21 }, 22 22 { 23 - "name": "AUTHORITY", 24 - "description": "to be in charge of and responsible for others" 23 + name: 'AUTHORITY', 24 + description: 'to be in charge of and responsible for others', 25 25 }, 26 26 { 27 - "name": "AUTONOMY", 28 - "description": "to be self-determined and independent" 27 + name: 'AUTONOMY', 28 + description: 'to be self-determined and independent', 29 29 }, 30 30 { 31 - "name": "BEAUTY", 32 - "description": "to appreciate beauty around me" 31 + name: 'BEAUTY', 32 + description: 'to appreciate beauty around me', 33 33 }, 34 34 { 35 - "name": "CARING", 36 - "description": "to take care of others" 35 + name: 'CARING', 36 + description: 'to take care of others', 37 37 }, 38 38 { 39 - "name": "CHALLENGE", 40 - "description": "to take on difficult tasks and problems" 39 + name: 'CHALLENGE', 40 + description: 'to take on difficult tasks and problems', 41 41 }, 42 42 { 43 - "name": "CHANGE", 44 - "description": "to have a life full of change and variety" 43 + name: 'CHANGE', 44 + description: 'to have a life full of change and variety', 45 45 }, 46 46 { 47 - "name": "COMFORT", 48 - "description": "to have a pleasant and comfortable life" 47 + name: 'COMFORT', 48 + description: 'to have a pleasant and comfortable life', 49 49 }, 50 50 { 51 - "name": "COMMITMENT", 52 - "description": "to make enduring, meaningful commitments" 51 + name: 'COMMITMENT', 52 + description: 'to make enduring, meaningful commitments', 53 53 }, 54 54 { 55 - "name": "COMPASSION", 56 - "description": "to feel and act on concern for others" 55 + name: 'COMPASSION', 56 + description: 'to feel and act on concern for others', 57 57 }, 58 58 { 59 - "name": "CONTRIBUTION", 60 - "description": "to make a lasting contribution in the world" 59 + name: 'CONTRIBUTION', 60 + description: 'to make a lasting contribution in the world', 61 61 }, 62 62 { 63 - "name": "COOPERATION", 64 - "description": "to work collaboratively with others" 63 + name: 'COOPERATION', 64 + description: 'to work collaboratively with others', 65 65 }, 66 66 { 67 - "name": "COURTESY", 68 - "description": "to be considerate and polite toward others" 67 + name: 'COURTESY', 68 + description: 'to be considerate and polite toward others', 69 69 }, 70 70 { 71 - "name": "CREATIVITY", 72 - "description": "to have new and original ideas" 71 + name: 'CREATIVITY', 72 + description: 'to have new and original ideas', 73 73 }, 74 74 { 75 - "name": "DEPENDABILITY", 76 - "description": "to be reliable and trustworthy" 75 + name: 'DEPENDABILITY', 76 + description: 'to be reliable and trustworthy', 77 77 }, 78 78 { 79 - "name": "DUTY", 80 - "description": "to carry out my duties and obligations" 79 + name: 'DUTY', 80 + description: 'to carry out my duties and obligations', 81 81 }, 82 82 { 83 - "name": "ECOLOGY", 84 - "description": "to live in harmony with the environment" 83 + name: 'ECOLOGY', 84 + description: 'to live in harmony with the environment', 85 85 }, 86 86 { 87 - "name": "EXCITEMENT", 88 - "description": "to have a life full of thrills and stimulation" 87 + name: 'EXCITEMENT', 88 + description: 'to have a life full of thrills and stimulation', 89 89 }, 90 90 { 91 - "name": "FAITHFULNESS", 92 - "description": "to be loyal and true in relationships" 91 + name: 'FAITHFULNESS', 92 + description: 'to be loyal and true in relationships', 93 93 }, 94 94 { 95 - "name": "FAME", 96 - "description": "to be known and recognized" 95 + name: 'FAME', 96 + description: 'to be known and recognized', 97 97 }, 98 98 { 99 - "name": "FAMILY", 100 - "description": "to have a happy, loving family" 99 + name: 'FAMILY', 100 + description: 'to have a happy, loving family', 101 101 }, 102 102 { 103 - "name": "FITNESS", 104 - "description": "to be physically fit and strong" 103 + name: 'FITNESS', 104 + description: 'to be physically fit and strong', 105 105 }, 106 106 { 107 - "name": "FLEXIBILITY", 108 - "description": "to adjust to new circumstances easily" 107 + name: 'FLEXIBILITY', 108 + description: 'to adjust to new circumstances easily', 109 109 }, 110 110 { 111 - "name": "FORGIVENESS", 112 - "description": "to be forgiving of others" 111 + name: 'FORGIVENESS', 112 + description: 'to be forgiving of others', 113 113 }, 114 114 { 115 - "name": "FRIENDSHIP", 116 - "description": "to have close, supportive friends" 115 + name: 'FRIENDSHIP', 116 + description: 'to have close, supportive friends', 117 117 }, 118 118 { 119 - "name": "FUN", 120 - "description": "to play and have fun" 119 + name: 'FUN', 120 + description: 'to play and have fun', 121 121 }, 122 122 { 123 - "name": "GENEROSITY", 124 - "description": "to give what I have to others" 123 + name: 'GENEROSITY', 124 + description: 'to give what I have to others', 125 125 }, 126 126 { 127 - "name": "GENUINENESS", 128 - "description": "to act in a manner that is true to who I am" 127 + name: 'GENUINENESS', 128 + description: 'to act in a manner that is true to who I am', 129 129 }, 130 130 { 131 - "name": "GOD'S WILL", 132 - "description": "to seek and obey the will of God" 131 + name: "GOD'S WILL", 132 + description: 'to seek and obey the will of God', 133 133 }, 134 134 { 135 - "name": "GROWTH", 136 - "description": "to keep changing and growing" 135 + name: 'GROWTH', 136 + description: 'to keep changing and growing', 137 137 }, 138 138 { 139 - "name": "HEALTH", 140 - "description": "to be physically well and healthy" 139 + name: 'HEALTH', 140 + description: 'to be physically well and healthy', 141 141 }, 142 142 { 143 - "name": "HELPFULNESS", 144 - "description": "to be helpful to others" 143 + name: 'HELPFULNESS', 144 + description: 'to be helpful to others', 145 145 }, 146 146 { 147 - "name": "HONESTY", 148 - "description": "to be honest and truthful" 147 + name: 'HONESTY', 148 + description: 'to be honest and truthful', 149 149 }, 150 150 { 151 - "name": "HOPE", 152 - "description": "to maintain a positive and optimistic outlook" 151 + name: 'HOPE', 152 + description: 'to maintain a positive and optimistic outlook', 153 153 }, 154 154 { 155 - "name": "HUMILITY", 156 - "description": "to be modest and unassuming" 155 + name: 'HUMILITY', 156 + description: 'to be modest and unassuming', 157 157 }, 158 158 { 159 - "name": "HUMOR", 160 - "description": "to see the humorous side of myself and the world" 159 + name: 'HUMOR', 160 + description: 'to see the humorous side of myself and the world', 161 161 }, 162 162 { 163 - "name": "INDEPENDENCE", 164 - "description": "to be free from dependence on others" 163 + name: 'INDEPENDENCE', 164 + description: 'to be free from dependence on others', 165 165 }, 166 166 { 167 - "name": "INDUSTRY", 168 - "description": "to work hard and well at my life tasks" 167 + name: 'INDUSTRY', 168 + description: 'to work hard and well at my life tasks', 169 169 }, 170 170 { 171 - "name": "INNER PEACE", 172 - "description": "to experience personal peace" 171 + name: 'INNER PEACE', 172 + description: 'to experience personal peace', 173 173 }, 174 174 { 175 - "name": "INTIMACY", 176 - "description": "to share my innermost experiences with others" 175 + name: 'INTIMACY', 176 + description: 'to share my innermost experiences with others', 177 177 }, 178 178 { 179 - "name": "JUSTICE", 180 - "description": "to promote fair and equal treatment for all" 179 + name: 'JUSTICE', 180 + description: 'to promote fair and equal treatment for all', 181 181 }, 182 182 { 183 - "name": "KNOWLEDGE", 184 - "description": "to learn and contribute valuable knowledge" 183 + name: 'KNOWLEDGE', 184 + description: 'to learn and contribute valuable knowledge', 185 185 }, 186 186 { 187 - "name": "LEISURE", 188 - "description": "to take time to relax and enjoy" 187 + name: 'LEISURE', 188 + description: 'to take time to relax and enjoy', 189 189 }, 190 190 { 191 - "name": "LOVED", 192 - "description": "to be loved by those close to me" 191 + name: 'LOVED', 192 + description: 'to be loved by those close to me', 193 193 }, 194 194 { 195 - "name": "LOVING", 196 - "description": "to give love to others" 195 + name: 'LOVING', 196 + description: 'to give love to others', 197 197 }, 198 198 { 199 - "name": "MASTERY", 200 - "description": "to be competent in my everyday activities" 199 + name: 'MASTERY', 200 + description: 'to be competent in my everyday activities', 201 201 }, 202 202 { 203 - "name": "MINDFULNESS", 204 - "description": "to live consciously and mindfully of the present moment" 203 + name: 'MINDFULNESS', 204 + description: 'to live consciously and mindfully of the present moment', 205 205 }, 206 206 { 207 - "name": "MODERATION", 208 - "description": "to avoid excesses and find a middle ground" 207 + name: 'MODERATION', 208 + description: 'to avoid excesses and find a middle ground', 209 209 }, 210 210 { 211 - "name": "MONOGAMY", 212 - "description": "to have one close, loving relationship" 211 + name: 'MONOGAMY', 212 + description: 'to have one close, loving relationship', 213 213 }, 214 214 { 215 - "name": "NONCONFORMITY", 216 - "description": "to question and challenge authority and norms" 215 + name: 'NONCONFORMITY', 216 + description: 'to question and challenge authority and norms', 217 217 }, 218 218 { 219 - "name": "NURTURANCE", 220 - "description": "to take care of and nurture others" 219 + name: 'NURTURANCE', 220 + description: 'to take care of and nurture others', 221 221 }, 222 222 { 223 - "name": "OPENNESS", 224 - "description": "to be open to new experiences, ideas, and options" 223 + name: 'OPENNESS', 224 + description: 'to be open to new experiences, ideas, and options', 225 225 }, 226 226 { 227 - "name": "ORDER", 228 - "description": "to have a life that is well-ordered and organized" 227 + name: 'ORDER', 228 + description: 'to have a life that is well-ordered and organized', 229 229 }, 230 230 { 231 - "name": "PASSION", 232 - "description": "to have deep feelings about ideas, activities, or people" 231 + name: 'PASSION', 232 + description: 'to have deep feelings about ideas, activities, or people', 233 233 }, 234 234 { 235 - "name": "PLEASURE", 236 - "description": "to feel good" 235 + name: 'PLEASURE', 236 + description: 'to feel good', 237 237 }, 238 238 { 239 - "name": "POPULARITY", 240 - "description": "to be well-liked by many people" 239 + name: 'POPULARITY', 240 + description: 'to be well-liked by many people', 241 241 }, 242 242 { 243 - "name": "POWER", 244 - "description": "to have control over others" 243 + name: 'POWER', 244 + description: 'to have control over others', 245 245 }, 246 246 { 247 - "name": "PURPOSE", 248 - "description": "to have meaning and direction in my life" 247 + name: 'PURPOSE', 248 + description: 'to have meaning and direction in my life', 249 249 }, 250 250 { 251 - "name": "RATIONALITY", 252 - "description": "to be guided by reason and logic" 251 + name: 'RATIONALITY', 252 + description: 'to be guided by reason and logic', 253 253 }, 254 254 { 255 - "name": "REALISM", 256 - "description": "to see and act realistically and practically" 255 + name: 'REALISM', 256 + description: 'to see and act realistically and practically', 257 257 }, 258 258 { 259 - "name": "RESPONSIBILITY", 260 - "description": "to make and carry out responsible decisions" 259 + name: 'RESPONSIBILITY', 260 + description: 'to make and carry out responsible decisions', 261 261 }, 262 262 { 263 - "name": "RISK", 264 - "description": "to take risks and chances" 263 + name: 'RISK', 264 + description: 'to take risks and chances', 265 265 }, 266 266 { 267 - "name": "ROMANCE", 268 - "description": "to have intense, exciting love in my life" 267 + name: 'ROMANCE', 268 + description: 'to have intense, exciting love in my life', 269 269 }, 270 270 { 271 - "name": "SAFETY", 272 - "description": "to be safe and secure" 271 + name: 'SAFETY', 272 + description: 'to be safe and secure', 273 273 }, 274 274 { 275 - "name": "SELF-ACCEPTANCE", 276 - "description": "to accept myself as I am" 275 + name: 'SELF-ACCEPTANCE', 276 + description: 'to accept myself as I am', 277 277 }, 278 278 { 279 - "name": "SELF-CONTROL", 280 - "description": "to be disciplined in my own actions" 279 + name: 'SELF-CONTROL', 280 + description: 'to be disciplined in my own actions', 281 281 }, 282 282 { 283 - "name": "SELF-ESTEEM", 284 - "description": "to feel good about myself" 283 + name: 'SELF-ESTEEM', 284 + description: 'to feel good about myself', 285 285 }, 286 286 { 287 - "name": "SELF-KNOWLEDGE", 288 - "description": "to have a deep and honest understanding of myself" 287 + name: 'SELF-KNOWLEDGE', 288 + description: 'to have a deep and honest understanding of myself', 289 289 }, 290 290 { 291 - "name": "SERVICE", 292 - "description": "to be of service to others" 291 + name: 'SERVICE', 292 + description: 'to be of service to others', 293 293 }, 294 294 { 295 - "name": "SEXUALITY", 296 - "description": "to have an active and satisfying sex life" 295 + name: 'SEXUALITY', 296 + description: 'to have an active and satisfying sex life', 297 297 }, 298 298 { 299 - "name": "SIMPLICITY", 300 - "description": "to live life simply, with minimal needs" 299 + name: 'SIMPLICITY', 300 + description: 'to live life simply, with minimal needs', 301 301 }, 302 302 { 303 - "name": "SOLITUDE", 304 - "description": "to have time and space where I can be apart from others" 303 + name: 'SOLITUDE', 304 + description: 'to have time and space where I can be apart from others', 305 305 }, 306 306 { 307 - "name": "SPIRITUALITY", 308 - "description": "to grow and mature spiritually" 307 + name: 'SPIRITUALITY', 308 + description: 'to grow and mature spiritually', 309 309 }, 310 310 { 311 - "name": "STABILITY", 312 - "description": "to have a life that stays fairly consistent" 311 + name: 'STABILITY', 312 + description: 'to have a life that stays fairly consistent', 313 313 }, 314 314 { 315 - "name": "TOLERANCE", 316 - "description": "to accept and respect those who differ from me" 315 + name: 'TOLERANCE', 316 + description: 'to accept and respect those who differ from me', 317 317 }, 318 318 { 319 - "name": "TRADITION", 320 - "description": "to follow respected patterns of the past" 319 + name: 'TRADITION', 320 + description: 'to follow respected patterns of the past', 321 321 }, 322 322 { 323 - "name": "VIRTUE", 324 - "description": "to live a morally pure and excellent life" 323 + name: 'VIRTUE', 324 + description: 'to live a morally pure and excellent life', 325 325 }, 326 326 { 327 - "name": "WEALTH", 328 - "description": "to have plenty of money" 327 + name: 'WEALTH', 328 + description: 'to have plenty of money', 329 329 }, 330 330 { 331 - "name": "WORLD PEACE", 332 - "description": "to work to promote peace in the world" 333 - } 334 - ] 335 - 331 + name: 'WORLD PEACE', 332 + description: 'to work to promote peace in the world', 333 + }, 334 + ];