From aa032323f30bde054b6f2ea155ee9d400f78df61 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 11:25:46 +0900 Subject: [PATCH 01/22] chore: update and install dependencies --- package-lock.json | 2257 ++++++++++++++++++++--------------- package.json | 3 + public/mockServiceWorker.js | 2 +- 3 files changed, 1295 insertions(+), 967 deletions(-) diff --git a/package-lock.json b/package-lock.json index 88150579..df53bd54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "frontend", "version": "0.0.0", "dependencies": { + "@stomp/stompjs": "^7.3.0", "@tanstack/eslint-plugin-query": "^5.91.4", "@tanstack/react-query": "^5.90.20", "axios": "^1.13.4", @@ -24,6 +25,7 @@ "react-i18next": "^16.5.4", "react-icons": "^5.5.0", "react-router-dom": "^7.13.0", + "sockjs-client": "^1.6.1", "vite-bundle-visualizer": "^1.2.1" }, "devDependencies": { @@ -51,6 +53,7 @@ "@types/pako": "^2.0.3", "@types/react": "^18.3.27", "@types/react-dom": "^18.3.7", + "@types/sockjs-client": "^1.5.4", "@vitejs/plugin-react": "^5.1.3", "autoprefixer": "^10.4.20", "chromatic": "^11.20.2", @@ -113,23 +116,26 @@ } }, "node_modules/@asamuzakjp/css-color": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz", - "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.0.1.tgz", + "integrity": "sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-color-parser": "^3.1.0", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "lru-cache": "^11.2.4" + "@csstools/css-calc": "^3.1.1", + "@csstools/css-color-parser": "^4.0.2", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -137,9 +143,9 @@ } }, "node_modules/@asamuzakjp/dom-selector": { - "version": "6.7.7", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.7.tgz", - "integrity": "sha512-8CO/UQ4tzDd7ula+/CVimJIVWez99UJlbMyIgk8xOnhAVPKLnBZmUFYVgugS441v2ZqUq5EnSh6B0Ua0liSFAA==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", "dev": true, "license": "MIT", "dependencies": { @@ -147,13 +153,13 @@ "bidi-js": "^1.0.3", "css-tree": "^3.1.0", "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.2.5" + "lru-cache": "^11.2.6" } }, "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -234,9 +240,9 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.0.tgz", - "integrity": "sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { @@ -360,23 +366,23 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", - "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/types": "^7.29.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "dev": true, "license": "MIT", "dependencies": { @@ -422,9 +428,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -478,17 +484,30 @@ "node": ">=6.9.0" } }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, "node_modules/@cacheable/memory": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.7.tgz", - "integrity": "sha512-RbxnxAMf89Tp1dLhXMS7ceft/PGsDl1Ip7T20z5nZ+pwIAsQ1p2izPjVG69oCLv/jfQ7HDPHTWK0c9rcAWXN3A==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.8.tgz", + "integrity": "sha512-FvEb29x5wVwu/Kf93IWwsOOEuhHh6dYCJF3vcKLzXc0KXIW181AOzv6ceT4ZpBHDvAfG60eqb+ekmrnLHIy+jw==", "dev": true, "license": "MIT", "dependencies": { - "@cacheable/utils": "^2.3.3", - "@keyv/bigmap": "^1.3.0", - "hookified": "^1.14.0", - "keyv": "^5.5.5" + "@cacheable/utils": "^2.4.0", + "@keyv/bigmap": "^1.3.1", + "hookified": "^1.15.1", + "keyv": "^5.6.0" } }, "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": { @@ -519,14 +538,14 @@ } }, "node_modules/@cacheable/utils": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.3.3.tgz", - "integrity": "sha512-JsXDL70gQ+1Vc2W/KUFfkAJzgb4puKwwKehNLuB+HrNKWf91O736kGfxn4KujXCCSuh6mRRL4XEB0PkAFjWS0A==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.4.1.tgz", + "integrity": "sha512-eiFgzCbIneyMlLOmNG4g9xzF7Hv3Mga4LjxjcSC/ues6VYq2+gUbQI8JqNuw/ZM8tJIeIaBGpswAsqV2V7ApgA==", "dev": true, "license": "MIT", "dependencies": { - "hashery": "^1.3.0", - "keyv": "^5.5.5" + "hashery": "^1.5.1", + "keyv": "^5.6.0" } }, "node_modules/@cacheable/utils/node_modules/keyv": { @@ -561,9 +580,9 @@ } }, "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", "dev": true, "funding": [ { @@ -577,13 +596,13 @@ ], "license": "MIT-0", "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", + "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", "dev": true, "funding": [ { @@ -597,17 +616,17 @@ ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz", + "integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==", "dev": true, "funding": [ { @@ -621,21 +640,21 @@ ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.1.1" }, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", "dev": true, "funding": [ { @@ -649,16 +668,16 @@ ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.26.tgz", - "integrity": "sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.2.tgz", + "integrity": "sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA==", "dev": true, "funding": [ { @@ -670,32 +689,20 @@ "url": "https://opencollective.com/csstools" } ], - "license": "MIT-0" - }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true } - ], - "license": "MIT", - "engines": { - "node": ">=18" } }, - "node_modules/@csstools/media-query-list-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", - "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", "dev": true, "funding": [ { @@ -709,11 +716,7 @@ ], "license": "MIT", "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "node": ">=20.19.0" } }, "node_modules/@csstools/selector-specificity": { @@ -1220,23 +1223,29 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^3.1.5" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -1280,19 +1289,19 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "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.1", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -1302,10 +1311,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -1337,9 +1352,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1371,9 +1386,9 @@ } }, "node_modules/@exodus/bytes": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.11.0.tgz", - "integrity": "sha512-wO3vd8nsEHdumsXrjGO/v4p6irbg7hy9kvIeR6i2AwylZSk4HJdWgL0FNaVquW1+AweJcdvU1IEpuIWk/WaPnA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz", + "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==", "dev": true, "license": "MIT", "engines": { @@ -1592,9 +1607,9 @@ } }, "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", + "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", "dev": true, "license": "MIT", "engines": { @@ -1602,9 +1617,9 @@ } }, "node_modules/@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", + "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", "dev": true, "license": "MIT", "dependencies": { @@ -1652,9 +1667,9 @@ } }, "node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", + "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "license": "MIT", "dependencies": { @@ -1691,10 +1706,28 @@ } } }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/brace-expansion": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -1732,6 +1765,22 @@ "node": ">=12" } }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@joshwooding/vite-plugin-react-docgen-typescript/node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -1825,9 +1874,9 @@ } }, "node_modules/@mswjs/interceptors": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.40.0.tgz", - "integrity": "sha512-EFd6cVbHsgLa6wa4RljGj6Wk75qoHxUSyc5asLyyPSyuhIcdS2Q3Phw6ImS1q+CkALthJRShiYfKANcQMuMqsQ==", + "version": "0.41.3", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.41.3.tgz", + "integrity": "sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA==", "dev": true, "license": "MIT", "dependencies": { @@ -1930,9 +1979,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.2", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.2.tgz", - "integrity": "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==", + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", "dev": true, "license": "MIT" }, @@ -1960,9 +2009,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.0.tgz", + "integrity": "sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==", "cpu": [ "arm" ], @@ -1974,9 +2023,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.0.tgz", + "integrity": "sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==", "cpu": [ "arm64" ], @@ -1988,9 +2037,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.0.tgz", + "integrity": "sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==", "cpu": [ "arm64" ], @@ -2002,9 +2051,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.0.tgz", + "integrity": "sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==", "cpu": [ "x64" ], @@ -2016,9 +2065,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.0.tgz", + "integrity": "sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==", "cpu": [ "arm64" ], @@ -2030,9 +2079,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.0.tgz", + "integrity": "sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==", "cpu": [ "x64" ], @@ -2044,9 +2093,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.0.tgz", + "integrity": "sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==", "cpu": [ "arm" ], @@ -2058,9 +2107,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.0.tgz", + "integrity": "sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==", "cpu": [ "arm" ], @@ -2072,9 +2121,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.0.tgz", + "integrity": "sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==", "cpu": [ "arm64" ], @@ -2086,9 +2135,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.0.tgz", + "integrity": "sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==", "cpu": [ "arm64" ], @@ -2100,9 +2149,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.0.tgz", + "integrity": "sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==", "cpu": [ "loong64" ], @@ -2114,9 +2163,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.0.tgz", + "integrity": "sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==", "cpu": [ "loong64" ], @@ -2128,9 +2177,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.0.tgz", + "integrity": "sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==", "cpu": [ "ppc64" ], @@ -2142,9 +2191,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.0.tgz", + "integrity": "sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==", "cpu": [ "ppc64" ], @@ -2156,9 +2205,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.0.tgz", + "integrity": "sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==", "cpu": [ "riscv64" ], @@ -2170,9 +2219,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.0.tgz", + "integrity": "sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==", "cpu": [ "riscv64" ], @@ -2184,9 +2233,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.0.tgz", + "integrity": "sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==", "cpu": [ "s390x" ], @@ -2198,9 +2247,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.0.tgz", + "integrity": "sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==", "cpu": [ "x64" ], @@ -2212,9 +2261,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.0.tgz", + "integrity": "sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==", "cpu": [ "x64" ], @@ -2226,9 +2275,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.0.tgz", + "integrity": "sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==", "cpu": [ "x64" ], @@ -2240,9 +2289,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.0.tgz", + "integrity": "sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==", "cpu": [ "arm64" ], @@ -2254,9 +2303,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.0.tgz", + "integrity": "sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==", "cpu": [ "arm64" ], @@ -2268,9 +2317,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.0.tgz", + "integrity": "sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==", "cpu": [ "ia32" ], @@ -2282,9 +2331,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.0.tgz", + "integrity": "sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==", "cpu": [ "x64" ], @@ -2296,9 +2345,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.0.tgz", + "integrity": "sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==", "cpu": [ "x64" ], @@ -2330,10 +2379,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@stomp/stompjs": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@stomp/stompjs/-/stompjs-7.3.0.tgz", + "integrity": "sha512-nKMLoFfJhrQAqkvvKd1vLq/cVBGCMwPRCD0LqW7UT1fecRx9C3GoKEIR2CYwVuErGeZu8w0kFkl2rlhPlqHVgQ==", + "license": "Apache-2.0" + }, "node_modules/@storybook/addon-actions": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.15.tgz", - "integrity": "sha512-zc600PBJqP9hCyRY5escKgKf6Zt9kdNZfm+Jwb46k5/NMSO4tNVeOPGBFxW9kSsIYk8j55sNske+Yh60G+8bcw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.18.tgz", + "integrity": "sha512-GcYhtE91GjIQTuZlwpTJ8jfMp6NC79nkpe1DGe0eetTpyQqLq1WUt+ACkk0Z5lqq2u8HBc09zCCGw+D8iCLpYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2348,13 +2403,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-backgrounds": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.15.tgz", - "integrity": "sha512-W36uEzMWPO/K3+8vV1R/GozdaFrIix0qqmxX0qoAT6/o4+zqHiloZkTF+2iuUTx/VmuztLcAoSaPDh8UPy3Q+g==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.18.tgz", + "integrity": "sha512-froND3WwvSCYzjEBO8QODStaWNL+aGXqxBEbrMnGYejDFST4qEFkvM2IYWMnLBkRgrgJ0yIqTeDQoyH9b9/8uQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2367,13 +2422,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-controls": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.15.tgz", - "integrity": "sha512-CgV8WqGxQrqSKs1a/Y1v4mrsBJXGFmO5u4kvdhPbftRVfln11W4Hvc1SFmgXwGvmcwekAKH79Uwwkjhj3l6gzA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.18.tgz", + "integrity": "sha512-K09dHDCfGW3cudsfuyfu0Yi49aZ2h7VYK4IXDGo1sfmtzVh4xd3HrZQQMVUeKLcfDP/NnJowT+fLVwg04CLrxQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2386,20 +2441,20 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-docs": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.15.tgz", - "integrity": "sha512-Nm5LlxwAmGQRkCUY36FhtCLz21C+5XlydF7/bkBOHsf08p2xR5MNLMSPrIhte/PY7ne9viNUCm1d3d3LiWnkKg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.18.tgz", + "integrity": "sha512-55ADer0yNmmeR928Y3UAv3r4i7bJSd9LwywsQ+lRol/FNe0ZcwLEz31xL+jVsqQFNnDh/imsDIp8aYapGMtfEQ==", "dev": true, "license": "MIT", "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/blocks": "8.6.15", - "@storybook/csf-plugin": "8.6.15", - "@storybook/react-dom-shim": "8.6.15", + "@storybook/blocks": "8.6.18", + "@storybook/csf-plugin": "8.6.18", + "@storybook/react-dom-shim": "8.6.18", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" @@ -2409,25 +2464,25 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-essentials": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.15.tgz", - "integrity": "sha512-BIcE/7t5WXDXs4+zycm7MLNPHA2219ImkKO70IH7uxGM4cm7jDuJ5v0crkAvNeeRVsZixT2P2L9EfUfi1cFCQg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.18.tgz", + "integrity": "sha512-MmH7gFb8pyfRoAth0w2RW8j7mBaEJbEWGP3juIoH03ZqTGmbMUbJXElCuRgxQhve7pyz39zLsgtE78D7G+76ew==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/addon-actions": "8.6.15", - "@storybook/addon-backgrounds": "8.6.15", - "@storybook/addon-controls": "8.6.15", - "@storybook/addon-docs": "8.6.15", - "@storybook/addon-highlight": "8.6.15", - "@storybook/addon-measure": "8.6.15", - "@storybook/addon-outline": "8.6.15", - "@storybook/addon-toolbars": "8.6.15", - "@storybook/addon-viewport": "8.6.15", + "@storybook/addon-actions": "8.6.18", + "@storybook/addon-backgrounds": "8.6.18", + "@storybook/addon-controls": "8.6.18", + "@storybook/addon-docs": "8.6.18", + "@storybook/addon-highlight": "8.6.18", + "@storybook/addon-measure": "8.6.18", + "@storybook/addon-outline": "8.6.18", + "@storybook/addon-toolbars": "8.6.18", + "@storybook/addon-viewport": "8.6.18", "ts-dedent": "^2.0.0" }, "funding": { @@ -2435,13 +2490,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-highlight": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.15.tgz", - "integrity": "sha512-lOu44QTVw5nR8kzag0ukxWnLq48oy2MqMUDuMVFQWPBKX8ayhmgl2OiEcvAOVNsieTHrr2W4CkP7FFvF4D0vlg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.18.tgz", + "integrity": "sha512-wTFJ1DPM0C8gK6nGTJxH75byayQj7BPAz02fME4AOmT6clrBpVl1zSTFTkXaSr+k4xOfeMR/xNUfVskaXz6T9w==", "dev": true, "license": "MIT", "dependencies": { @@ -2452,19 +2507,19 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-interactions": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.15.tgz", - "integrity": "sha512-9qgu7jbPjzFm44UF57D6puK+/86maE26gY+06Thz1NpTBCjVIl2fTZ/CA00iXb5+12f3JmSF0w3XEjsqcrzd3w==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.18.tgz", + "integrity": "sha512-4Ie7sThNpHs+HH69ip4Pl7Ce/OVwiOuuXLO7mLGghkz6hTUz77IvH3P/09v3X0UOOcIbcF7LM3j+H7EVyY4ULA==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.6.15", - "@storybook/test": "8.6.15", + "@storybook/instrumenter": "8.6.18", + "@storybook/test": "8.6.18", "polished": "^4.2.2", "ts-dedent": "^2.2.0" }, @@ -2473,13 +2528,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-measure": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.15.tgz", - "integrity": "sha512-F78fJlmuXMulTphFp9Iqx7I1GsbmNLboChnW/VqR6nRZx5o9cdGjc8IaEyXVFXZ7k1pnSvdaP5ndFmzkcPxQdg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.18.tgz", + "integrity": "sha512-fMEOJXgPrTm6qHlWoRM+WTLE7Mr1QBIf2ei+pujBQFcWkD6Gjc2pV8zKzvh93d+EA13wD8AmwOq1DEw9J+XH+g==", "dev": true, "license": "MIT", "dependencies": { @@ -2491,13 +2546,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-onboarding": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-8.6.15.tgz", - "integrity": "sha512-HAsGUQxpwP4MoyaCuZcmLpSMVTXC6PSic2QY6156ZfFMiobD+W0vIaxuDw65iBNUJ2vWRmrQsR8YgmfyWMQ7qA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-8.6.18.tgz", + "integrity": "sha512-F0rpD5GwIpstQlRaPYQNroIPECB//yy0v2hHQOjFtH5OnCfJXpih4M5pFYcwXsMStRwLVJWS5ywfz+Xea0hmgg==", "dev": true, "license": "MIT", "funding": { @@ -2505,13 +2560,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-outline": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.15.tgz", - "integrity": "sha512-rpGRLajsjBdpbggPmdNZbftF68zQwsYLosu7YiUSBaR4dm+gQ+7m5nLLI/MjZDHbt2nJRW94yXpn7dUw2CDF6g==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.18.tgz", + "integrity": "sha512-TErFqfCtlV2xt9B6/kskROt69TPjr6AXdHpMselaRrN1X4WEjcMk9GT9PcNP7FXqL88/VYqUb3uNMiAmpDmS/g==", "dev": true, "license": "MIT", "dependencies": { @@ -2523,13 +2578,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-toolbars": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.15.tgz", - "integrity": "sha512-NfHAbOOu5qI9SQq6jJr2VfinaZpHrmz3bavBeUppxCxM+zfPuNudK8MlMOOuyPBPAoUqcDSoKZgNfCkOBQcyGg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.18.tgz", + "integrity": "sha512-x037KXCEcNfPISGX485DtiP+8Bw/cOT45plcQa8eiAQVrVcUwYaDoLubE9YV5b5CsSAjX8sDviGTme6ALfq7+w==", "dev": true, "license": "MIT", "funding": { @@ -2537,13 +2592,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/addon-viewport": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.15.tgz", - "integrity": "sha512-ylTK4sehAeVTwcYMZyisyP3xX+m43NjJrQHKc3DAII3Z3RFqTv9l6CUMogM2/8mysTzoo8xYVtQB6hX7zB8Dew==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.18.tgz", + "integrity": "sha512-z9sDJSkuWQb4BP+Z1+H+y/Q0rFbPSDcw+OBBEhMfRcJPPXavdC2pNQ0GdQNVw+tDwhAXj+U7jehKnMDKaP7TyA==", "dev": true, "license": "MIT", "dependencies": { @@ -2554,13 +2609,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/blocks": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.15.tgz", - "integrity": "sha512-nc5jQkvPo0EirteHsrmcx9on/0lGQ8F4lUNky7kN2I5WM8Frr3cPTeRoAvzjUkOwrqt/vm3g+T4zSbmDq/OEDA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.18.tgz", + "integrity": "sha512-esZv4msPQ9LxgTb8YUIZhhxVMuI6BPi5bkXtk8c7w7sWuAsqsCe/RnVInn7ooUry2gjnD4hd9+8Eqj0b8oTVoA==", "dev": true, "license": "MIT", "dependencies": { @@ -2574,7 +2629,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^8.6.15" + "storybook": "^8.6.18" }, "peerDependenciesMeta": { "react": { @@ -2586,13 +2641,13 @@ } }, "node_modules/@storybook/builder-vite": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.6.15.tgz", - "integrity": "sha512-9Y05/ndZE6/eI7ZIUCD/QtH2htRIUs9j1gxE6oW0zRo9TJO1iqxfLNwgzd59KEkId7gdZxPei0l+LGTUGXYKRg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.6.18.tgz", + "integrity": "sha512-XLqnOv4C36jlTd4uC8xpWBxv+7GV4/05zWJ0wAcU4qflorropUTirt4UQPGkwIzi+BVAhs9pJj+m4k0IWJtpHg==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/csf-plugin": "8.6.15", + "@storybook/csf-plugin": "8.6.18", "browser-assert": "^1.2.1", "ts-dedent": "^2.0.0" }, @@ -2601,14 +2656,14 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15", + "storybook": "^8.6.18", "vite": "^4.0.0 || ^5.0.0 || ^6.0.0" } }, "node_modules/@storybook/components": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.15.tgz", - "integrity": "sha512-+9GVKXPEW8Kl9zvNSTm9+VrJtx/puMZiO7gxCML63nK4aTWJXHQr4t9YUoGammSBM3AV1JglsKm6dBgJEeCoiA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.18.tgz", + "integrity": "sha512-55yViiZzPS/cPBuOeW4QGxGqrusjXVyxuknmbYCIwDtFyyvI/CgbjXRHdxNBaIjz+IlftxvBmmSaOqFG5+/dkA==", "dev": true, "license": "MIT", "funding": { @@ -2620,13 +2675,13 @@ } }, "node_modules/@storybook/core": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.15.tgz", - "integrity": "sha512-VFpKcphNurJpSC4fpUfKL3GTXVoL53oytghGR30QIw5jKWwaT50HVbTyb41BLOUuZjmMhUQA8weiQEew6RX0gw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.18.tgz", + "integrity": "sha512-dRBP2TnX6fGdS0T2mXBHjkS/3Nlu1ra1huovZVFuM67CYMzrhM/3hX/zru1vWSC5rqY93ZaAhjMciPW4pK5mMQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/theming": "8.6.15", + "@storybook/theming": "8.6.18", "better-opn": "^3.0.2", "browser-assert": "^1.2.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", @@ -2662,9 +2717,9 @@ } }, "node_modules/@storybook/csf-plugin": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.15.tgz", - "integrity": "sha512-ZLz/mtOoE1Jj2lE4pK3U7MmYrv5+lot3mGtwxGb832tcABMc97j9O+reCVxZYc7DeFbBuuEdMT9rBL/O3kXYmw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.18.tgz", + "integrity": "sha512-x1ioz/L0CwaelCkHci3P31YtvwayN3FBftvwQOPbvRh9qeb4Cpz5IdVDmyvSxxYwXN66uAORNoqgjTi7B4/y5Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2675,7 +2730,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/global": { @@ -2700,9 +2755,9 @@ } }, "node_modules/@storybook/instrumenter": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.15.tgz", - "integrity": "sha512-TvHR/+yyIAOp/1bLulFai2kkhIBtAlBw7J6Jd9DKyInoGhTWNE1G1Y61jD5GWXX29AlwaHfzGUaX5NL1K+FJpg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.18.tgz", + "integrity": "sha512-viEC1BGlYyjAzi1Tv3LZjByh7Y3Oh04u6QKsujxdeUbr5rUOH4pa/wCKmxXmY6yWrD4WjcNtojmUvQZN/66FXQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2714,13 +2769,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/manager-api": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.15.tgz", - "integrity": "sha512-ZOFtH821vFcwzECbFYFTKtSVO96Cvwwg45dMh3M/9bZIdN7klsloX7YNKw8OKvwE6XLFLsi2OvsNNcmTW6g88w==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.18.tgz", + "integrity": "sha512-BjIp12gEMgzFkEsgKpDIbZdnSWTZpm2dlws8WiPJCpgJtG+HWSxZ0/Ms30Au9yfwzQEKRSbV/5zpsKMGc2SIJw==", "dev": true, "license": "MIT", "funding": { @@ -2732,9 +2787,9 @@ } }, "node_modules/@storybook/preview-api": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.15.tgz", - "integrity": "sha512-oqsp8f7QekB9RzpDqOXZQcPPRXXd/mTsnZSdAAQB/pBVqUpC9h/y5hgovbYnJ6DWXcpODbMwH+wbJHZu5lvm+w==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.18.tgz", + "integrity": "sha512-joXRXh3GdVvzhbfIgmix1xs90p8Q/nja7AhEAC2egn5Pl7SKsIYZUCYI6UdrQANb2myg9P552LKXfPect8llKg==", "dev": true, "license": "MIT", "funding": { @@ -2746,18 +2801,18 @@ } }, "node_modules/@storybook/react": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.15.tgz", - "integrity": "sha512-hdnhlJg+YkpPMOw2hvK7+mhdxAbguA+TFTIAzVV9CeUYoHDIZAsgeKVhRmgZGN20NGjRN5ZcwkplAMJnF9v+6w==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.18.tgz", + "integrity": "sha512-BuLpzMkKtF+UCQCbi+lYVX9cdcAMG86Lu2dDn7UFkPi5HRNFq/zHPSvlz1XDgL0OYMtcqB1aoVzFzcyzUBhhjw==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/components": "8.6.15", + "@storybook/components": "8.6.18", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "8.6.15", - "@storybook/preview-api": "8.6.15", - "@storybook/react-dom-shim": "8.6.15", - "@storybook/theming": "8.6.15" + "@storybook/manager-api": "8.6.18", + "@storybook/preview-api": "8.6.18", + "@storybook/react-dom-shim": "8.6.18", + "@storybook/theming": "8.6.18" }, "engines": { "node": ">=18.0.0" @@ -2767,10 +2822,10 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "@storybook/test": "8.6.15", + "@storybook/test": "8.6.18", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.15", + "storybook": "^8.6.18", "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { @@ -2783,9 +2838,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.15.tgz", - "integrity": "sha512-m2trBmmd4iom1qwrp1F109zjRDc0cPaHYhDQxZR4Qqdz8pYevYJTlipDbH/K4NVB6Rn687RT29OoOPfJh6vkFA==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.18.tgz", + "integrity": "sha512-N4xULcAWZQTUv4jy1/d346Tyb4gufuC3UaLCuU/iVSZ1brYF4OW3ANr+096btbMxY8pR/65lmtoqr5CTGwnBvA==", "dev": true, "license": "MIT", "funding": { @@ -2795,20 +2850,20 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/react-vite": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.6.15.tgz", - "integrity": "sha512-9st+2NCemzzBwmindpDrRLEqYJmwwd2RnXMoj+Wt4Y1r4MGoRe1l837ciT2tmstaqekY2mVUSYd6879NzeeMYw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.6.18.tgz", + "integrity": "sha512-qpSYyH2IizlEsI95MJTdIL6xpLSgiNCMoJpHu+IEqLnyvmecRR/YEZvcHalgdtawuXlimH0bAYuwIu3l8Vo6FQ==", "dev": true, "license": "MIT", "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "0.5.0", "@rollup/pluginutils": "^5.0.2", - "@storybook/builder-vite": "8.6.15", - "@storybook/react": "8.6.15", + "@storybook/builder-vite": "8.6.18", + "@storybook/react": "8.6.18", "find-up": "^5.0.0", "magic-string": "^0.30.0", "react-docgen": "^7.0.0", @@ -2823,10 +2878,10 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "@storybook/test": "8.6.15", + "@storybook/test": "8.6.18", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.15", + "storybook": "^8.6.18", "vite": "^4.0.0 || ^5.0.0 || ^6.0.0" }, "peerDependenciesMeta": { @@ -2836,14 +2891,14 @@ } }, "node_modules/@storybook/test": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.15.tgz", - "integrity": "sha512-EwquDRUDVvWcZds3T2abmB5wSN/Vattal4YtZ6fpBlIUqONV4o/cOBX39cFfQSUCBrIXIjQ6RmapQCHK/PvBYw==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.18.tgz", + "integrity": "sha512-u/RwfWMyHcH0N2hqfMTw2CoZ58IXdeED3b8NmcHc8bmERB3byI5vVAkwYbcD7+WeRHIiym38ZHi0SRn+IpkO3Q==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.6.15", + "@storybook/instrumenter": "8.6.18", "@testing-library/dom": "10.4.0", "@testing-library/jest-dom": "6.5.0", "@testing-library/user-event": "14.5.2", @@ -2855,7 +2910,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.15" + "storybook": "^8.6.18" } }, "node_modules/@storybook/test/node_modules/@testing-library/dom": { @@ -2935,9 +2990,9 @@ } }, "node_modules/@storybook/theming": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.15.tgz", - "integrity": "sha512-dAbL0XOekyT6XsF49R6Etj3WxQ/LpdJDIswUUeHgVJ6/yd2opZOGbPxnwA3zlmAh1c0tvpPyhSDXxSG79u8e4Q==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.18.tgz", + "integrity": "sha512-n6OEjEtHupa2PdTwWzRepr7cO8NkDd4rgF6BKLitRbujOspLxzMBEqdphs+QLcuiCIgf33SqmEA64QWnbSMhPw==", "dev": true, "license": "MIT", "funding": { @@ -2949,9 +3004,9 @@ } }, "node_modules/@tanstack/eslint-plugin-query": { - "version": "5.91.4", - "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.91.4.tgz", - "integrity": "sha512-8a+GAeR7oxJ5laNyYBQ6miPK09Hi18o5Oie/jx8zioXODv/AUFLZQecKabPdpQSLmuDXEBPKFh+W5DKbWlahjQ==", + "version": "5.95.2", + "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.95.2.tgz", + "integrity": "sha512-EYUFRaqjBep4EHMPpZR12sXP7Kr5qv9iDIlq93NfbhHwhITaW6Txu3ROO6dLFz5r84T8p+oZXBG77pa2Wuok7A==", "license": "MIT", "dependencies": { "@typescript-eslint/utils": "^8.48.0" @@ -2962,7 +3017,7 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": "^5.0.0" + "typescript": "^5.4.0" }, "peerDependenciesMeta": { "typescript": { @@ -2971,9 +3026,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.90.20", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz", - "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==", + "version": "5.95.2", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.95.2.tgz", + "integrity": "sha512-o4T8vZHZET4Bib3jZ/tCW9/7080urD4c+0/AUaYVpIqOsr7y0reBc1oX3ttNaSW5mYyvZHctiQ/UOP2PfdmFEQ==", "license": "MIT", "funding": { "type": "github", @@ -2981,12 +3036,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.90.20", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.20.tgz", - "integrity": "sha512-vXBxa+qeyveVO7OA0jX1z+DeyCA4JKnThKv411jd5SORpBKgkcVnYKCiBgECvADvniBX7tobwBmg01qq9JmMJw==", + "version": "5.95.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.95.2.tgz", + "integrity": "sha512-/wGkvLj/st5Ud1Q76KF1uFxScV7WeqN1slQx5280ycwAyYkIPGaRZAEgHxe3bjirSd5Zpwkj6zNcR4cqYni/ZA==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.90.20" + "@tanstack/query-core": "5.95.2" }, "funding": { "type": "github", @@ -3231,9 +3286,9 @@ } }, "node_modules/@types/jest/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3280,13 +3335,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", - "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/pako": { @@ -3304,9 +3359,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.27", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", - "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", + "version": "18.3.28", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz", + "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", "dev": true, "license": "MIT", "dependencies": { @@ -3331,6 +3386,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/sockjs-client": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/sockjs-client/-/sockjs-client-1.5.4.tgz", + "integrity": "sha512-zk+uFZeWyvJ5ZFkLIwoGA/DfJ+pYzcZ8eH4H/EILCm2OBZyHH6Hkdna1/UWL/CFruh5wj6ES7g75SvUB0VsH5w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -3370,17 +3432,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", - "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", + "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/type-utils": "8.54.0", - "@typescript-eslint/utils": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/type-utils": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -3393,8 +3455,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.54.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.57.2", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -3409,16 +3471,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz", - "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", + "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "engines": { @@ -3429,18 +3491,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", - "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", + "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.54.0", - "@typescript-eslint/types": "^8.54.0", + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "engines": { @@ -3455,13 +3517,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", - "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", + "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0" + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3472,9 +3534,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", - "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", + "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3488,15 +3550,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz", - "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", + "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -3508,14 +3570,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", - "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", + "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3526,17 +3588,17 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", - "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", + "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.54.0", - "@typescript-eslint/tsconfig-utils": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -3553,15 +3615,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", - "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", + "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0" + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3571,18 +3633,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", - "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", + "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.57.2", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3593,28 +3655,28 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@vitejs/plugin-react": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.3.tgz", - "integrity": "sha512-NVUnA6gQCl8jfoYqKqQU5Clv0aPw14KkZYCsX6T9Lfu9slI0LOU10OTwFHS/WmptsMMpshNd/1tuWsHQ2Uk+cg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", + "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-rc.2", + "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, @@ -3622,7 +3684,7 @@ "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@vitest/expect": { @@ -3681,13 +3743,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.18.tgz", - "integrity": "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.2.tgz", + "integrity": "sha512-Ize4iQtEALHDttPRCmN+FKqOl2vxTiNUhzobQFFt/BM1lRUTG7zRCLOykG/6Vo4E4hnUdfVLo5/eqKPukcWW7Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.0.18", + "@vitest/spy": "4.1.2", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -3696,7 +3758,7 @@ }, "peerDependencies": { "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0-0" + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "msw": { @@ -3708,9 +3770,9 @@ } }, "node_modules/@vitest/mocker/node_modules/@vitest/spy": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz", - "integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.2.tgz", + "integrity": "sha512-DU4fBnbVCJGNBwVA6xSToNXrkZNSiw59H8tcuUspVMsBDBST4nfvsPsEHDHGtWRRnqBERBQu7TrTKskmjqTXKA==", "dev": true, "license": "MIT", "funding": { @@ -3741,13 +3803,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.18.tgz", - "integrity": "sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.2.tgz", + "integrity": "sha512-Gr+FQan34CdiYAwpGJmQG8PgkyFVmARK8/xSijia3eTFgVfpcpztWLuP6FttGNfPLJhaZVP/euvujeNYar36OQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.0.18", + "@vitest/utils": "4.1.2", "pathe": "^2.0.3" }, "funding": { @@ -3755,36 +3817,37 @@ } }, "node_modules/@vitest/runner/node_modules/@vitest/pretty-format": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz", - "integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.2.tgz", + "integrity": "sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.0.3" + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner/node_modules/@vitest/utils": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.18.tgz", - "integrity": "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.2.tgz", + "integrity": "sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.18", - "tinyrainbow": "^3.0.3" + "@vitest/pretty-format": "4.1.2", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/runner/node_modules/tinyrainbow": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", - "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { @@ -3792,13 +3855,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.18.tgz", - "integrity": "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.2.tgz", + "integrity": "sha512-g7yfUmxYS4mNxk31qbOYsSt2F4m1E02LFqO53Xpzg3zKMhLAPZAjjfyl9e6z7HrW6LvUdTwAQR3HHfLjpko16A==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.18", + "@vitest/pretty-format": "4.1.2", + "@vitest/utils": "4.1.2", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -3807,22 +3871,37 @@ } }, "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz", - "integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.2.tgz", + "integrity": "sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/@vitest/utils": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.2.tgz", + "integrity": "sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.0.3" + "@vitest/pretty-format": "4.1.2", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/snapshot/node_modules/tinyrainbow": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", - "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { @@ -3858,9 +3937,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -3950,9 +4029,9 @@ } }, "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -4212,9 +4291,9 @@ "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.4.24", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.24.tgz", - "integrity": "sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw==", + "version": "10.4.27", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.27.tgz", + "integrity": "sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==", "dev": true, "funding": [ { @@ -4233,7 +4312,7 @@ "license": "MIT", "dependencies": { "browserslist": "^4.28.1", - "caniuse-lite": "^1.0.30001766", + "caniuse-lite": "^1.0.30001774", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" @@ -4275,14 +4354,14 @@ } }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz", + "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "proxy-from-env": "^2.1.0" } }, "node_modules/axobject-query": { @@ -4296,19 +4375,25 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/baseline-browser-mapping": { - "version": "2.9.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "version": "2.10.11", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.11.tgz", + "integrity": "sha512-DAKrHphkJyiGuau/cFieRYhcTFeK/lBuD++C7cZ6KZHbMhBrisoi+EvhQ5RZrIfV5qwsW8kgQ07JIC+MDJRAhg==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/better-opn": { @@ -4348,9 +4433,9 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -4359,15 +4444,6 @@ "node": "18 || 20 || >=22" } }, - "node_modules/brace-expansion/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -4431,17 +4507,17 @@ } }, "node_modules/cacheable": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.2.tgz", - "integrity": "sha512-w+ZuRNmex9c1TR9RcsxbfTKCjSL0rh1WA5SABbrWprIHeNBdmyQLSYonlDy9gpD+63XT8DgZ/wNh1Smvc9WnJA==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.4.tgz", + "integrity": "sha512-djgxybDbw9fL/ZWMI3+CE8ZilNxcwFkVtDc1gJ+IlOSSWkSMPQabhV/XCHTQ6pwwN6aivXPZ43omTooZiX06Ew==", "dev": true, "license": "MIT", "dependencies": { - "@cacheable/memory": "^2.0.7", - "@cacheable/utils": "^2.3.3", + "@cacheable/memory": "^2.0.8", + "@cacheable/utils": "^2.4.0", "hookified": "^1.15.0", - "keyv": "^5.5.5", - "qified": "^0.6.0" + "keyv": "^5.6.0", + "qified": "^0.9.0" } }, "node_modules/cacheable/node_modules/keyv": { @@ -4523,9 +4599,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001767", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001767.tgz", - "integrity": "sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==", + "version": "1.0.30001781", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz", + "integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==", "dev": true, "funding": [ { @@ -4800,9 +4876,9 @@ } }, "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4850,24 +4926,24 @@ } }, "node_modules/css-functions-list": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", - "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.3.3.tgz", + "integrity": "sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==", "dev": true, "license": "MIT", "engines": { - "node": ">=12 || >=16" + "node": ">=12" } }, "node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", "dev": true, "license": "MIT", "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" @@ -4894,25 +4970,25 @@ } }, "node_modules/cssstyle": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", - "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.2.0.tgz", + "integrity": "sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^4.1.1", - "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "@asamuzakjp/css-color": "^5.0.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.28", "css-tree": "^3.1.0", - "lru-cache": "^11.2.4" + "lru-cache": "^11.2.6" }, "engines": { "node": ">=20" } }, "node_modules/cssstyle/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -5174,9 +5250,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.283", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.283.tgz", - "integrity": "sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w==", + "version": "1.5.328", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", + "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==", "dev": true, "license": "ISC" }, @@ -5308,9 +5384,9 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz", - "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.1.tgz", + "integrity": "sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5329,6 +5405,7 @@ "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0", "safe-array-concat": "^1.1.3" }, "engines": { @@ -5336,9 +5413,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, @@ -5477,24 +5554,24 @@ } }, "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", + "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "ajv": "^6.12.4", + "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", @@ -5513,7 +5590,7 @@ "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -5632,10 +5709,17 @@ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, + "node_modules/eslint-plugin-import/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -5742,10 +5826,17 @@ "node": ">= 0.4" } }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -5853,10 +5944,17 @@ "eslint": ">=8.40" } }, + "node_modules/eslint-plugin-react/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint-plugin-react/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -5878,19 +5976,25 @@ } }, "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5968,10 +6072,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -6094,19 +6204,28 @@ "node": ">=0.10.0" } }, + "node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", "dev": true, "license": "MIT", "dependencies": { - "@jest/expect-utils": "30.2.0", + "@jest/expect-utils": "30.3.0", "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -6214,6 +6333,18 @@ "reusify": "^1.0.4" } }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -6296,9 +6427,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "license": "ISC" }, "node_modules/follow-redirects": { @@ -6385,13 +6516,13 @@ } }, "node_modules/framer-motion": { - "version": "12.29.3", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.29.3.tgz", - "integrity": "sha512-naVvtFA7IiRTU5n7w7Nj51QFVWu955bU0p9H0gGC4AbhHDQR0TcohoEYwdOZXWEkXrEYNTl95EDOxsjDqn1AvQ==", + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz", + "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==", "license": "MIT", "dependencies": { - "motion-dom": "^12.29.2", - "motion-utils": "^12.29.2", + "motion-dom": "^12.38.0", + "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { @@ -6551,9 +6682,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.1.tgz", - "integrity": "sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==", + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", + "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", "dev": true, "license": "MIT", "dependencies": { @@ -6564,18 +6695,18 @@ } }, "node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -6593,22 +6724,6 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -6651,9 +6766,9 @@ } }, "node_modules/globals": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.3.0.tgz", - "integrity": "sha512-yMqGUQVVCkD4tqjOJf3TnrvaaHDMYp4VlUSObbkIiuCPe/ofdMBFIAcBbCSRFWOnos6qRiTVStDwqPLUclaxIw==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", + "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", "dev": true, "license": "MIT", "engines": { @@ -6728,9 +6843,9 @@ "license": "ISC" }, "node_modules/graphql": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz", - "integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==", + "version": "16.13.2", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.2.tgz", + "integrity": "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==", "dev": true, "license": "MIT", "engines": { @@ -6816,13 +6931,13 @@ } }, "node_modules/hashery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.4.0.tgz", - "integrity": "sha512-Wn2i1In6XFxl8Az55kkgnFRiAlIAushzh26PTjL2AKtQcEfXrcLa7Hn5QOWGZEf3LU057P9TwwZjFyxfS1VuvQ==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", "dev": true, "license": "MIT", "dependencies": { - "hookified": "^1.14.0" + "hookified": "^1.15.0" }, "engines": { "node": ">=20" @@ -6889,6 +7004,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -6918,29 +7039,29 @@ } }, "node_modules/i18next": { - "version": "25.8.0", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.8.0.tgz", - "integrity": "sha512-urrg4HMFFMQZ2bbKRK7IZ8/CTE7D8H4JRlAwqA2ZwDRFfdd0K/4cdbNNLgfn9mo+I/h9wJu61qJzH7jCFAhUZQ==", + "version": "25.10.10", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.10.10.tgz", + "integrity": "sha512-cqUW2Z3EkRx7NqSyywjkgCLK7KLCL6IFVFcONG7nVYIJ3ekZ1/N5jUsihHV6Bq37NfhgtczxJcxduELtjTwkuQ==", "funding": [ { "type": "individual", - "url": "https://locize.com" + "url": "https://www.locize.com/i18next" }, { "type": "individual", - "url": "https://locize.com/i18next.html" + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" }, { "type": "individual", - "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + "url": "https://www.locize.com" } ], "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.4" + "@babel/runtime": "^7.29.2" }, "peerDependencies": { - "typescript": "^5" + "typescript": "^5 || ^6" }, "peerDependenciesMeta": { "typescript": { @@ -6949,9 +7070,9 @@ } }, "node_modules/i18next-browser-languagedetector": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.0.tgz", - "integrity": "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.1.tgz", + "integrity": "sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.2" @@ -7037,7 +7158,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, "license": "ISC" }, "node_modules/ini": { @@ -7597,16 +7717,16 @@ } }, "node_modules/jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.0.1", + "@jest/diff-sequences": "30.3.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -7626,9 +7746,9 @@ } }, "node_modules/jest-diff/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7648,16 +7768,16 @@ "license": "MIT" }, "node_modules/jest-matcher-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", - "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", + "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", "dev": true, "license": "MIT", "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "jest-diff": "30.2.0", - "pretty-format": "30.2.0" + "jest-diff": "30.3.0", + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -7677,9 +7797,9 @@ } }, "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7699,19 +7819,19 @@ "license": "MIT" }, "node_modules/jest-message-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", - "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", + "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", + "picomatch": "^4.0.3", + "pretty-format": "30.3.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -7733,9 +7853,9 @@ } }, "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7755,15 +7875,15 @@ "license": "MIT" }, "node_modules/jest-mock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", - "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", + "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-util": "30.2.0" + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -7780,18 +7900,18 @@ } }, "node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", + "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -7836,16 +7956,17 @@ } }, "node_modules/jsdom": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.0.0.tgz", - "integrity": "sha512-KDYJgZ6T2TKdU8yBfYueq5EPG/EylMsBvCaenWMJb2OXmjgczzwveRCoJ+Hgj1lXPDyasvrgneSn4GBuR1hYyA==", + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.1.0.tgz", + "integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==", "dev": true, "license": "MIT", "dependencies": { "@acemir/cssom": "^0.9.31", - "@asamuzakjp/dom-selector": "^6.7.6", + "@asamuzakjp/dom-selector": "^6.8.1", + "@bramus/specificity": "^2.4.2", "@exodus/bytes": "^1.11.0", - "cssstyle": "^5.3.7", + "cssstyle": "^6.0.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", @@ -7856,7 +7977,7 @@ "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.0", - "undici": "^7.20.0", + "undici": "^7.21.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", @@ -8146,9 +8267,9 @@ } }, "node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "dev": true, "license": "CC0-1.0" }, @@ -8200,9 +8321,9 @@ } }, "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -8244,15 +8365,15 @@ } }, "node_modules/minimatch": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.8.tgz", - "integrity": "sha512-reYkDYtj/b19TeqbNZCV4q9t+Yxylf/rYBsLb42SXJatTv4/ylq5lEiAmhA/IToxO7NI2UzNMghHoHuaqDkAjw==", - "license": "ISC", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -8269,28 +8390,28 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/motion-dom": { - "version": "12.29.2", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.29.2.tgz", - "integrity": "sha512-/k+NuycVV8pykxyiTCoFzIVLA95Nb1BFIVvfSu9L50/6K6qNeAYtkxXILy/LRutt7AzaYDc2myj0wkCVVYAPPA==", + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz", + "integrity": "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==", "license": "MIT", "dependencies": { - "motion-utils": "^12.29.2" + "motion-utils": "^12.36.0" } }, "node_modules/motion-utils": { - "version": "12.29.2", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.29.2.tgz", - "integrity": "sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==", + "version": "12.36.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz", + "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==", "license": "MIT" }, "node_modules/ms": { @@ -8300,15 +8421,15 @@ "license": "MIT" }, "node_modules/msw": { - "version": "2.12.7", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.12.7.tgz", - "integrity": "sha512-retd5i3xCZDVWMYjHEVuKTmhqY8lSsxujjVrZiGbbdoxxIBg5S7rCuYy/YQpfrTYIxpd/o0Kyb/3H+1udBMoYg==", + "version": "2.12.14", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.12.14.tgz", + "integrity": "sha512-4KXa4nVBIBjbDbd7vfQNuQ25eFxug0aropCQFoI0JdOBuJWamkT1yLVIWReFI8SiTRc+H1hKzaNk+cLk2N9rtQ==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { "@inquirer/confirm": "^5.0.0", - "@mswjs/interceptors": "^0.40.0", + "@mswjs/interceptors": "^0.41.2", "@open-draft/deferred-promise": "^2.2.0", "@types/statuses": "^2.0.6", "cookie": "^1.0.2", @@ -8318,7 +8439,7 @@ "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", "picocolors": "^1.1.1", - "rettime": "^0.7.0", + "rettime": "^0.10.1", "statuses": "^2.0.2", "strict-event-emitter": "^0.5.1", "tough-cookie": "^6.0.0", @@ -8358,9 +8479,9 @@ } }, "node_modules/msw/node_modules/type-fest": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.4.3.tgz", - "integrity": "sha512-AXSAQJu79WGc79/3e9/CR77I/KQgeY1AhNvcShIH4PTcGYyC4xv6H4R4AUOwkPS5799KlVDAu8zExeCrkGquiA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", + "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", "dev": true, "license": "(MIT OR CC0-1.0)", "dependencies": { @@ -8420,6 +8541,35 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "license": "MIT" }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-exports-info/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -8463,9 +8613,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", "dev": true, "license": "MIT" }, @@ -8795,9 +8945,9 @@ "license": "MIT" }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -8805,16 +8955,16 @@ "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -8863,9 +9013,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { "node": ">=12" @@ -8918,9 +9068,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, "funding": [ { @@ -9311,10 +9461,13 @@ "license": "MIT" }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/punycode": { "version": "2.3.1", @@ -9326,18 +9479,25 @@ } }, "node_modules/qified": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/qified/-/qified-0.6.0.tgz", - "integrity": "sha512-tsSGN1x3h569ZSU1u6diwhltLyfUWDp3YbFHedapTmpBl0B3P6U3+Qptg7xu+v+1io1EwhdPyyRHYbEw0KN2FA==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.9.0.tgz", + "integrity": "sha512-4q61YgkHbY6gmwkqm0BsxyLDO3UYdrdiJTJ7JiaZb3xpW1duxn135SB7KqUEkCiuu5O4W+TtwEWP2VjmSRanvA==", "dev": true, "license": "MIT", "dependencies": { - "hookified": "^1.14.0" + "hookified": "^2.1.0" }, "engines": { "node": ">=20" } }, + "node_modules/qified/node_modules/hookified": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.1.0.tgz", + "integrity": "sha512-ootKng4eaxNxa7rx6FJv2YKef3DuhqbEj3l70oGXwddPQEEnISm50TEZQclqiLTAtilT2nu7TErtCO523hHkyg==", + "dev": true, + "license": "MIT" + }, "node_modules/qrcode.react": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz", @@ -9347,6 +9507,12 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9461,19 +9627,19 @@ "license": "MIT" }, "node_modules/react-i18next": { - "version": "16.5.4", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.5.4.tgz", - "integrity": "sha512-6yj+dcfMncEC21QPhOTsW8mOSO+pzFmT6uvU7XXdvM/Cp38zJkmTeMeKmTrmCMD5ToT79FmiE/mRWiYWcJYW4g==", + "version": "16.6.6", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.6.6.tgz", + "integrity": "sha512-ZgL2HUoW34UKUkOV7uSQFE1CDnRPD+tCR3ywSuWH7u2iapnz86U8Bi3Vrs620qNDzCf1F47NxglCEkchCTDOHw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.28.4", + "@babel/runtime": "^7.29.2", "html-parse-stringify": "^3.0.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { - "i18next": ">= 25.6.2", + "i18next": ">= 25.10.9", "react": ">= 16.8.0", - "typescript": "^5" + "typescript": "^5 || ^6" }, "peerDependenciesMeta": { "react-dom": { @@ -9488,9 +9654,9 @@ } }, "node_modules/react-icons": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", - "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.6.0.tgz", + "integrity": "sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==", "license": "MIT", "peerDependencies": { "react": "*" @@ -9514,9 +9680,9 @@ } }, "node_modules/react-router": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz", - "integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==", + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.2.tgz", + "integrity": "sha512-tX1Aee+ArlKQP+NIUd7SE6Li+CiGKwQtbS+FfRxPX6Pe4vHOo6nr9d++u5cwg+Z8K/x8tP+7qLmujDtfrAoUJA==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -9536,12 +9702,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.0.tgz", - "integrity": "sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g==", + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.2.tgz", + "integrity": "sha512-aR7SUORwTqAW0JDeiWF07e9SBE9qGpByR9I8kJT5h/FrBKxPMS6TiC7rmVO+gC0q52Bx7JnjWe8Z1sR9faN4YA==", "license": "MIT", "dependencies": { - "react-router": "7.13.0" + "react-router": "7.13.2" }, "engines": { "node": ">=20.0.0" @@ -9575,9 +9741,9 @@ } }, "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -9694,6 +9860,12 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, "node_modules/resolve": { "version": "1.22.11", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", @@ -9735,9 +9907,9 @@ } }, "node_modules/rettime": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rettime/-/rettime-0.7.0.tgz", - "integrity": "sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/rettime/-/rettime-0.10.1.tgz", + "integrity": "sha512-uyDrIlUEH37cinabq0AX4QbgV4HbFZ/gqoiunWQ1UqBtRvTTytwhNYjE++pO/MjPTZL5KQCf2bEoJ/BJNVQ5Kw==", "dev": true, "license": "MIT" }, @@ -9753,9 +9925,9 @@ } }, "node_modules/rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.0.tgz", + "integrity": "sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -9769,31 +9941,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", + "@rollup/rollup-android-arm-eabi": "4.60.0", + "@rollup/rollup-android-arm64": "4.60.0", + "@rollup/rollup-darwin-arm64": "4.60.0", + "@rollup/rollup-darwin-x64": "4.60.0", + "@rollup/rollup-freebsd-arm64": "4.60.0", + "@rollup/rollup-freebsd-x64": "4.60.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.0", + "@rollup/rollup-linux-arm-musleabihf": "4.60.0", + "@rollup/rollup-linux-arm64-gnu": "4.60.0", + "@rollup/rollup-linux-arm64-musl": "4.60.0", + "@rollup/rollup-linux-loong64-gnu": "4.60.0", + "@rollup/rollup-linux-loong64-musl": "4.60.0", + "@rollup/rollup-linux-ppc64-gnu": "4.60.0", + "@rollup/rollup-linux-ppc64-musl": "4.60.0", + "@rollup/rollup-linux-riscv64-gnu": "4.60.0", + "@rollup/rollup-linux-riscv64-musl": "4.60.0", + "@rollup/rollup-linux-s390x-gnu": "4.60.0", + "@rollup/rollup-linux-x64-gnu": "4.60.0", + "@rollup/rollup-linux-x64-musl": "4.60.0", + "@rollup/rollup-openbsd-x64": "4.60.0", + "@rollup/rollup-openharmony-arm64": "4.60.0", + "@rollup/rollup-win32-arm64-msvc": "4.60.0", + "@rollup/rollup-win32-ia32-msvc": "4.60.0", + "@rollup/rollup-win32-x64-gnu": "4.60.0", + "@rollup/rollup-win32-x64-msvc": "4.60.0", "fsevents": "~2.3.2" } }, @@ -9880,6 +10052,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safe-push-apply": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", @@ -9938,9 +10130,9 @@ } }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -10149,6 +10341,34 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/sockjs-client": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.1.tgz", + "integrity": "sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==", + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "eventsource": "^2.0.2", + "faye-websocket": "^0.11.4", + "inherits": "^2.0.4", + "url-parse": "^1.5.10" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://tidelift.com/funding/github/npm/sockjs-client" + } + }, + "node_modules/sockjs-client/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -10210,9 +10430,9 @@ } }, "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.0.0.tgz", + "integrity": "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==", "dev": true, "license": "MIT" }, @@ -10231,13 +10451,13 @@ } }, "node_modules/storybook": { - "version": "8.6.15", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.15.tgz", - "integrity": "sha512-Ob7DMlwWx8s7dMvcQ3xPc02TvUeralb+xX3oaPRk9wY9Hc6M1IBC/7cEoITkSmRS2v38DHubC+mtEKNc1u2gQg==", + "version": "8.6.18", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.18.tgz", + "integrity": "sha512-p8seiSI6FiVY6P3V0pG+5v7c8pDMehMAFRWEhG5XqIBSQszzOjDnW2rNvm3odoLKfo3V3P6Cs6Hv9ILzymULyQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core": "8.6.15" + "@storybook/core": "8.6.18" }, "bin": { "getstorybook": "bin/index.cjs", @@ -10446,13 +10666,13 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -10621,6 +10841,73 @@ "tailwindcss": ">=2.2.16" } }, + "node_modules/stylelint/node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/stylelint/node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/stylelint/node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, "node_modules/stylelint/node_modules/balanced-match": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", @@ -10639,14 +10926,14 @@ } }, "node_modules/stylelint/node_modules/flat-cache": { - "version": "6.1.20", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.20.tgz", - "integrity": "sha512-AhHYqwvN62NVLp4lObVXGVluiABTHapoB57EyegZVmazN+hhGhLTn3uZbOofoTw4DSDvVCadzzyChXhOAvy8uQ==", + "version": "6.1.22", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.22.tgz", + "integrity": "sha512-N2dnzVJIphnNsjHcrxGW7DePckJ6haPrSFqpsBUhHYgwtKGVq4JrBGielEGD2fCVnsGm1zlBVZ8wGhkyuetgug==", "dev": true, "license": "MIT", "dependencies": { - "cacheable": "^2.3.2", - "flatted": "^3.3.3", + "cacheable": "^2.3.4", + "flatted": "^3.4.2", "hookified": "^1.15.0" } }, @@ -10921,9 +11208,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", + "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", "dev": true, "license": "MIT", "engines": { @@ -10967,22 +11254,22 @@ } }, "node_modules/tldts": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.21.tgz", - "integrity": "sha512-Plu6V8fF/XU6d2k8jPtlQf5F4Xx2hAin4r2C2ca7wR8NK5MbRTo9huLUWRe28f3Uk8bYZfg74tit/dSjc18xnw==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.27.tgz", + "integrity": "sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.0.21" + "tldts-core": "^7.0.27" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.21.tgz", - "integrity": "sha512-oVOMdHvgjqyzUZH1rOESgJP1uNe2bVrfK0jUHHmiM2rpEiRbf3j4BrsIc6JigJRbHGanQwuZv/R+LTcHsw+bLA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.27.tgz", + "integrity": "sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg==", "dev": true, "license": "MIT" }, @@ -11009,9 +11296,9 @@ } }, "node_modules/tough-cookie": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", - "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", + "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -11035,9 +11322,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "license": "MIT", "engines": { "node": ">=18.12" @@ -11105,9 +11392,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", - "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", "cpu": [ "ppc64" ], @@ -11122,9 +11409,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", - "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", "cpu": [ "arm" ], @@ -11139,9 +11426,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", - "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", "cpu": [ "arm64" ], @@ -11156,9 +11443,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", - "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", "cpu": [ "x64" ], @@ -11173,9 +11460,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", - "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", "cpu": [ "arm64" ], @@ -11190,9 +11477,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/darwin-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", - "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", "cpu": [ "x64" ], @@ -11207,9 +11494,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", - "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", "cpu": [ "arm64" ], @@ -11224,9 +11511,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", - "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", "cpu": [ "x64" ], @@ -11241,9 +11528,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-arm": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", - "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", "cpu": [ "arm" ], @@ -11258,9 +11545,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", - "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", "cpu": [ "arm64" ], @@ -11275,9 +11562,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", - "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", "cpu": [ "ia32" ], @@ -11292,9 +11579,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-loong64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", - "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", "cpu": [ "loong64" ], @@ -11309,9 +11596,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", - "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", "cpu": [ "mips64el" ], @@ -11326,9 +11613,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", - "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", "cpu": [ "ppc64" ], @@ -11343,9 +11630,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", - "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", "cpu": [ "riscv64" ], @@ -11360,9 +11647,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-s390x": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", - "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", "cpu": [ "s390x" ], @@ -11377,9 +11664,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", - "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", "cpu": [ "x64" ], @@ -11394,9 +11681,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", - "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", "cpu": [ "arm64" ], @@ -11411,9 +11698,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", - "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", "cpu": [ "x64" ], @@ -11428,9 +11715,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", - "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", "cpu": [ "arm64" ], @@ -11445,9 +11732,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", - "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", "cpu": [ "x64" ], @@ -11462,9 +11749,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", - "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", "cpu": [ "arm64" ], @@ -11479,9 +11766,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/sunos-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", - "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", "cpu": [ "x64" ], @@ -11496,9 +11783,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-arm64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", - "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", "cpu": [ "arm64" ], @@ -11513,9 +11800,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-ia32": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", - "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", "cpu": [ "ia32" ], @@ -11530,9 +11817,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-x64": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", - "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", "cpu": [ "x64" ], @@ -11547,9 +11834,9 @@ } }, "node_modules/tsx/node_modules/esbuild": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", - "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -11560,32 +11847,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.2", - "@esbuild/android-arm": "0.27.2", - "@esbuild/android-arm64": "0.27.2", - "@esbuild/android-x64": "0.27.2", - "@esbuild/darwin-arm64": "0.27.2", - "@esbuild/darwin-x64": "0.27.2", - "@esbuild/freebsd-arm64": "0.27.2", - "@esbuild/freebsd-x64": "0.27.2", - "@esbuild/linux-arm": "0.27.2", - "@esbuild/linux-arm64": "0.27.2", - "@esbuild/linux-ia32": "0.27.2", - "@esbuild/linux-loong64": "0.27.2", - "@esbuild/linux-mips64el": "0.27.2", - "@esbuild/linux-ppc64": "0.27.2", - "@esbuild/linux-riscv64": "0.27.2", - "@esbuild/linux-s390x": "0.27.2", - "@esbuild/linux-x64": "0.27.2", - "@esbuild/netbsd-arm64": "0.27.2", - "@esbuild/netbsd-x64": "0.27.2", - "@esbuild/openbsd-arm64": "0.27.2", - "@esbuild/openbsd-x64": "0.27.2", - "@esbuild/openharmony-arm64": "0.27.2", - "@esbuild/sunos-x64": "0.27.2", - "@esbuild/win32-arm64": "0.27.2", - "@esbuild/win32-ia32": "0.27.2", - "@esbuild/win32-x64": "0.27.2" + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" } }, "node_modules/tween-functions": { @@ -11712,16 +11999,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.54.0.tgz", - "integrity": "sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.2.tgz", + "integrity": "sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.54.0", - "@typescript-eslint/parser": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/utils": "8.54.0" + "@typescript-eslint/eslint-plugin": "8.57.2", + "@typescript-eslint/parser": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11731,7 +12018,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -11755,9 +12042,9 @@ } }, "node_modules/undici": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.20.0.tgz", - "integrity": "sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.6.tgz", + "integrity": "sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==", "dev": true, "license": "MIT", "engines": { @@ -11765,9 +12052,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, "license": "MIT" }, @@ -11845,6 +12132,16 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/use-sync-external-store": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", @@ -11983,31 +12280,31 @@ } }, "node_modules/vitest": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.18.tgz", - "integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.2.tgz", + "integrity": "sha512-xjR1dMTVHlFLh98JE3i/f/WePqJsah4A0FK9cc8Ehp9Udk0AZk6ccpIZhh1qJ/yxVWRZ+Q54ocnD8TXmkhspGg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.0.18", - "@vitest/mocker": "4.0.18", - "@vitest/pretty-format": "4.0.18", - "@vitest/runner": "4.0.18", - "@vitest/snapshot": "4.0.18", - "@vitest/spy": "4.0.18", - "@vitest/utils": "4.0.18", - "es-module-lexer": "^1.7.0", - "expect-type": "^1.2.2", + "@vitest/expect": "4.1.2", + "@vitest/mocker": "4.1.2", + "@vitest/pretty-format": "4.1.2", + "@vitest/runner": "4.1.2", + "@vitest/snapshot": "4.1.2", + "@vitest/spy": "4.1.2", + "@vitest/utils": "4.1.2", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", - "std-env": "^3.10.0", + "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", - "tinyrainbow": "^3.0.3", - "vite": "^6.0.0 || ^7.0.0", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", "why-is-node-running": "^2.3.0" }, "bin": { @@ -12023,12 +12320,13 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.0.18", - "@vitest/browser-preview": "4.0.18", - "@vitest/browser-webdriverio": "4.0.18", - "@vitest/ui": "4.0.18", + "@vitest/browser-playwright": "4.1.2", + "@vitest/browser-preview": "4.1.2", + "@vitest/browser-webdriverio": "4.1.2", + "@vitest/ui": "4.1.2", "happy-dom": "*", - "jsdom": "*" + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@edge-runtime/vm": { @@ -12057,44 +12355,47 @@ }, "jsdom": { "optional": true + }, + "vite": { + "optional": false } } }, "node_modules/vitest/node_modules/@vitest/expect": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.18.tgz", - "integrity": "sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.2.tgz", + "integrity": "sha512-gbu+7B0YgUJ2nkdsRJrFFW6X7NTP44WlhiclHniUhxADQJH5Szt9mZ9hWnJPJ8YwOK5zUOSSlSvyzRf0u1DSBQ==", "dev": true, "license": "MIT", "dependencies": { - "@standard-schema/spec": "^1.0.0", + "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.0.18", - "@vitest/utils": "4.0.18", - "chai": "^6.2.1", - "tinyrainbow": "^3.0.3" + "@vitest/spy": "4.1.2", + "@vitest/utils": "4.1.2", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/vitest/node_modules/@vitest/pretty-format": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz", - "integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.2.tgz", + "integrity": "sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.0.3" + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/vitest/node_modules/@vitest/spy": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz", - "integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.2.tgz", + "integrity": "sha512-DU4fBnbVCJGNBwVA6xSToNXrkZNSiw59H8tcuUspVMsBDBST4nfvsPsEHDHGtWRRnqBERBQu7TrTKskmjqTXKA==", "dev": true, "license": "MIT", "funding": { @@ -12102,14 +12403,15 @@ } }, "node_modules/vitest/node_modules/@vitest/utils": { - "version": "4.0.18", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.18.tgz", - "integrity": "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.2.tgz", + "integrity": "sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.18", - "tinyrainbow": "^3.0.3" + "@vitest/pretty-format": "4.1.2", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, "funding": { "url": "https://opencollective.com/vitest" @@ -12126,9 +12428,9 @@ } }, "node_modules/vitest/node_modules/tinyrainbow": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", - "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", "dev": true, "license": "MIT", "engines": { @@ -12174,6 +12476,29 @@ "dev": true, "license": "MIT" }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/whatwg-mimetype": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", @@ -12185,9 +12510,9 @@ } }, "node_modules/whatwg-url": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.0.tgz", - "integrity": "sha512-9CcxtEKsf53UFwkSUZjG+9vydAsFO4lFHBpJUtjBcoJOCJpKnSJNwCw813zrYJHpCJ7sgfbtOe0V5Ku7Pa1XMQ==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", "dev": true, "license": "MIT", "dependencies": { @@ -12404,9 +12729,9 @@ } }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index da998cb2..0db7c3ae 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "i18n:transform": "tsx scripts/i18nTransform.ts" }, "dependencies": { + "@stomp/stompjs": "^7.3.0", "@tanstack/eslint-plugin-query": "^5.91.4", "@tanstack/react-query": "^5.90.20", "axios": "^1.13.4", @@ -35,6 +36,7 @@ "react-i18next": "^16.5.4", "react-icons": "^5.5.0", "react-router-dom": "^7.13.0", + "sockjs-client": "^1.6.1", "vite-bundle-visualizer": "^1.2.1" }, "devDependencies": { @@ -62,6 +64,7 @@ "@types/pako": "^2.0.3", "@types/react": "^18.3.27", "@types/react-dom": "^18.3.7", + "@types/sockjs-client": "^1.5.4", "@vitejs/plugin-react": "^5.1.3", "autoprefixer": "^10.4.20", "chromatic": "^11.20.2", diff --git a/public/mockServiceWorker.js b/public/mockServiceWorker.js index 461e2600..b17fcd65 100644 --- a/public/mockServiceWorker.js +++ b/public/mockServiceWorker.js @@ -7,7 +7,7 @@ * - Please do NOT modify this file. */ -const PACKAGE_VERSION = '2.12.7' +const PACKAGE_VERSION = '2.12.14' const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82' const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') const activeClientIds = new Set() From 484a8cc3b4d433ce11548270b78df2a158611668 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 14:58:55 +0900 Subject: [PATCH 02/22] =?UTF-8?q?feat:=20=EC=86=8C=EC=BC=93=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EA=B8=B0=EC=B4=88=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EB=B0=8F=20=EC=9D=B8=ED=84=B0=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/type.ts | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/apis/sockets/type.ts diff --git a/src/apis/sockets/type.ts b/src/apis/sockets/type.ts new file mode 100644 index 00000000..7e1fa3dc --- /dev/null +++ b/src/apis/sockets/type.ts @@ -0,0 +1,46 @@ +import { Stance, TimeBoxType } from '../../type/type'; + +// WS ์‚ฌ์šฉ์„ ์œ„ํ•œ ์ด๋ฒคํŠธ ํƒ€์ž… +export type TimerEventTypes = + | 'NEXT' + | 'STOP' + | 'BEFORE' + | 'PLAY' + | 'RESET' + | 'TEAM_SWITCH'; + +// ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ์ด๋ฒคํŠธ +export type NullDataEventTypes = 'FINISHED' | 'ERROR'; + +// ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ˜๋“œ์‹œ ํฌํ•จ๋˜๋Š” ์ด๋ฒคํŠธ +export type SocketEventType = TimerEventTypes | NullDataEventTypes; + +/** ์†Œ์ผ“ ํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š”, ํƒ€์ด๋จธ ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ ํŽ˜์ด๋กœ๋“œ */ +export interface TimerDataPayload { + /** ํƒ€์ด๋จธ ์œ ํ˜• (์ž์œ ํ† ๋ก , ์ผ๋ฐ˜) */ + timerType: Omit; + + /** ํ˜„์žฌ ํƒ€์ด๋จธ ์ˆœ์„œ + * - 0๋ถ€ํ„ฐ ์‹œ์ž‘ + * - `NEXT`, `BEFORE` ์ด๋ฒคํŠธ์˜ ๊ฒฝ์šฐ, ๋ฐœ์–ธํ•ด์•ผ ํ•  ์ฐจ๋ก€์˜ ํƒ€์ด๋จธ ์ˆœ์„œ๋ฅผ ์˜๋ฏธ + */ + sequence: number; + + /** ํ˜„์žฌ ๋ฐœ์–ธํ•˜๊ณ  ์žˆ๋Š” ํŒ€์˜ ์ง„์˜ */ + currentTeam: Stance; + + /** ๋‚จ์€ ์‹œ๊ฐ„ (์ดˆ ๋‹จ์œ„) */ + remainingTime: number; +} + +// ๊ณตํ†ต ๋ฉ”์‹œ์ง€ ๊ตฌ์กฐ +// ๋ฐ์ดํ„ฐ๊ฐ€ null์ธ ์ด๋ฒคํŠธ์™€ ๊ทธ๋ ‡์ง€ ์•Š์€ ์ด๋ฒคํŠธ๋ฅผ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ +export type SocketMessage = + | { + eventType: TimerEventTypes; + data: TimerDataPayload; + } + | { + eventType: NullDataEventTypes; + data: null; + }; From e04b812f34dc5c21b4064bfd768feff0c0f18927 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 14:59:06 +0900 Subject: [PATCH 03/22] =?UTF-8?q?feat:=20=EC=86=8C=EC=BC=93=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EB=8B=B4=EB=8B=B9=ED=95=98=EB=8A=94=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EB=A7=A4=EB=8B=88=EC=A0=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.ts | 225 ++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 src/apis/sockets/SocketManager.ts diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts new file mode 100644 index 00000000..ddec3c7f --- /dev/null +++ b/src/apis/sockets/SocketManager.ts @@ -0,0 +1,225 @@ +import { Client, IMessage, StompHeaders } from '@stomp/stompjs'; +import SockJS from 'sockjs-client'; +import { SocketMessage } from './type'; + +/** + * ์†Œ์ผ“ ์„ค์ •์„ ์ •ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค + * - `maxRetires` ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’ 3ํšŒ) + * - `jitterMs` ๋ฐฑ์—”๋“œ ๋ถ€ํ•˜๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•œ ์ง€ํ„ฐ (๊ธฐ๋ณธ๊ฐ’ 500 ms) + * - `baseRetryDelayMs` ๊ธฐ๋ณธ ์žฌ์‹œ๋„ ๋Œ€๊ธฐ ์‹œ๊ฐ„ (๊ธฐ๋ณธ๊ฐ’ 1000 ms) + * - `heartbeatInMs` ์ˆ˜์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’ 10000 ms) + * - `heartbeatOutMs` ๋ฐœ์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’ 10000 ms) + * - `onConnect` ์—ฐ๊ฒฐ ์‹œ ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ + */ +export interface SocketOptions { + /** ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’: 3) */ + maxRetries?: number; + + /** ๋ฐฑ์—”๋“œ ๋ถ€ํ•˜๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•œ ์ง€ํ„ฐ(๋‚œ์ˆ˜ ๋ถ„์‚ฐ) ๊ฐ’ (๊ธฐ๋ณธ๊ฐ’: 500ms) */ + jitterMs?: number; + + /** ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๊ณ„์‚ฐ์˜ ๊ธฐ์ค€์ด ๋˜๋Š” ์ดˆ๊ธฐ ์ง€์—ฐ ์‹œ๊ฐ„ (๊ธฐ๋ณธ๊ฐ’: 1000ms) */ + baseRetryDelayMs?: number; + + /** ์ˆ˜์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’: 10000ms) */ + heartbeatInMs?: number; + + /** ๋ฐœ์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’: 10000ms) */ + heartbeatOutMs?: number; + + /** ์—ฐ๊ฒฐ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜๋ฆฝ๋œ ์งํ›„ ์‹คํ–‰๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ */ + onConnect?: () => void; +} + +// ๊ธฐ๋ณธ๊ฐ’ ๊ฐ์ฒด ์„ ์–ธ (onConnect๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ํ•„์ˆ˜ ์†์„ฑ ์ •์˜) +const DEFAULT_OPTIONS: Required> = { + maxRetries: 3, + jitterMs: 500, + baseRetryDelayMs: 1000, + heartbeatInMs: 10000, + heartbeatOutMs: 10000, +}; + +// ์†Œ์ผ“ ํ†ต์‹ ์„ ๋‹ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค +class SocketManager { + // ๋ณ€์ˆ˜ + private client: Client | null = null; + private static instance: SocketManager; + private currentOptions = DEFAULT_OPTIONS; // ์†Œ์ผ“ ์„ค์ •์„ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜ + private retryCount: number = 0; + + // ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ์ ์šฉ + // - ์ƒ์„ฑ์ž๋ฅผ ์ฐจ๋‹จํ•˜์—ฌ ์™ธ๋ถ€์—์„œ์˜ ๊ฐ์ฒด ์ƒ์„ฑ์„ ๋ง‰์Œ + private constructor() {} + + // - ์˜ค์ง ํด๋ž˜์Šค ์ˆ˜์ค€ ๋ณ€์ˆ˜์—์„œ๋งŒ ์ธ์Šคํ„ด์Šค์— ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ œํ•œ + public static getInstance(): SocketManager { + if (!SocketManager.instance) { + SocketManager.instance = new SocketManager(); + } + return SocketManager.instance; + } + + /** + * ์›น ์†Œ์ผ“(STOMP) ์—ฐ๊ฒฐ์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์„œ๋ฒ„์™€ ์„ธ์…˜์„ ์ˆ˜๋ฆฝํ•ฉ๋‹ˆ๋‹ค. + * HTTPS์—์„œ WS๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ์‹œ ์ฒญ์ค‘๊ณผ ์‚ฌํšŒ์ž ๋ชจ๋‘ ๋ฌด์ธ์ฆ์œผ๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. + * + * @param options - ์†Œ์ผ“ ํด๋ผ์ด์–ธํŠธ ๋™์ž‘์„ ์ œ์–ดํ•˜๋Š” ์„ ํƒ์  ์„ค์ • ๊ฐ์ฒด + * @param options.maxRetries - ์ตœ๋Œ€ ์žฌ์—ฐ๊ฒฐ ์‹œ๋„ ํšŸ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’: 3) + * @param options.jitterMs - ์žฌ์—ฐ๊ฒฐ ์ง€์—ฐ ์‹œ๊ฐ„์— ์ถ”๊ฐ€๋  ์ง€ํ„ฐ(๋‚œ์ˆ˜ ๋ถ„์‚ฐ) ๊ฐ’ (๊ธฐ๋ณธ๊ฐ’: 500) + * @param options.baseRetryDelayMs - ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๊ณ„์‚ฐ์˜ ๊ธฐ์ค€์ด ๋˜๋Š” ์ดˆ๊ธฐ ์ง€์—ฐ ์‹œ๊ฐ„ (๊ธฐ๋ณธ๊ฐ’: 1000) + * @param options.heartbeatInMs - ์„œ๋ฒ„ > ํด๋ผ์ด์–ธํŠธ ์ˆ˜์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ(ms) (๊ธฐ๋ณธ๊ฐ’: 10000) + * @param options.heartbeatOutMs - ํด๋ผ์ด์–ธํŠธ > ์„œ๋ฒ„ ๋ฐœ์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ(ms) (๊ธฐ๋ณธ๊ฐ’: 10000) + * @param options.onConnect - ์—ฐ๊ฒฐ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜๋ฆฝ๋œ ์งํ›„ ์‹คํ–‰๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ + */ + public connect(options?: SocketOptions) { + // ์ด๋ฏธ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์กด์žฌํ•˜๊ณ  ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ค‘๋ณต ์—ฐ๊ฒฐ ๋ฐฉ์ง€ + if (this.client && this.client.active) return; + + // ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •ํ•œ ์˜ต์…˜์ด ์žˆ๋‹ค๋ฉด ๋ฎ์–ด์“ฐ๊ธฐ + this.currentOptions = { ...DEFAULT_OPTIONS, ...options }; + + // ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ URL ๋กœ๋“œ + const wsUrl = import.meta.env.VITE_WS_BASE_URL; + + this.client = new Client({ + // wss:// ๋Œ€์‹  https:// ์ฃผ์†Œ๋ฅผ SockJS ํŒฉํ† ๋ฆฌ์— ์ฃผ์ž… + webSocketFactory: () => new SockJS(wsUrl), + + // ๋””๋ฒ„๊ทธ ๋กœ๊ทธ + debug: (str) => { + console.log('[STOMP DEBUG]', str); + }, + + // ์ž๋™ ์žฌ์—ฐ๊ฒฐ ๊ฐ„๊ฒฉ (์ง€์ˆ˜ ๋ฐฑ์˜คํ”„๋Š” ์ปค์Šคํ…€ ๊ตฌํ˜„์ด ํ•„์š”ํ•˜๋‚˜, ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์œผ๋กœ 5์ดˆ ์„ค์ •) + reconnectDelay: this.calculateBackoffDelay(0), + + // ํ•˜ํŠธ๋น„ํŠธ + heartbeatIncoming: this.currentOptions.heartbeatInMs, + heartbeatOutgoing: this.currentOptions.heartbeatOutMs, + + onConnect: () => { + console.log('โœ… ์›น ์†Œ์ผ“(STOMP) ์—ฐ๊ฒฐ ์„ฑ๊ณต'); + this.retryCount = 0; + + // ์˜ต์…˜์œผ๋กœ ์ „๋‹ฌ๋œ ์ฝœ๋ฐฑ์ด ์žˆ๋‹ค๋ฉด ์‹คํ–‰ + if (options?.onConnect) { + options.onConnect(); + } + }, + + onStompError: (frame) => { + console.error('โŒ ๋ธŒ๋กœ์ปค ์—๋Ÿฌ ๋ฐœ์ƒ:', frame.headers['message']); + console.error('์ƒ์„ธ ๋‚ด์šฉ:', frame.body); + }, + + onWebSocketClose: () => { + console.log('โš ๏ธ ์›น ์†Œ์ผ“ ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.'); + this.handleReconnection(); + }, + }); + + // ์‹ค์ œ ์—ฐ๊ฒฐ ์‹œ๋™ + this.client.activate(); + } + + /** + * ์†Œ์ผ“ ์—ฐ๊ฒฐ ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ + */ + public disconnect() { + if (this.client && this.client.active) { + // ํด๋ผ์ด์–ธํŠธ ๋น„ํ™œ์„ฑํ™” + this.client.deactivate(); + + // ๊ฐ์ข… ์„ค์ • ์ดˆ๊ธฐํ™” + this.retryCount = 0; + this.client = null; + this.currentOptions = DEFAULT_OPTIONS; + + console.log('๐Ÿ›‘ ์›น ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ์ˆ˜๋™์œผ๋กœ ํ•ด์ œํ–ˆ์Šต๋‹ˆ๋‹ค.'); + } + } + + /** + * ํŠน์ • ์ฑ„๋„ ๊ตฌ๋… (์ˆ˜์‹ ) + * @param destination - ๊ตฌ๋…ํ•  ์ฑ„๋„ (e.g., '/chairman/{roomId}) + * @param callback - ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•ด ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ + */ + public subscribe(destination: string, callback: (message: IMessage) => void) { + if (!this.client || !this.client.connected) { + console.warn('์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์•„ ๊ตฌ๋…ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.'); + return null; + } + // ๊ตฌ๋… ๊ฐ์ฒด ๋ฐ˜ํ™˜ (๋‚˜์ค‘์— unsubscribe ํ•  ๋•Œ ํ•„์š”ํ•จ) + return this.client.subscribe(destination, callback); + } + + /** + * ํŠน์ • ์ฑ„๋„๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœํ–‰(์ „์†ก)ํ•ฉ๋‹ˆ๋‹ค. + * @param destination - ๋ชฉ์ ์ง€ ์ฑ„๋„ (e.g., '/chairman/{roomId}) + * @param body - ์ „์†กํ•  ๋ฐ์ดํ„ฐ (๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ „๋‹ฌํ•˜๋ฉด ๋‚ด๋ถ€์—์„œ JSON ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋จ) + * @param headers - ์ถ”๊ฐ€์ ์œผ๋กœ ์ฒจ๋ถ€ํ•  STOMP ํ—ค๋” (์„ ํƒ ์‚ฌํ•ญ) + */ + public publish( + destination: string, + body: SocketMessage, + headers?: StompHeaders, + ): void { + if (!this.client || !this.client.connected) { + console.warn('์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์•„ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.'); + return; + } + + this.client.publish({ + destination, + headers, + body: JSON.stringify(body), + }); + } + + /** + * ๋‚ด๋ถ€์ ์œผ๋กœ ์—ฐ๊ฒฐ ์žฌ์‹œ๋„๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜ + */ + private handleReconnection() { + // ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—†์„ ์‹œ + if (!this.client) { + return; + } + + // ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ์ดˆ๊ณผํ–ˆ์„ ๊ฒฝ์šฐ ์—ฐ๊ฒฐ์„ ์ฆ‰์‹œ ์ข…๋ฃŒ + if (this.retryCount >= this.currentOptions.maxRetries) { + console.error( + '๐Ÿšจ ์ตœ๋Œ€ ์žฌ์—ฐ๊ฒฐ ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ์ดˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์„ ํฌ๊ธฐํ•ฉ๋‹ˆ๋‹ค.', + ); + this.client.reconnectDelay = 0; + this.client.deactivate(); + return; + } + + // ์•„์ง ์žฌ์‹œ๋„ ํšŸ์ˆ˜๊ฐ€ ๋‚จ์•˜์„ ๊ฒฝ์šฐ, ์žฌ์‹œ๋„ ๋”œ๋ ˆ์ด๋ฅผ ๊ฐฑ์‹  + const nextDelay = this.calculateBackoffDelay(this.retryCount); + this.client.reconnectDelay = nextDelay; + this.retryCount++; + + console.log( + `๐Ÿ”„ ์žฌ์—ฐ๊ฒฐ ์‹œ๋„ ๋Œ€๊ธฐ ์ค‘... (${this.retryCount}/${this.currentOptions.maxRetries}) - ${nextDelay}ms ํ›„ ์‹œ๋„`, + ); + } + + /** + * ํ˜„์žฌ ํšŸ์ˆ˜์— ๋”ฐ๋ผ ์žฌ์—ฐ๊ฒฐ ์š”์ฒญ ๋”œ๋ ˆ์ด๋ฅผ ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๋ฐฉ์‹์œผ๋กœ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜ + * - ๊ณ„์‚ฐ์‹์€ `๋”œ๋ ˆ์ด = ๊ธฐ๋ณธ ์žฌ์‹œ๋„ ๋Œ€๊ธฐ ์‹œ๊ฐ„ * 2 ^ ํ˜„์žฌ ์žฌ์‹œ๋„ ํšŸ์ˆ˜` + * - ๊ธฐ๋ณธ ์žฌ์‹œ๋„ ๋Œ€๊ธฐ ์‹œ๊ฐ„์€ ์†Œ์ผ“ ์—ฐ๊ฒฐ ์‹œ `SocketOptions`์—์„œ ์ง€์ • + * - ํ˜„์žฌ ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋Š” ์†Œ์ผ“ ์—ฐ๊ฒฐ ํ›„ ์ธ์Šคํ„ด์Šค ์ˆ˜์ค€ ๋ณ€์ˆ˜๋กœ ๋‚ด๋ถ€์—์„œ ๊ด€๋ฆฌ๋จ + * @param currentRetryCount ํ˜„์žฌ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ + * @returns ์žฌ์—ฐ๊ฒฐ ์š”์ฒญ๊นŒ์ง€ ํ•„์š”ํ•œ ๋”œ๋ ˆ์ด ์‹œ๊ฐ„ + */ + private calculateBackoffDelay(currentRetryCount: number): number { + const exponentialDelay = + this.currentOptions.baseRetryDelayMs * Math.pow(2, currentRetryCount); + return exponentialDelay + this.currentOptions.jitterMs; + } +} + +// ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์—ญ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์‹ฑ๊ธ€ํ†ค ํ•จ์ˆ˜๋งŒ ๋…ธ์ถœ +export const socketManager = SocketManager.getInstance(); From dc5855500d3e7ada758bf30cb4a1257347442807 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 14:59:15 +0900 Subject: [PATCH 04/22] =?UTF-8?q?feat:=20=EC=86=8C=EC=BC=93=20=EB=A7=A4?= =?UTF-8?q?=EB=8B=88=EC=A0=80=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8A=94=20React=20=ED=9B=85=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useSocket.ts | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/hooks/useSocket.ts diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts new file mode 100644 index 00000000..b773a5a9 --- /dev/null +++ b/src/hooks/useSocket.ts @@ -0,0 +1,94 @@ +import { useEffect, useRef, useCallback } from 'react'; +import { IMessage, StompHeaders, StompSubscription } from '@stomp/stompjs'; +import { socketManager, SocketOptions } from '../apis/sockets/SocketManager'; + +export const useSocket = () => { + // ํ˜„์žฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ™œ์„ฑํ™”ํ•œ ๊ตฌ๋…์„ ์ €์žฅํ•˜๋Š” ๋ณด๊ด€์†Œ + const subscriptions = useRef>(new Map()); + + // ์—ฐ๊ฒฐ + const connect = useCallback((options?: SocketOptions) => { + socketManager.connect(options); + }, []); + + // ํ•ด์ œ + const disconnect = useCallback(() => { + socketManager.disconnect(); + }, []); + + // ๋ฉ”์‹œ์ง€ ๋ฐœ์‹  (Publish) + const publish = useCallback( + (destination: string, body: T, headers: StompHeaders) => { + socketManager.publish(destination, body, headers); + }, + [], + ); + + /** + * ๊ตฌ๋… (Subscribe) + * + * ์ด ํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ ์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋œ ๋’ค์— ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค! + * ๋” ์ •ํ™•ํžˆ ๋งํ•˜๋ฉด, ์†Œ์ผ“์ด ์—ฐ๊ฒฐ ์„ฑ๊ณต ํ›„์— ์‹คํ–‰ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ธ `onConnect` ์•ˆ์— + * ๊ตฌ๋… ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”. + * ์• ์ดˆ์— ์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋˜๊ธฐ๋„ ์ „์— ๊ตฌ๋…์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ๋ชจ์ˆœ์ ์ธ ์ผ์ด๋‹ˆ๊นŒ์š”. + * + * ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด์š”: + * ``` + * useEffect(() => { + * connect({ + * onConnect: () => { + * // โœ… ์†Œ์ผ“ ์—ฐ๊ฒฐ์ด ์™„์ „ํžˆ ๋๋‚œ ๋’ค์— ๊ตฌ๋…ํ•ด์•ผ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค! + * subscribe('/topic/room/123', (msg) => console.log(msg)); + * } + * }); + * }, []); + * ``` + */ + const subscribe = useCallback( + (destination: string, callback: (message: IMessage) => void) => { + // ์ด๋ฏธ ํ•ด๋‹น ์ฑ„๋„์„ ๊ตฌ๋… ์ค‘์ด๋ฉด ์ค‘๋ณต ๊ตฌ๋… ๋ฐฉ์ง€ + if (subscriptions.current.has(destination)) return; + + // ๊ตฌ๋… ์ค‘์ด์ง€ ์•Š๋‹ค๋ฉด, ๊ตฌ๋… ์š”์ฒญ ํ›„ ์„ฑ๊ณต ์‹œ useRef๋กœ ์œ ์ง€ํ•˜๋Š” Map์— ์ €์žฅ + const subscription = socketManager.subscribe(destination, callback); + if (subscription) { + subscriptions.current.set(destination, subscription); + } + }, + [], + ); + + // ์ˆ˜๋™ ๊ตฌ๋… ํ•ด์ œ + const unsubscribe = useCallback((destination: string) => { + const subscription = subscriptions.current.get(destination); + if (subscription) { + subscription.unsubscribe(); // STOMP ์„œ๋ฒ„์— ํ•ด์ œ ์š”์ฒญ + subscriptions.current.delete(destination); // ๋งต์—์„œ ์ œ๊ฑฐ + } + }, []); + + // ํด๋ฆฐ์—… + useEffect(() => { + return () => { + // ํ˜„์žฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งŒ๋“ค์–ด๋‘” ๋ชจ๋“  ๊ตฌ๋…์„ ์ˆœํšŒํ•˜๋ฉฐ ์ผ๊ด„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. + subscriptions.current.forEach((sub) => sub.unsubscribe()); + + // ์•„๋ž˜ Ref์˜ ๊ฒฝ์šฐ React์— ์˜ํ•ด ๋ Œ๋”๋ง๋˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง€์‹œํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, + // ์ฃผ์„์˜ ๊ฒฝ๊ณ ์™€ ์ „ํ˜€ ์—ฐ๊ด€์ด ์—†์œผ๋ฏ€๋กœ ๊ฒฝ๊ณ ๋ฅผ ๊บผ ๋‘ก๋‹ˆ๋‹ค. + // eslint-disable-next-line react-hooks/exhaustive-deps + subscriptions.current.clear(); + + // ํŽ˜์ด์ง€๋ฅผ ๋‚˜๊ฐˆ ๋•Œ ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ๋Š์„ ๊ฒƒ์ธ๊ฐ€? (์ •์ฑ… ๊ฒฐ์ • ํ›„ ์ˆ˜์ • ์˜ˆ์ •) + // socketManager.disconnect(); + }; + }, []); + + // ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•  ํ•จ์ˆ˜๋“ค๋งŒ ๋ฐ˜ํ™˜ + return { + connect, + disconnect, + subscribe, + unsubscribe, + publish, + }; +}; From e6c7458c2246b016e44c337abfa4b2d4a927f443 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 15:06:45 +0900 Subject: [PATCH 05/22] =?UTF-8?q?refactor:=20=EC=9D=B4=ED=95=B4=EA=B0=80?= =?UTF-8?q?=20=EC=89=BD=EA=B2=8C=20=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/type.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apis/sockets/type.ts b/src/apis/sockets/type.ts index 7e1fa3dc..2e6216fa 100644 --- a/src/apis/sockets/type.ts +++ b/src/apis/sockets/type.ts @@ -10,10 +10,10 @@ export type TimerEventTypes = | 'TEAM_SWITCH'; // ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ์ด๋ฒคํŠธ -export type NullDataEventTypes = 'FINISHED' | 'ERROR'; +export type NonTimerEventType = 'FINISHED' | 'ERROR'; // ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ˜๋“œ์‹œ ํฌํ•จ๋˜๋Š” ์ด๋ฒคํŠธ -export type SocketEventType = TimerEventTypes | NullDataEventTypes; +export type SocketEventType = TimerEventTypes | NonTimerEventType; /** ์†Œ์ผ“ ํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š”, ํƒ€์ด๋จธ ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ ํŽ˜์ด๋กœ๋“œ */ export interface TimerDataPayload { @@ -41,6 +41,6 @@ export type SocketMessage = data: TimerDataPayload; } | { - eventType: NullDataEventTypes; + eventType: NonTimerEventType; data: null; }; From a96db1eb9407c3f36a5ccac41ca3f571e9259d83 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 15:24:04 +0900 Subject: [PATCH 06/22] =?UTF-8?q?chore:=20WS=20URL=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts index ddec3c7f..1683eac2 100644 --- a/src/apis/sockets/SocketManager.ts +++ b/src/apis/sockets/SocketManager.ts @@ -80,7 +80,7 @@ class SocketManager { this.currentOptions = { ...DEFAULT_OPTIONS, ...options }; // ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ URL ๋กœ๋“œ - const wsUrl = import.meta.env.VITE_WS_BASE_URL; + const wsUrl = import.meta.env.VITE_API_BASE_URL + '/ws'; this.client = new Client({ // wss:// ๋Œ€์‹  https:// ์ฃผ์†Œ๋ฅผ SockJS ํŒฉํ† ๋ฆฌ์— ์ฃผ์ž… From 8ba66828d170286c5c85df0b4c467c089b07c582 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 15:24:26 +0900 Subject: [PATCH 07/22] =?UTF-8?q?fix:=20=ED=9B=85=EC=97=90=EC=84=9C?= =?UTF-8?q?=EB=8F=84=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=9D=84=20=EC=A0=9C=EB=84=A4=EB=A6=AD=EC=9D=B4=20=EC=95=84?= =?UTF-8?q?=EB=8B=88=EB=9D=BC=20=EB=AA=85=EC=8B=9C=EC=A0=81=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useSocket.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index b773a5a9..0efe22f5 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -1,6 +1,7 @@ import { useEffect, useRef, useCallback } from 'react'; import { IMessage, StompHeaders, StompSubscription } from '@stomp/stompjs'; import { socketManager, SocketOptions } from '../apis/sockets/SocketManager'; +import { SocketMessage } from '../apis/sockets/type'; export const useSocket = () => { // ํ˜„์žฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ™œ์„ฑํ™”ํ•œ ๊ตฌ๋…์„ ์ €์žฅํ•˜๋Š” ๋ณด๊ด€์†Œ @@ -18,7 +19,7 @@ export const useSocket = () => { // ๋ฉ”์‹œ์ง€ ๋ฐœ์‹  (Publish) const publish = useCallback( - (destination: string, body: T, headers: StompHeaders) => { + (destination: string, body: SocketMessage, headers: StompHeaders) => { socketManager.publish(destination, body, headers); }, [], From 2377413672be9ad06e207e151a41cfdc8b3c0047 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 15:24:38 +0900 Subject: [PATCH 08/22] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=96=B8=EB=A7=88=EC=9A=B4=ED=8A=B8=20=EC=8B=9C=20=EC=86=8C?= =?UTF-8?q?=EC=BC=93=20=EB=81=8A=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useSocket.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 0efe22f5..b4ca9318 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -80,7 +80,7 @@ export const useSocket = () => { subscriptions.current.clear(); // ํŽ˜์ด์ง€๋ฅผ ๋‚˜๊ฐˆ ๋•Œ ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ๋Š์„ ๊ฒƒ์ธ๊ฐ€? (์ •์ฑ… ๊ฒฐ์ • ํ›„ ์ˆ˜์ • ์˜ˆ์ •) - // socketManager.disconnect(); + socketManager.disconnect(); }; }, []); From e18fd80fe9c0c9ab028ed66e7b2db99ae55d13a6 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 15:39:53 +0900 Subject: [PATCH 09/22] =?UTF-8?q?feat:=20=ED=92=80=20=EC=A7=80=ED=84=B0=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts index 1683eac2..5de0cc2b 100644 --- a/src/apis/sockets/SocketManager.ts +++ b/src/apis/sockets/SocketManager.ts @@ -207,17 +207,18 @@ class SocketManager { } /** - * ํ˜„์žฌ ํšŸ์ˆ˜์— ๋”ฐ๋ผ ์žฌ์—ฐ๊ฒฐ ์š”์ฒญ ๋”œ๋ ˆ์ด๋ฅผ ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๋ฐฉ์‹์œผ๋กœ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜ - * - ๊ณ„์‚ฐ์‹์€ `๋”œ๋ ˆ์ด = ๊ธฐ๋ณธ ์žฌ์‹œ๋„ ๋Œ€๊ธฐ ์‹œ๊ฐ„ * 2 ^ ํ˜„์žฌ ์žฌ์‹œ๋„ ํšŸ์ˆ˜` + * ํ˜„์žฌ ํšŸ์ˆ˜์— ๋”ฐ๋ผ ์žฌ์—ฐ๊ฒฐ ์š”์ฒญ ๋”œ๋ ˆ์ด๋ฅผ ํ’€ ์ง€ํ„ฐ + ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๋ฐฉ์‹์œผ๋กœ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. (0, ์ตœ๋Œ€ ๋”œ๋ ˆ์ด ์ƒํ•œ์„ ) ์‚ฌ์ด ๋‚œ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + * - `์ตœ๋Œ€ ๋”œ๋ ˆ์ด ์ƒํ•œ์„  = ๊ธฐ๋ณธ ์žฌ์‹œ๋„ ๋Œ€๊ธฐ ์‹œ๊ฐ„ * 2 ^ ํ˜„์žฌ ์žฌ์‹œ๋„ ํšŸ์ˆ˜` * - ๊ธฐ๋ณธ ์žฌ์‹œ๋„ ๋Œ€๊ธฐ ์‹œ๊ฐ„์€ ์†Œ์ผ“ ์—ฐ๊ฒฐ ์‹œ `SocketOptions`์—์„œ ์ง€์ • * - ํ˜„์žฌ ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋Š” ์†Œ์ผ“ ์—ฐ๊ฒฐ ํ›„ ์ธ์Šคํ„ด์Šค ์ˆ˜์ค€ ๋ณ€์ˆ˜๋กœ ๋‚ด๋ถ€์—์„œ ๊ด€๋ฆฌ๋จ * @param currentRetryCount ํ˜„์žฌ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ * @returns ์žฌ์—ฐ๊ฒฐ ์š”์ฒญ๊นŒ์ง€ ํ•„์š”ํ•œ ๋”œ๋ ˆ์ด ์‹œ๊ฐ„ */ private calculateBackoffDelay(currentRetryCount: number): number { - const exponentialDelay = + // ์ตœ๋Œ€ ์ง€ํ„ฐ ์ƒํ•œ์„  ๊ณ„์‚ฐ + const maxExponentialDelay = this.currentOptions.baseRetryDelayMs * Math.pow(2, currentRetryCount); - return exponentialDelay + this.currentOptions.jitterMs; + return Math.floor(Math.random() * maxExponentialDelay); } } From 1b7ebfdf6c41f5a677aa90bf16e08d333ca955e5 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sat, 28 Mar 2026 16:50:06 +0900 Subject: [PATCH 10/22] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.test.ts | 236 +++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 src/apis/sockets/SocketManager.test.ts diff --git a/src/apis/sockets/SocketManager.test.ts b/src/apis/sockets/SocketManager.test.ts new file mode 100644 index 00000000..192c807c --- /dev/null +++ b/src/apis/sockets/SocketManager.test.ts @@ -0,0 +1,236 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { socketManager } from './SocketManager'; +import type { IMessage, StompConfig } from '@stomp/stompjs'; +import { SocketMessage } from './type'; + +// ------------------------------------------------------------------ +// 1. ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Mocking +// ------------------------------------------------------------------ + +vi.mock('sockjs-client', () => ({ default: vi.fn() })); + +/** + * vi.hoisted: vi.mock ํŒฉํ† ๋ฆฌ๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰๋จ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. + * ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ์ƒ์„ฑ๋œ Client ์ธ์Šคํ„ด์Šค๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. + */ +const clientInstances = vi.hoisted( + (): { + activate: ReturnType; + deactivate: ReturnType; + publish: ReturnType; + subscribe: ReturnType; + active: boolean; + connected: boolean; + reconnectDelay: number; + config: StompConfig; + }[] => [], +); + +/** + * ํ•ต์‹ฌ ์ „๋žต: vi.fn().mockImplementation() ๋ฐฉ์‹์„ ๋ฒ„๋ฆฌ๊ณ , + * vi.mock ํŒฉํ† ๋ฆฌ ๋‚ด๋ถ€์— ์ง„์งœ ํด๋ž˜์Šค๋ฅผ ์ง์ ‘ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. + * + * vi.clearAllMocks / vi.resetAllMocks๋Š” vi.fn()์˜ ๊ตฌํ˜„์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์ง€๋งŒ, + * ํŒฉํ† ๋ฆฌ ํด๋กœ์ € ๋‚ด๋ถ€์— ์ •์˜๋œ ํด๋ž˜์Šค ์ž์ฒด๋Š” ์ ˆ๋Œ€ ๊ฑด๋“œ๋ฆฌ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. + * ๋”ฐ๋ผ์„œ new Client()๋Š” ํ•ญ์ƒ ์˜ฌ๋ฐ”๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. + */ +vi.mock('@stomp/stompjs', () => { + class MockClient { + activate = vi.fn(); + deactivate = vi.fn(); + publish = vi.fn(); + subscribe = vi.fn(); + active = true; + connected = false; + reconnectDelay: number; + config: StompConfig; + + constructor(config: StompConfig) { + this.config = config; + this.reconnectDelay = config?.reconnectDelay ?? 0; + clientInstances.push(this); + } + } + + return { Client: MockClient }; +}); + +// ------------------------------------------------------------------ +// 2. ํ—ฌํผ +// ------------------------------------------------------------------ + +/** ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ƒ์„ฑ๋œ Client ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. */ +const getLatestClient = () => clientInstances[clientInstances.length - 1]; + +// ------------------------------------------------------------------ +// 3. ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ +// ------------------------------------------------------------------ + +describe('SocketManager', () => { + beforeEach(() => { + /** + * ์ˆœ์„œ ์ค‘์š”: + * 1. disconnect ๋จผ์ € โ†’ ์ด์ „ ํ…Œ์ŠคํŠธ์˜ client.active = true์ด๋ฏ€๋กœ deactivate ์‹คํ–‰, client = null ์ฒ˜๋ฆฌ + * 2. ์ธ์Šคํ„ด์Šค ๋ฐฐ์—ด ์ดˆ๊ธฐํ™” + * 3. vi.fn() ํ˜ธ์ถœ ๊ธฐ๋ก ์ดˆ๊ธฐํ™” (MockClient ํด๋ž˜์Šค ์ž์ฒด์—๋Š” ์˜ํ–ฅ ์—†์Œ) + */ + socketManager.disconnect(); + clientInstances.length = 0; + vi.clearAllMocks(); + vi.stubEnv('VITE_API_BASE_URL', 'https://test.com'); + }); + + afterEach(() => { + vi.unstubAllEnvs(); + }); + + // --- [๊ทธ๋ฃน 1] ์—ฐ๊ฒฐ & ํ•ด์ œ --- + describe('Connection & Disconnection', () => { + it('connect ํ˜ธ์ถœ ์‹œ Client ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  activate๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค', () => { + socketManager.connect(); + + expect(clientInstances).toHaveLength(1); + expect(getLatestClient().activate).toHaveBeenCalledOnce(); + }); + + it('์ด๋ฏธ ์—ฐ๊ฒฐ๋œ ์ƒํƒœ์—์„œ connect๋ฅผ ์žฌํ˜ธ์ถœํ•˜๋ฉด ์ค‘๋ณต ์—ฐ๊ฒฐ์„ ๋ฐฉ์ง€ํ•ด์•ผ ํ•œ๋‹ค', () => { + socketManager.connect(); + socketManager.connect(); + + // Client ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•œ๋‹ค + expect(clientInstances).toHaveLength(1); + }); + + it('disconnect ํ˜ธ์ถœ ์‹œ deactivate๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค', () => { + socketManager.connect(); + const client = getLatestClient(); + + socketManager.disconnect(); + + expect(client.deactivate).toHaveBeenCalledOnce(); + }); + + it('disconnect ํ›„ ์žฌ์—ฐ๊ฒฐํ•˜๋ฉด ์ƒˆ Client ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค', () => { + socketManager.connect(); + socketManager.disconnect(); + socketManager.connect(); + + expect(clientInstances).toHaveLength(2); + expect(getLatestClient().activate).toHaveBeenCalledOnce(); + }); + }); + + // --- [๊ทธ๋ฃน 2] ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ์žฌ์—ฐ๊ฒฐ --- + describe('Reconnection & Full Jitter Backoff', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + /** + * calculateBackoffDelay(retryCount) = floor(random * base * 2^retryCount) + * handleReconnection()์€ ํ˜„์žฌ retryCount๋กœ ๋”œ๋ ˆ์ด๋ฅผ ๊ณ„์‚ฐํ•œ ํ›„ retryCount๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค. + * + * Math.random = 0.5, baseRetryDelayMs = 1000 ๊ณ ์ • ์‹œ: + * ์ดˆ๊ธฐ connect: calculateBackoffDelay(0) = floor(0.5 * 1000 * 2^0) = 500 + * 1๋ฒˆ์งธ close: calculateBackoffDelay(0) = floor(0.5 * 1000 * 2^0) = 500 โ†’ retryCount: 0 โ†’ 1 + * 2๋ฒˆ์งธ close: calculateBackoffDelay(1) = floor(0.5 * 1000 * 2^1) = 1000 โ†’ retryCount: 1 โ†’ 2 + */ + it('onWebSocketClose ๋ฐœ์ƒ ์‹œ ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๋”œ๋ ˆ์ด๋ฅผ ๊ฐฑ์‹ ํ•ด์•ผ ํ•œ๋‹ค', () => { + vi.spyOn(Math, 'random').mockReturnValue(0.5); + socketManager.connect({ baseRetryDelayMs: 1000 }); + + const client = getLatestClient(); + + // ์ดˆ๊ธฐ ๋”œ๋ ˆ์ด: calculateBackoffDelay(0) = 500 + expect(client.reconnectDelay).toBe(500); + + // 1๋ฒˆ์งธ ๋Š๊น€: retryCount=0 ๊ธฐ์ค€ ๊ณ„์‚ฐ โ†’ 500, ์ดํ›„ retryCount=1 + client.config.onWebSocketClose?.({} as CloseEvent); + expect(client.reconnectDelay).toBe(500); + + // 2๋ฒˆ์งธ ๋Š๊น€: retryCount=1 ๊ธฐ์ค€ ๊ณ„์‚ฐ โ†’ 1000, ์ดํ›„ retryCount=2 + client.config.onWebSocketClose?.({} as CloseEvent); + expect(client.reconnectDelay).toBe(1000); + }); + + it('์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜(maxRetries) ์ดˆ๊ณผ ์‹œ reconnectDelay๋ฅผ 0์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•ด์•ผ ํ•œ๋‹ค', () => { + socketManager.connect({ maxRetries: 3 }); + const client = getLatestClient(); + + // 3๋ฒˆ๊นŒ์ง€๋Š” ์•„์ง maxRetries ๋ฏธ์ดˆ๊ณผ โ†’ deactivate ํ˜ธ์ถœ ์•ˆ ๋จ + for (let i = 0; i < 3; i++) { + client.config.onWebSocketClose?.({} as CloseEvent); + } + expect(client.deactivate).not.toHaveBeenCalled(); + + // 4๋ฒˆ์งธ ๋Š๊น€: retryCount(3) >= maxRetries(3) โ†’ ํฌ๊ธฐ + client.config.onWebSocketClose?.({} as CloseEvent); + expect(client.reconnectDelay).toBe(0); + expect(client.deactivate).toHaveBeenCalledOnce(); + }); + + it('onConnect ์‹คํ–‰ ์‹œ retryCount๊ฐ€ 0์œผ๋กœ ๋ฆฌ์…‹๋˜์–ด์•ผ ํ•œ๋‹ค', () => { + vi.spyOn(Math, 'random').mockReturnValue(0.5); + socketManager.connect({ baseRetryDelayMs: 1000, maxRetries: 5 }); + const client = getLatestClient(); + + // ๋Š๊น€ 2๋ฒˆ โ†’ retryCount = 2 + client.config.onWebSocketClose?.({} as CloseEvent); + client.config.onWebSocketClose?.({} as CloseEvent); + + // ์žฌ์—ฐ๊ฒฐ ์„ฑ๊ณต โ†’ retryCount 0์œผ๋กœ ๋ฆฌ์…‹ + client.config.onConnect?.({} as IMessage); + + // ๋Š๊น€ 1๋ฒˆ: retryCount=0 ๊ธฐ์ค€ ๊ณ„์‚ฐ โ†’ 500 (retryCount๊ฐ€ ๋ฆฌ์…‹๋์œผ๋ฏ€๋กœ) + client.config.onWebSocketClose?.({} as CloseEvent); + expect(client.reconnectDelay).toBe(500); + }); + }); + + // --- [๊ทธ๋ฃน 3] ๊ตฌ๋… & ๋ฐœํ–‰ --- + describe('Subscribe & Publish', () => { + it('์—ฐ๊ฒฐ ์ „ subscribe ํ˜ธ์ถœ ์‹œ null์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค', () => { + const result = socketManager.subscribe('/topic/test', vi.fn()); + expect(result).toBeNull(); + }); + + it('์—ฐ๊ฒฐ ํ›„ subscribe ํ˜ธ์ถœ ์‹œ client.subscribe๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค', () => { + socketManager.connect(); + const client = getLatestClient(); + client.connected = true; // ์—ฐ๊ฒฐ ์™„๋ฃŒ ์ƒํƒœ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ + + const callback = () => console.log('test'); + socketManager.subscribe('/topic/test', callback); + + expect(client.subscribe).toHaveBeenCalledWith('/topic/test', callback); + }); + + it('์—ฐ๊ฒฐ ์ „ publish ํ˜ธ์ถœ ์‹œ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค', () => { + socketManager.publish('/app/test', {} as SocketMessage); + expect(clientInstances).toHaveLength(0); + }); + + it('์—ฐ๊ฒฐ ํ›„ publish ํ˜ธ์ถœ ์‹œ JSON ์ง๋ ฌํ™”๋œ body๋ฅผ ์ „์†กํ•ด์•ผ ํ•œ๋‹ค', () => { + socketManager.connect(); + const client = getLatestClient(); + client.connected = true; + + const message: SocketMessage = { + eventType: 'NEXT', + data: { + timerType: 'NORMAL', + currentTeam: 'PROS', + remainingTime: 40, + sequence: 0, + }, + }; + socketManager.publish('/app/test', message); + + expect(client.publish).toHaveBeenCalledWith({ + destination: '/app/test', + headers: undefined, + body: JSON.stringify(message), + }); + }); + }); +}); From c8d48435b07d030523d4c0b58841bd0e5510cb21 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 11:29:26 +0900 Subject: [PATCH 11/22] =?UTF-8?q?fix:=20=EA=B3=A0=EC=A0=95=20=EC=A7=80?= =?UTF-8?q?=ED=84=B0=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts index 5de0cc2b..27525e31 100644 --- a/src/apis/sockets/SocketManager.ts +++ b/src/apis/sockets/SocketManager.ts @@ -5,7 +5,6 @@ import { SocketMessage } from './type'; /** * ์†Œ์ผ“ ์„ค์ •์„ ์ •ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค * - `maxRetires` ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’ 3ํšŒ) - * - `jitterMs` ๋ฐฑ์—”๋“œ ๋ถ€ํ•˜๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•œ ์ง€ํ„ฐ (๊ธฐ๋ณธ๊ฐ’ 500 ms) * - `baseRetryDelayMs` ๊ธฐ๋ณธ ์žฌ์‹œ๋„ ๋Œ€๊ธฐ ์‹œ๊ฐ„ (๊ธฐ๋ณธ๊ฐ’ 1000 ms) * - `heartbeatInMs` ์ˆ˜์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’ 10000 ms) * - `heartbeatOutMs` ๋ฐœ์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’ 10000 ms) @@ -15,9 +14,6 @@ export interface SocketOptions { /** ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’: 3) */ maxRetries?: number; - /** ๋ฐฑ์—”๋“œ ๋ถ€ํ•˜๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•œ ์ง€ํ„ฐ(๋‚œ์ˆ˜ ๋ถ„์‚ฐ) ๊ฐ’ (๊ธฐ๋ณธ๊ฐ’: 500ms) */ - jitterMs?: number; - /** ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๊ณ„์‚ฐ์˜ ๊ธฐ์ค€์ด ๋˜๋Š” ์ดˆ๊ธฐ ์ง€์—ฐ ์‹œ๊ฐ„ (๊ธฐ๋ณธ๊ฐ’: 1000ms) */ baseRetryDelayMs?: number; @@ -34,7 +30,6 @@ export interface SocketOptions { // ๊ธฐ๋ณธ๊ฐ’ ๊ฐ์ฒด ์„ ์–ธ (onConnect๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ํ•„์ˆ˜ ์†์„ฑ ์ •์˜) const DEFAULT_OPTIONS: Required> = { maxRetries: 3, - jitterMs: 500, baseRetryDelayMs: 1000, heartbeatInMs: 10000, heartbeatOutMs: 10000, @@ -66,7 +61,6 @@ class SocketManager { * * @param options - ์†Œ์ผ“ ํด๋ผ์ด์–ธํŠธ ๋™์ž‘์„ ์ œ์–ดํ•˜๋Š” ์„ ํƒ์  ์„ค์ • ๊ฐ์ฒด * @param options.maxRetries - ์ตœ๋Œ€ ์žฌ์—ฐ๊ฒฐ ์‹œ๋„ ํšŸ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’: 3) - * @param options.jitterMs - ์žฌ์—ฐ๊ฒฐ ์ง€์—ฐ ์‹œ๊ฐ„์— ์ถ”๊ฐ€๋  ์ง€ํ„ฐ(๋‚œ์ˆ˜ ๋ถ„์‚ฐ) ๊ฐ’ (๊ธฐ๋ณธ๊ฐ’: 500) * @param options.baseRetryDelayMs - ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๊ณ„์‚ฐ์˜ ๊ธฐ์ค€์ด ๋˜๋Š” ์ดˆ๊ธฐ ์ง€์—ฐ ์‹œ๊ฐ„ (๊ธฐ๋ณธ๊ฐ’: 1000) * @param options.heartbeatInMs - ์„œ๋ฒ„ > ํด๋ผ์ด์–ธํŠธ ์ˆ˜์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ(ms) (๊ธฐ๋ณธ๊ฐ’: 10000) * @param options.heartbeatOutMs - ํด๋ผ์ด์–ธํŠธ > ์„œ๋ฒ„ ๋ฐœ์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ(ms) (๊ธฐ๋ณธ๊ฐ’: 10000) From 64d5bc8ce9396247563daceb6a93163d1c028b3d Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 11:56:15 +0900 Subject: [PATCH 12/22] =?UTF-8?q?refactor:=20=EB=AA=87=20=EA=B0=80?= =?UTF-8?q?=EC=A7=80=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.ts | 2 +- src/apis/sockets/type.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts index 27525e31..3422b4fc 100644 --- a/src/apis/sockets/SocketManager.ts +++ b/src/apis/sockets/SocketManager.ts @@ -4,7 +4,7 @@ import { SocketMessage } from './type'; /** * ์†Œ์ผ“ ์„ค์ •์„ ์ •ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค - * - `maxRetires` ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’ 3ํšŒ) + * - `maxRetries` ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’ 3ํšŒ) * - `baseRetryDelayMs` ๊ธฐ๋ณธ ์žฌ์‹œ๋„ ๋Œ€๊ธฐ ์‹œ๊ฐ„ (๊ธฐ๋ณธ๊ฐ’ 1000 ms) * - `heartbeatInMs` ์ˆ˜์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’ 10000 ms) * - `heartbeatOutMs` ๋ฐœ์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’ 10000 ms) diff --git a/src/apis/sockets/type.ts b/src/apis/sockets/type.ts index 2e6216fa..34eac83a 100644 --- a/src/apis/sockets/type.ts +++ b/src/apis/sockets/type.ts @@ -18,7 +18,7 @@ export type SocketEventType = TimerEventTypes | NonTimerEventType; /** ์†Œ์ผ“ ํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š”, ํƒ€์ด๋จธ ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ ํŽ˜์ด๋กœ๋“œ */ export interface TimerDataPayload { /** ํƒ€์ด๋จธ ์œ ํ˜• (์ž์œ ํ† ๋ก , ์ผ๋ฐ˜) */ - timerType: Omit; + timerType: Exclude; /** ํ˜„์žฌ ํƒ€์ด๋จธ ์ˆœ์„œ * - 0๋ถ€ํ„ฐ ์‹œ์ž‘ From e7e9211a499d1d3c188d2a0fe4bc0d9296eb244d Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 11:56:32 +0900 Subject: [PATCH 13/22] =?UTF-8?q?feat:=20=ED=9B=85=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=86=8C=EC=BC=93=20=EC=97=B0=EA=B2=B0=20=ED=95=B4=EC=A0=9C=20?= =?UTF-8?q?=EC=B1=85=EC=9E=84=EC=9D=84=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useSocket.ts | 44 +++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index b4ca9318..8b5a540e 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -3,30 +3,55 @@ import { IMessage, StompHeaders, StompSubscription } from '@stomp/stompjs'; import { socketManager, SocketOptions } from '../apis/sockets/SocketManager'; import { SocketMessage } from '../apis/sockets/type'; +/** + * ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ๋•๋Š” React ํ›…์ž…๋‹ˆ๋‹ค. ์ œ๊ณต๋˜๋Š” ํ•จ์ˆ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค: + * + * - `connect`๋Š” ๊ธฐ์กด HTTP ์—ฐ๊ฒฐ์„ WS ์—ฐ๊ฒฐ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•ฉ๋‹ˆ๋‹ค. `options`๋ฅผ ํ†ตํ•ด ์„ค์ •์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + * ๊ธฐ๋ณธ๊ฐ’์€ [SocketManager.ts](../apis/sockets/SocketManager.ts) ์ฐธ๊ณ . + * - `disconnect`๋Š” ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ๋Š์Šต๋‹ˆ๋‹ค. ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ๋Š์–ด์•ผ ํ•  ์ฑ…์ž„์€ ์†Œ์ผ“์„ ์—ฐ๊ฒฐํ•œ ํŽ˜์ด์ง€์— ์žˆ์Šต๋‹ˆ๋‹ค. + * - `subscribe`๋Š” ํŠน์ • ์ฑ„๋„์„ ๊ตฌ๋…ํ•ฉ๋‹ˆ๋‹ค. + * - `unsubscribe`๋Š” ํŠน์ • ์ฑ„๋„์˜ ๊ตฌ๋…์„ ๋Š์Šต๋‹ˆ๋‹ค. ์ด ํ›…์ด ์–ธ๋งˆ์šดํŠธ๋  ๋•Œ, ํ˜„์žฌ ๊ตฌ๋…๋œ ์ฑ„๋„๋“ค์— ๋Œ€ํ•ด ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. + * - `publish`๋Š” ํŠน์ • ์ฑ„๋„๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค. + * + * ํŠนํžˆ, ๊ตฌ๋… ํ•ด์ œ์˜ ์ฑ…์ž„์€ ์ด ํ›…์— ์žˆ์œผ๋‚˜, ์—ฐ๊ฒฐ ์ž์ฒด๋ฅผ ๋Š๋Š” ์ฑ…์ž„์€ ์†Œ์ผ“์„ ํ˜ธ์ถœํ•œ ํŽ˜์ด์ง€์— ์žˆ๋‹ค๋Š” ์ ์„ ์œ ๋…ํ•ด์ฃผ์„ธ์š”. + */ export const useSocket = () => { // ํ˜„์žฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ™œ์„ฑํ™”ํ•œ ๊ตฌ๋…์„ ์ €์žฅํ•˜๋Š” ๋ณด๊ด€์†Œ const subscriptions = useRef>(new Map()); - // ์—ฐ๊ฒฐ + /** + * ์†Œ์ผ“ ์—ฐ๊ฒฐ + * HTTP ์—ฐ๊ฒฐ์„ WS ์—ฐ๊ฒฐ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ. + * @param options - (์„ ํƒ ์˜ต์…˜) ์†Œ์ผ“ ์—ฐ๊ฒฐ์— ์‚ฌ์šฉํ•  ์˜ต์…˜. ์ƒ์„ธ ํ•ญ๋ชฉ์€ [SocketManager.ts](../apis/sockets/SocketManager.ts) ์ฐธ๊ณ . + */ const connect = useCallback((options?: SocketOptions) => { socketManager.connect(options); }, []); - // ํ•ด์ œ + /** + * ์†Œ์ผ“ ์—ฐ๊ฒฐ ํ•ด์ œ + * WS ์—ฐ๊ฒฐ์„ ๋Š์Œ. + */ const disconnect = useCallback(() => { socketManager.disconnect(); }, []); - // ๋ฉ”์‹œ์ง€ ๋ฐœ์‹  (Publish) + /** + * ๋ฉ”์‹œ์ง€ ๋ฐœํ–‰ + * ํŠน์ • ์ฑ„๋„๋กœ ๋ฉ”์‹œ์ง€ ๋ฐœํ–‰. + * @param destination - ๋ชฉ์ ์ง€ ์ฑ„๋„ + * @param body - ๋ฐœํ–‰ํ•  ๋ฉ”์‹œ์ง€ + * @param headers - (์„ ํƒ ์˜ต์…˜) ํ•„์š”์— ๋”ฐ๋ผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ STOMP ํ—ค๋”. + */ const publish = useCallback( - (destination: string, body: SocketMessage, headers: StompHeaders) => { + (destination: string, body: SocketMessage, headers?: StompHeaders) => { socketManager.publish(destination, body, headers); }, [], ); /** - * ๊ตฌ๋… (Subscribe) + * ๊ตฌ๋… * * ์ด ํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ ์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋œ ๋’ค์— ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค! * ๋” ์ •ํ™•ํžˆ ๋งํ•˜๋ฉด, ์†Œ์ผ“์ด ์—ฐ๊ฒฐ ์„ฑ๊ณต ํ›„์— ์‹คํ–‰ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ธ `onConnect` ์•ˆ์— @@ -59,7 +84,11 @@ export const useSocket = () => { [], ); - // ์ˆ˜๋™ ๊ตฌ๋… ํ•ด์ œ + /** + * ์ˆ˜๋™ ๊ตฌ๋… ํ•ด์ œ + * ์ˆ˜๋™์œผ๋กœ ๊ตฌ๋…์„ ํ•ด์ œํ•˜๋Š” ํ•จ์ˆ˜. + * @param destination - ๊ตฌ๋…์„ ํ•ด์ œํ•  ์ฑ„๋„ + */ const unsubscribe = useCallback((destination: string) => { const subscription = subscriptions.current.get(destination); if (subscription) { @@ -78,9 +107,6 @@ export const useSocket = () => { // ์ฃผ์„์˜ ๊ฒฝ๊ณ ์™€ ์ „ํ˜€ ์—ฐ๊ด€์ด ์—†์œผ๋ฏ€๋กœ ๊ฒฝ๊ณ ๋ฅผ ๊บผ ๋‘ก๋‹ˆ๋‹ค. // eslint-disable-next-line react-hooks/exhaustive-deps subscriptions.current.clear(); - - // ํŽ˜์ด์ง€๋ฅผ ๋‚˜๊ฐˆ ๋•Œ ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ๋Š์„ ๊ฒƒ์ธ๊ฐ€? (์ •์ฑ… ๊ฒฐ์ • ํ›„ ์ˆ˜์ • ์˜ˆ์ •) - socketManager.disconnect(); }; }, []); From 3a660195d714e203c5752c1f8caab0128c3be6d1 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 12:03:03 +0900 Subject: [PATCH 14/22] =?UTF-8?q?fix:=20=EC=A4=91=EB=B3=B5=20=EA=B5=AC?= =?UTF-8?q?=EB=8F=85=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EB=B0=8F=20=EC=9E=AC=EA=B5=AC=EB=8F=85=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=ED=95=98=EA=B2=8C=20=EC=99=84=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useSocket.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 8b5a540e..aea8ca5c 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -72,8 +72,12 @@ export const useSocket = () => { */ const subscribe = useCallback( (destination: string, callback: (message: IMessage) => void) => { - // ์ด๋ฏธ ํ•ด๋‹น ์ฑ„๋„์„ ๊ตฌ๋… ์ค‘์ด๋ฉด ์ค‘๋ณต ๊ตฌ๋… ๋ฐฉ์ง€ - if (subscriptions.current.has(destination)) return; + // ์ด๋ฏธ ํ•ด๋‹น ์ฑ„๋„์„ ๊ตฌ๋… ์ค‘์ด๋ฉด Map์—์„œ ๊ตฌ๋… ์ œ๊ฑฐํ•˜์—ฌ ์žฌ๊ตฌ๋… ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•จ + const existing = subscriptions.current.get(destination); + if (existing) { + existing.unsubscribe(); + subscriptions.current.delete(destination); + } // ๊ตฌ๋… ์ค‘์ด์ง€ ์•Š๋‹ค๋ฉด, ๊ตฌ๋… ์š”์ฒญ ํ›„ ์„ฑ๊ณต ์‹œ useRef๋กœ ์œ ์ง€ํ•˜๋Š” Map์— ์ €์žฅ const subscription = socketManager.subscribe(destination, callback); From f9469abc0d1ecb4954d5a6cd0cec2d4e9da53229 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 12:03:33 +0900 Subject: [PATCH 15/22] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=AA=A8=EB=B0=A9=20=EA=B0=9D=EC=B2=B4=EC=9D=98=20=EC=9E=98?= =?UTF-8?q?=EB=AA=BB=EB=90=9C=20=EC=B4=88=EA=B8=B0=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EC=A0=95=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.test.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/apis/sockets/SocketManager.test.ts b/src/apis/sockets/SocketManager.test.ts index 192c807c..c1fd82a3 100644 --- a/src/apis/sockets/SocketManager.test.ts +++ b/src/apis/sockets/SocketManager.test.ts @@ -36,11 +36,15 @@ const clientInstances = vi.hoisted( */ vi.mock('@stomp/stompjs', () => { class MockClient { - activate = vi.fn(); - deactivate = vi.fn(); + activate = vi.fn().mockImplementation(() => { + this.active = true; + }); + deactivate = vi.fn().mockImplementation(() => { + this.active = false; + }); publish = vi.fn(); subscribe = vi.fn(); - active = true; + active = false; connected = false; reconnectDelay: number; config: StompConfig; From 0b6c16b1798ff73f1d20f47fd22887fae95c0737 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 16:50:03 +0900 Subject: [PATCH 16/22] =?UTF-8?q?refactor:=20=EC=9E=AC=EA=B5=AC=EB=8F=85?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=A0=84=EB=A9=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.ts | 42 ++++++++++++++--- src/hooks/useSocket.ts | 75 +++++++++++++++++++++++-------- 2 files changed, 93 insertions(+), 24 deletions(-) diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts index 3422b4fc..d02fd5e0 100644 --- a/src/apis/sockets/SocketManager.ts +++ b/src/apis/sockets/SocketManager.ts @@ -55,6 +55,36 @@ class SocketManager { return SocketManager.instance; } + // ์žฌ์—ฐ๊ฒฐ ์‹œ ์•ˆ์ •์  ๊ตฌ๋… ๋ณต๊ตฌ๋ฅผ ์œ„ํ•œ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋ชจ์•„๋‘๋Š” Set + // - ๊ด€์ฐฐ์ž ํŒจํ„ด(observer pattern) ์ ์šฉ + // - ๊ด€์ฐฐ์ž(observer)๋Š” ๊ตฌ๋…์„ ๊ด€๋ฆฌํ•˜๋Š” useSocket ํ›… + // - ๋ฐœํ–‰์ž(publisher)๋Š” ์žฌ์—ฐ๊ฒฐ ์—ฌ๋ถ€๋ฅผ ์•Œ๋ฆฌ๋Š” ์ด ํด๋ž˜์Šค (SocketManager) + private connectListeners: Set<() => void> = new Set(); + + /** + * ๊ด€์ฐฐ์ž๋ฅผ ๋“ฑ๋กํ•˜๋Š” ํ•จ์ˆ˜ + * @param listener - ์—ฐ๊ฒฐ ์ˆ˜๋ฆฝ ์‹œ ๊ฐ ๊ตฌ๋…์—์„œ ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ + */ + public onConnectEvent(listener: () => void) { + this.connectListeners.add(listener); + } + + /** + * ๊ด€์ฐฐ์ž๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ํ•จ์ˆ˜ + * @param listener - ์ œ๊ฑฐํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ + */ + public offConnectEvent(listener: () => void) { + this.connectListeners.delete(listener); + } + + /** + * ์—ฐ๊ฒฐ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜ + * @returns ์—ฐ๊ฒฐ ์—ฌ๋ถ€ + */ + public isConnected(): boolean { + return this.client?.connected ?? false; + } + /** * ์›น ์†Œ์ผ“(STOMP) ์—ฐ๊ฒฐ์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์„œ๋ฒ„์™€ ์„ธ์…˜์„ ์ˆ˜๋ฆฝํ•ฉ๋‹ˆ๋‹ค. * HTTPS์—์„œ WS๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ์‹œ ์ฒญ์ค‘๊ณผ ์‚ฌํšŒ์ž ๋ชจ๋‘ ๋ฌด์ธ์ฆ์œผ๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. @@ -71,6 +101,7 @@ class SocketManager { if (this.client && this.client.active) return; // ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •ํ•œ ์˜ต์…˜์ด ์žˆ๋‹ค๋ฉด ๋ฎ์–ด์“ฐ๊ธฐ + this.retryCount = 0; this.currentOptions = { ...DEFAULT_OPTIONS, ...options }; // ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ URL ๋กœ๋“œ @@ -96,10 +127,8 @@ class SocketManager { console.log('โœ… ์›น ์†Œ์ผ“(STOMP) ์—ฐ๊ฒฐ ์„ฑ๊ณต'); this.retryCount = 0; - // ์˜ต์…˜์œผ๋กœ ์ „๋‹ฌ๋œ ์ฝœ๋ฐฑ์ด ์žˆ๋‹ค๋ฉด ์‹คํ–‰ - if (options?.onConnect) { - options.onConnect(); - } + // ๋ชจ๋“  ๊ด€์ฐฐ์ž์—๊ฒŒ ์—ฐ๊ฒฐ์ด ์ˆ˜๋ฆฝ๋˜์—ˆ๋‹ค๊ณ  ์•Œ๋ฆผ + this.connectListeners.forEach((listener) => listener()); }, onStompError: (frame) => { @@ -212,7 +241,10 @@ class SocketManager { // ์ตœ๋Œ€ ์ง€ํ„ฐ ์ƒํ•œ์„  ๊ณ„์‚ฐ const maxExponentialDelay = this.currentOptions.baseRetryDelayMs * Math.pow(2, currentRetryCount); - return Math.floor(Math.random() * maxExponentialDelay); + + // ๋‚œ์ˆ˜๊ฐ€ 0์ด ๋  ๊ฒฝ์šฐ STOMP๊ฐ€ ์žฌ์—ฐ๊ฒฐ ๋น„ํ™œ์„ฑํ™”๋กœ ํŒŒ์•…ํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด + // ๊ณ„์‚ฐํ•œ ๊ฐ’์— 10 ms๋ฅผ ์ถ”๊ฐ€ + return Math.floor(Math.random() * maxExponentialDelay) + 10; } } diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index aea8ca5c..4c2189ce 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -17,7 +17,12 @@ import { SocketMessage } from '../apis/sockets/type'; */ export const useSocket = () => { // ํ˜„์žฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ™œ์„ฑํ™”ํ•œ ๊ตฌ๋…์„ ์ €์žฅํ•˜๋Š” ๋ณด๊ด€์†Œ - const subscriptions = useRef>(new Map()); + const activeSubscriptions = useRef>(new Map()); + + // ์žฌ์—ฐ๊ฒฐ์‹œ ๋ณต๊ตฌ๋ฅผ ์œ„ํ•ด ์ง€๊ธˆ๊นŒ์ง€ ๊ตฌ๋…ํ–ˆ๋˜ ์ฑ„๋„๊ณผ ์ฝœ๋ฐฑ์„ ์ €์žฅํ•˜๋Š” ๋ณด๊ด€์„œ + const subscriptionInfos = useRef void>>( + new Map(), + ); /** * ์†Œ์ผ“ ์—ฐ๊ฒฐ @@ -72,17 +77,21 @@ export const useSocket = () => { */ const subscribe = useCallback( (destination: string, callback: (message: IMessage) => void) => { - // ์ด๋ฏธ ํ•ด๋‹น ์ฑ„๋„์„ ๊ตฌ๋… ์ค‘์ด๋ฉด Map์—์„œ ๊ตฌ๋… ์ œ๊ฑฐํ•˜์—ฌ ์žฌ๊ตฌ๋… ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•จ - const existing = subscriptions.current.get(destination); - if (existing) { - existing.unsubscribe(); - subscriptions.current.delete(destination); - } + // ๊ตฌ๋… ์ •๋ณด๋ฅผ ๋ฐฑ์—… ๋ฆฌ์ŠคํŠธ์— ๋“ฑ๋ก + subscriptionInfos.current.set(destination, callback); - // ๊ตฌ๋… ์ค‘์ด์ง€ ์•Š๋‹ค๋ฉด, ๊ตฌ๋… ์š”์ฒญ ํ›„ ์„ฑ๊ณต ์‹œ useRef๋กœ ์œ ์ง€ํ•˜๋Š” Map์— ์ €์žฅ - const subscription = socketManager.subscribe(destination, callback); - if (subscription) { - subscriptions.current.set(destination, subscription); + // ์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋œ ์ƒํƒœ๋ผ๋ฉด ์ฆ‰์‹œ ๊ตฌ๋… ์‹คํ–‰ + if (socketManager.isConnected()) { + // ์ค‘๋ณต ๊ตฌ๋… ๋ฐฉ์ง€ + if (activeSubscriptions.current.has(destination)) { + return; + } + + // ์ค‘๋ณต์ด ์•„๋‹ˆ๋ผ๋ฉด ๋ฆฌ์ŠคํŠธ์— ๋“ฑ๋ก + const subscription = socketManager.subscribe(destination, callback); + if (subscription) { + activeSubscriptions.current.set(destination, subscription); + } } }, [], @@ -94,23 +103,51 @@ export const useSocket = () => { * @param destination - ๊ตฌ๋…์„ ํ•ด์ œํ•  ์ฑ„๋„ */ const unsubscribe = useCallback((destination: string) => { - const subscription = subscriptions.current.get(destination); + // ๋ฐฑ์—… ๋ฆฌ์ŠคํŠธ์˜ ๊ตฌ๋… ์ •๋ณด๋ฅผ ์ œ๊ฑฐ + subscriptionInfos.current.delete(destination); + + // ํ˜„์žฌ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š” ๊ตฌ๋… ๋ฆฌ์ŠคํŠธ์—์„œ๋„ ์ œ๊ฑฐ + const subscription = activeSubscriptions.current.get(destination); if (subscription) { - subscription.unsubscribe(); // STOMP ์„œ๋ฒ„์— ํ•ด์ œ ์š”์ฒญ - subscriptions.current.delete(destination); // ๋งต์—์„œ ์ œ๊ฑฐ + subscription.unsubscribe(); + activeSubscriptions.current.delete(destination); } }, []); // ํด๋ฆฐ์—… useEffect(() => { + // ์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋  ํ•ธ๋“ค๋Ÿฌ + const handleConnect = () => { + // ๊ธฐ์กด ํ™œ์„ฑํ™”๋œ ๊ตฌ๋… ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐํ™” + activeSubscriptions.current.clear(); + + // ๋ฐฑ์—… ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๊ตฌ๋…์„ ๋‹ค์‹œ ํ™œ์„ฑํ™” + subscriptionInfos.current.forEach((callback, destination) => { + const subscription = socketManager.subscribe(destination, callback); + if (subscription) { + activeSubscriptions.current.set(destination, subscription); + } + }); + }; + + // ์ด ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ๋ฐœํ–‰์ž(SocketManager)์— ๋“ฑ๋ก + socketManager.onConnectEvent(handleConnect); + + // ์–ธ๋งˆ์šดํŠธ ์‹œ ๊ตฌ๋… ํด๋ฆฌ์–ดํ•˜๋Š” ํ•จ์ˆ˜ return () => { - // ํ˜„์žฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งŒ๋“ค์–ด๋‘” ๋ชจ๋“  ๊ตฌ๋…์„ ์ˆœํšŒํ•˜๋ฉฐ ์ผ๊ด„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. - subscriptions.current.forEach((sub) => sub.unsubscribe()); + // ๋จผ์ € ๋ฐœํ–‰์ž(SocketManager)์—๊ฒŒ ๋“ฑ๋ก๋œ ํ•ธ๋“ค๋Ÿฌ๋ถ€ํ„ฐ ์ œ๊ฑฐ + socketManager.offConnectEvent(handleConnect); - // ์•„๋ž˜ Ref์˜ ๊ฒฝ์šฐ React์— ์˜ํ•ด ๋ Œ๋”๋ง๋˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง€์‹œํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, - // ์ฃผ์„์˜ ๊ฒฝ๊ณ ์™€ ์ „ํ˜€ ์—ฐ๊ด€์ด ์—†์œผ๋ฏ€๋กœ ๊ฒฝ๊ณ ๋ฅผ ๊บผ ๋‘ก๋‹ˆ๋‹ค. + // ํ™œ์„ฑํ™”๋œ ๋ชจ๋“  ๊ตฌ๋… ํ•ด์ œ + activeSubscriptions.current.forEach((subscription) => + subscription.unsubscribe(), + ); + + // ์•„๋ž˜ 2์ค„์— ๋Œ€ํ•œ ๊ฒฝ๊ณ ๋Š” Ref๊ฐ€ React ์ปดํฌ๋„ŒํŠธ์ผ ๊ฒฝ์šฐ์—๋งŒ ์œ ํšจํ•˜๋ฏ€๋กœ, ์—ฌ๊ธฐ์„  ๋น„ํ™œ์„ฑํ™” + // eslint-disable-next-line react-hooks/exhaustive-deps + activeSubscriptions.current.clear(); // eslint-disable-next-line react-hooks/exhaustive-deps - subscriptions.current.clear(); + subscriptionInfos.current.clear(); }; }, []); From ddf4f80eb6dbcee1761ed623bcb3ba02e7aa4d46 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 16:52:40 +0900 Subject: [PATCH 17/22] =?UTF-8?q?test:=20=EC=A7=80=ED=84=B0=EC=97=90=20?= =?UTF-8?q?=EC=B5=9C=EC=86=8C=20=EB=94=9C=EB=A0=88=EC=9D=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EC=97=90=20=EB=94=B0=EB=A5=B8=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.test.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/apis/sockets/SocketManager.test.ts b/src/apis/sockets/SocketManager.test.ts index c1fd82a3..2709de69 100644 --- a/src/apis/sockets/SocketManager.test.ts +++ b/src/apis/sockets/SocketManager.test.ts @@ -135,9 +135,9 @@ describe('SocketManager', () => { * handleReconnection()์€ ํ˜„์žฌ retryCount๋กœ ๋”œ๋ ˆ์ด๋ฅผ ๊ณ„์‚ฐํ•œ ํ›„ retryCount๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค. * * Math.random = 0.5, baseRetryDelayMs = 1000 ๊ณ ์ • ์‹œ: - * ์ดˆ๊ธฐ connect: calculateBackoffDelay(0) = floor(0.5 * 1000 * 2^0) = 500 - * 1๋ฒˆ์งธ close: calculateBackoffDelay(0) = floor(0.5 * 1000 * 2^0) = 500 โ†’ retryCount: 0 โ†’ 1 - * 2๋ฒˆ์งธ close: calculateBackoffDelay(1) = floor(0.5 * 1000 * 2^1) = 1000 โ†’ retryCount: 1 โ†’ 2 + * ์ดˆ๊ธฐ connect: calculateBackoffDelay(0) = floor(0.5 * 1000 * 2^0) = 500 + 10 + * 1๋ฒˆ์งธ close: calculateBackoffDelay(0) = floor(0.5 * 1000 * 2^0) = 500 + 10 โ†’ retryCount: 0 โ†’ 1 + * 2๋ฒˆ์งธ close: calculateBackoffDelay(1) = floor(0.5 * 1000 * 2^1) = 1000 + 10 โ†’ retryCount: 1 โ†’ 2 */ it('onWebSocketClose ๋ฐœ์ƒ ์‹œ ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๋”œ๋ ˆ์ด๋ฅผ ๊ฐฑ์‹ ํ•ด์•ผ ํ•œ๋‹ค', () => { vi.spyOn(Math, 'random').mockReturnValue(0.5); @@ -145,16 +145,16 @@ describe('SocketManager', () => { const client = getLatestClient(); - // ์ดˆ๊ธฐ ๋”œ๋ ˆ์ด: calculateBackoffDelay(0) = 500 - expect(client.reconnectDelay).toBe(500); + // ์ดˆ๊ธฐ ๋”œ๋ ˆ์ด: calculateBackoffDelay(0) = 500 + 10 + expect(client.reconnectDelay).toBe(500 + 10); - // 1๋ฒˆ์งธ ๋Š๊น€: retryCount=0 ๊ธฐ์ค€ ๊ณ„์‚ฐ โ†’ 500, ์ดํ›„ retryCount=1 + // 1๋ฒˆ์งธ ๋Š๊น€: retryCount=0 ๊ธฐ์ค€ ๊ณ„์‚ฐ โ†’ 500 + 10, ์ดํ›„ retryCount=1 client.config.onWebSocketClose?.({} as CloseEvent); - expect(client.reconnectDelay).toBe(500); + expect(client.reconnectDelay).toBe(500 + 10); // 2๋ฒˆ์งธ ๋Š๊น€: retryCount=1 ๊ธฐ์ค€ ๊ณ„์‚ฐ โ†’ 1000, ์ดํ›„ retryCount=2 client.config.onWebSocketClose?.({} as CloseEvent); - expect(client.reconnectDelay).toBe(1000); + expect(client.reconnectDelay).toBe(1000 + 10); }); it('์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜(maxRetries) ์ดˆ๊ณผ ์‹œ reconnectDelay๋ฅผ 0์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•ด์•ผ ํ•œ๋‹ค', () => { @@ -185,9 +185,9 @@ describe('SocketManager', () => { // ์žฌ์—ฐ๊ฒฐ ์„ฑ๊ณต โ†’ retryCount 0์œผ๋กœ ๋ฆฌ์…‹ client.config.onConnect?.({} as IMessage); - // ๋Š๊น€ 1๋ฒˆ: retryCount=0 ๊ธฐ์ค€ ๊ณ„์‚ฐ โ†’ 500 (retryCount๊ฐ€ ๋ฆฌ์…‹๋์œผ๋ฏ€๋กœ) + // ๋Š๊น€ 1๋ฒˆ: retryCount=0 ๊ธฐ์ค€ ๊ณ„์‚ฐ โ†’ 500 + 10 (retryCount๊ฐ€ ๋ฆฌ์…‹๋์œผ๋ฏ€๋กœ) client.config.onWebSocketClose?.({} as CloseEvent); - expect(client.reconnectDelay).toBe(500); + expect(client.reconnectDelay).toBe(500 + 10); }); }); From 3aaea89fad90d774c8bcc9f65013724e3f021d62 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 17:06:45 +0900 Subject: [PATCH 18/22] =?UTF-8?q?fix:=20=EA=B3=BC=EA=B1=B0=20=ED=81=B4?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=EC=96=B8=ED=8A=B8=EC=97=90=20=EC=9D=98?= =?UTF-8?q?=ED=95=9C=20=ED=98=84=EC=9E=AC=20=ED=81=B4=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EC=96=B8=ED=8A=B8=20=EC=98=A4=EC=97=BC=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts index d02fd5e0..0376dd8d 100644 --- a/src/apis/sockets/SocketManager.ts +++ b/src/apis/sockets/SocketManager.ts @@ -8,7 +8,6 @@ import { SocketMessage } from './type'; * - `baseRetryDelayMs` ๊ธฐ๋ณธ ์žฌ์‹œ๋„ ๋Œ€๊ธฐ ์‹œ๊ฐ„ (๊ธฐ๋ณธ๊ฐ’ 1000 ms) * - `heartbeatInMs` ์ˆ˜์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’ 10000 ms) * - `heartbeatOutMs` ๋ฐœ์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’ 10000 ms) - * - `onConnect` ์—ฐ๊ฒฐ ์‹œ ์‹คํ–‰ํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ */ export interface SocketOptions { /** ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’: 3) */ @@ -22,9 +21,6 @@ export interface SocketOptions { /** ๋ฐœ์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ (๊ธฐ๋ณธ๊ฐ’: 10000ms) */ heartbeatOutMs?: number; - - /** ์—ฐ๊ฒฐ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜๋ฆฝ๋œ ์งํ›„ ์‹คํ–‰๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ */ - onConnect?: () => void; } // ๊ธฐ๋ณธ๊ฐ’ ๊ฐ์ฒด ์„ ์–ธ (onConnect๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ํ•„์ˆ˜ ์†์„ฑ ์ •์˜) @@ -94,7 +90,6 @@ class SocketManager { * @param options.baseRetryDelayMs - ์ง€์ˆ˜ ๋ฐฑ์˜คํ”„ ๊ณ„์‚ฐ์˜ ๊ธฐ์ค€์ด ๋˜๋Š” ์ดˆ๊ธฐ ์ง€์—ฐ ์‹œ๊ฐ„ (๊ธฐ๋ณธ๊ฐ’: 1000) * @param options.heartbeatInMs - ์„œ๋ฒ„ > ํด๋ผ์ด์–ธํŠธ ์ˆ˜์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ(ms) (๊ธฐ๋ณธ๊ฐ’: 10000) * @param options.heartbeatOutMs - ํด๋ผ์ด์–ธํŠธ > ์„œ๋ฒ„ ๋ฐœ์‹  ํ•˜ํŠธ๋น„ํŠธ ์ฃผ๊ธฐ(ms) (๊ธฐ๋ณธ๊ฐ’: 10000) - * @param options.onConnect - ์—ฐ๊ฒฐ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜๋ฆฝ๋œ ์งํ›„ ์‹คํ–‰๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜ */ public connect(options?: SocketOptions) { // ์ด๋ฏธ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์กด์žฌํ•˜๊ณ  ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ค‘๋ณต ์—ฐ๊ฒฐ ๋ฐฉ์ง€ @@ -107,7 +102,7 @@ class SocketManager { // ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ URL ๋กœ๋“œ const wsUrl = import.meta.env.VITE_API_BASE_URL + '/ws'; - this.client = new Client({ + const newClient = new Client({ // wss:// ๋Œ€์‹  https:// ์ฃผ์†Œ๋ฅผ SockJS ํŒฉํ† ๋ฆฌ์— ์ฃผ์ž… webSocketFactory: () => new SockJS(wsUrl), @@ -137,12 +132,19 @@ class SocketManager { }, onWebSocketClose: () => { + // ํ˜„์žฌ SocketManager๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ์ค‘์ธ ์ตœ์‹  ์†Œ์ผ“๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์ฆ + if (this.client !== newClient) { + console.log('๐Ÿ‘ป ๊ณผ๊ฑฐ ์„ธ์…˜์˜ ์ง€์—ฐ๋œ close ์ด๋ฒคํŠธ๊ฐ€ ๋ฌด์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.'); + return; + } + console.log('โš ๏ธ ์›น ์†Œ์ผ“ ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.'); this.handleReconnection(); }, }); // ์‹ค์ œ ์—ฐ๊ฒฐ ์‹œ๋™ + this.client = newClient; this.client.activate(); } From 85f6a54bca1dd73a7b486365c05dd593e34e15a9 Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 19:37:41 +0900 Subject: [PATCH 19/22] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts index 0376dd8d..830c820d 100644 --- a/src/apis/sockets/SocketManager.ts +++ b/src/apis/sockets/SocketManager.ts @@ -24,7 +24,7 @@ export interface SocketOptions { } // ๊ธฐ๋ณธ๊ฐ’ ๊ฐ์ฒด ์„ ์–ธ (onConnect๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ํ•„์ˆ˜ ์†์„ฑ ์ •์˜) -const DEFAULT_OPTIONS: Required> = { +const DEFAULT_OPTIONS: Required = { maxRetries: 3, baseRetryDelayMs: 1000, heartbeatInMs: 10000, @@ -100,7 +100,12 @@ class SocketManager { this.currentOptions = { ...DEFAULT_OPTIONS, ...options }; // ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ URL ๋กœ๋“œ - const wsUrl = import.meta.env.VITE_API_BASE_URL + '/ws'; + const baseUrl = import.meta.env.VITE_API_BASE_URL; + if (!baseUrl) { + console.error('VITE_API_BASE_URL ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.'); + return; + } + const wsUrl = baseUrl + '/ws'; const newClient = new Client({ // wss:// ๋Œ€์‹  https:// ์ฃผ์†Œ๋ฅผ SockJS ํŒฉํ† ๋ฆฌ์— ์ฃผ์ž… @@ -217,7 +222,12 @@ class SocketManager { '๐Ÿšจ ์ตœ๋Œ€ ์žฌ์—ฐ๊ฒฐ ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ์ดˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์„ ํฌ๊ธฐํ•ฉ๋‹ˆ๋‹ค.', ); this.client.reconnectDelay = 0; - this.client.deactivate(); + + // ํด๋ผ์ด์–ธํŠธ ๋ถ„๋ฆฌ + const clientToDeactivate = this.client; + this.client = null; + clientToDeactivate.deactivate(); + return; } From 9ea9a21756d153087328b9a39c37831ed54d370f Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Mon, 30 Mar 2026 19:51:59 +0900 Subject: [PATCH 20/22] =?UTF-8?q?chore:=20=EC=A3=BC=EC=84=9D=20=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useSocket.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 4c2189ce..7840537e 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -59,21 +59,10 @@ export const useSocket = () => { * ๊ตฌ๋… * * ์ด ํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ ์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋œ ๋’ค์— ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค! - * ๋” ์ •ํ™•ํžˆ ๋งํ•˜๋ฉด, ์†Œ์ผ“์ด ์—ฐ๊ฒฐ ์„ฑ๊ณต ํ›„์— ์‹คํ–‰ํ•˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ธ `onConnect` ์•ˆ์— - * ๊ตฌ๋… ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”. * ์• ์ดˆ์— ์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋˜๊ธฐ๋„ ์ „์— ๊ตฌ๋…์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ๋ชจ์ˆœ์ ์ธ ์ผ์ด๋‹ˆ๊นŒ์š”. * - * ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด์š”: - * ``` - * useEffect(() => { - * connect({ - * onConnect: () => { - * // โœ… ์†Œ์ผ“ ์—ฐ๊ฒฐ์ด ์™„์ „ํžˆ ๋๋‚œ ๋’ค์— ๊ตฌ๋…ํ•ด์•ผ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค! - * subscribe('/topic/room/123', (msg) => console.log(msg)); - * } - * }); - * }, []); - * ``` + * @params destination - ๋ชฉ์ ์ง€ ์ฑ„๋„ + * @params callback - ๊ตฌ๋… ์ดํ›„ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ์ˆ˜ํ–‰ํ•  ๋™์ž‘์ด ๋ฌ˜์‚ฌ๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ */ const subscribe = useCallback( (destination: string, callback: (message: IMessage) => void) => { From 628743de81efb27329ebae2eb3931a41b3e3256b Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sun, 5 Apr 2026 15:51:03 +0900 Subject: [PATCH 21/22] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.test.ts | 29 ++++++++++++++++++++++++-- src/apis/sockets/SocketManager.ts | 1 + src/hooks/useSocket.ts | 5 +++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/apis/sockets/SocketManager.test.ts b/src/apis/sockets/SocketManager.test.ts index 2709de69..144977d7 100644 --- a/src/apis/sockets/SocketManager.test.ts +++ b/src/apis/sockets/SocketManager.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { socketManager } from './SocketManager'; -import type { IMessage, StompConfig } from '@stomp/stompjs'; +import type { IFrame, StompConfig } from '@stomp/stompjs'; import { SocketMessage } from './type'; // ------------------------------------------------------------------ @@ -183,7 +183,7 @@ describe('SocketManager', () => { client.config.onWebSocketClose?.({} as CloseEvent); // ์žฌ์—ฐ๊ฒฐ ์„ฑ๊ณต โ†’ retryCount 0์œผ๋กœ ๋ฆฌ์…‹ - client.config.onConnect?.({} as IMessage); + client.config.onConnect?.({} as IFrame); // ๋Š๊น€ 1๋ฒˆ: retryCount=0 ๊ธฐ์ค€ ๊ณ„์‚ฐ โ†’ 500 + 10 (retryCount๊ฐ€ ๋ฆฌ์…‹๋์œผ๋ฏ€๋กœ) client.config.onWebSocketClose?.({} as CloseEvent); @@ -237,4 +237,29 @@ describe('SocketManager', () => { }); }); }); + + describe('Connect Listeners (Observer Pattern)', () => { + it('onConnectEvent๋กœ ๋“ฑ๋กํ•œ ๋ฆฌ์Šค๋„ˆ๊ฐ€ onConnect ์‹œ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•œ๋‹ค', () => { + const listener = vi.fn(); + socketManager.onConnectEvent(listener); + socketManager.connect(); + + const client = getLatestClient(); + client.config.onConnect?.({} as IFrame); + + expect(listener).toHaveBeenCalledOnce(); + }); + + it('offConnectEvent๋กœ ์ œ๊ฑฐํ•œ ๋ฆฌ์Šค๋„ˆ๋Š” onConnect ์‹œ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค', () => { + const listener = vi.fn(); + socketManager.onConnectEvent(listener); + socketManager.offConnectEvent(listener); + socketManager.connect(); + + const client = getLatestClient(); + client.config.onConnect?.({} as IFrame); + + expect(listener).not.toHaveBeenCalled(); + }); + }); }); diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts index 830c820d..d3de68c2 100644 --- a/src/apis/sockets/SocketManager.ts +++ b/src/apis/sockets/SocketManager.ts @@ -165,6 +165,7 @@ class SocketManager { this.retryCount = 0; this.client = null; this.currentOptions = DEFAULT_OPTIONS; + this.connectListeners.clear(); console.log('๐Ÿ›‘ ์›น ์†Œ์ผ“ ์—ฐ๊ฒฐ์„ ์ˆ˜๋™์œผ๋กœ ํ•ด์ œํ–ˆ์Šต๋‹ˆ๋‹ค.'); } diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 7840537e..002e0f90 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -122,6 +122,11 @@ export const useSocket = () => { // ์ด ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ๋ฐœํ–‰์ž(SocketManager)์— ๋“ฑ๋ก socketManager.onConnectEvent(handleConnect); + // ๋ฆฌ์Šค๋„ˆ ๋“ฑ๋ก ์ดํ›„ ์—ฐ๊ฒฐ์ด ์ด๋ฏธ ๋˜์–ด ์žˆ๋Š” ๊ฒŒ ํ™•์ธ๋˜๋ฉด, ํ•ธ๋“ค๋Ÿฌ ๋ฐ”๋กœ ์‹คํ–‰ + if (socketManager.isConnected()) { + handleConnect(); + } + // ์–ธ๋งˆ์šดํŠธ ์‹œ ๊ตฌ๋… ํด๋ฆฌ์–ดํ•˜๋Š” ํ•จ์ˆ˜ return () => { // ๋จผ์ € ๋ฐœํ–‰์ž(SocketManager)์—๊ฒŒ ๋“ฑ๋ก๋œ ํ•ธ๋“ค๋Ÿฌ๋ถ€ํ„ฐ ์ œ๊ฑฐ From b758387525c13520a7b1c8efad1eb7747869142f Mon Sep 17 00:00:00 2001 From: Shawn Kang Date: Sun, 5 Apr 2026 16:14:53 +0900 Subject: [PATCH 22/22] =?UTF-8?q?fix:=20=EB=A6=AC=EC=8A=A4=EB=84=88=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=B3=B5=EA=B5=AC=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/sockets/SocketManager.ts | 8 ++++- src/hooks/useSocket.ts | 52 +++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/apis/sockets/SocketManager.ts b/src/apis/sockets/SocketManager.ts index d3de68c2..14c7df47 100644 --- a/src/apis/sockets/SocketManager.ts +++ b/src/apis/sockets/SocketManager.ts @@ -128,7 +128,13 @@ class SocketManager { this.retryCount = 0; // ๋ชจ๋“  ๊ด€์ฐฐ์ž์—๊ฒŒ ์—ฐ๊ฒฐ์ด ์ˆ˜๋ฆฝ๋˜์—ˆ๋‹ค๊ณ  ์•Œ๋ฆผ - this.connectListeners.forEach((listener) => listener()); + this.connectListeners.forEach((listener) => { + try { + listener(); + } catch (error) { + console.error('๋ฆฌ์Šค๋„ˆ ์˜ค๋ฅ˜ ๋ฐœ์ƒ. ๋‹ค์Œ ๋ฆฌ์Šค๋„ˆ๋กœ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.', error); + } + }); }, onStompError: (frame) => { diff --git a/src/hooks/useSocket.ts b/src/hooks/useSocket.ts index 002e0f90..1c44ee23 100644 --- a/src/hooks/useSocket.ts +++ b/src/hooks/useSocket.ts @@ -1,4 +1,4 @@ -import { useEffect, useRef, useCallback } from 'react'; +import { useEffect, useRef, useCallback, useState } from 'react'; import { IMessage, StompHeaders, StompSubscription } from '@stomp/stompjs'; import { socketManager, SocketOptions } from '../apis/sockets/SocketManager'; import { SocketMessage } from '../apis/sockets/type'; @@ -24,6 +24,9 @@ export const useSocket = () => { new Map(), ); + // ์˜ค๋ฅ˜ ์•ˆ๋‚ด๋ฅผ ์œ„ํ•œ ์ƒํƒœ + const [error, setError] = useState(null); + /** * ์†Œ์ผ“ ์—ฐ๊ฒฐ * HTTP ์—ฐ๊ฒฐ์„ WS ์—ฐ๊ฒฐ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ. @@ -107,16 +110,44 @@ export const useSocket = () => { useEffect(() => { // ์†Œ์ผ“์ด ์—ฐ๊ฒฐ๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋  ํ•ธ๋“ค๋Ÿฌ const handleConnect = () => { - // ๊ธฐ์กด ํ™œ์„ฑํ™”๋œ ๊ตฌ๋… ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐํ™” - activeSubscriptions.current.clear(); - - // ๋ฐฑ์—… ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๊ตฌ๋…์„ ๋‹ค์‹œ ํ™œ์„ฑํ™” - subscriptionInfos.current.forEach((callback, destination) => { - const subscription = socketManager.subscribe(destination, callback); - if (subscription) { + const recover = () => { + // ๊ธฐ์กด ํ™œ์„ฑํ™”๋œ ๊ตฌ๋… ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐํ™” + activeSubscriptions.current.clear(); + + // ๋ฐฑ์—… ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ๊ตฌ๋…์„ ๋‹ค์‹œ ํ™œ์„ฑํ™” + subscriptionInfos.current.forEach((callback, destination) => { + const subscription = socketManager.subscribe(destination, callback); + if (!subscription) { + throw new Error(`์ฑ„๋„ ๊ตฌ๋… ์‹คํŒจ: ${destination}`); + } activeSubscriptions.current.set(destination, subscription); - } - }); + }); + }; + + // ์žฌ์‹œ๋„ ๋ฐ ์˜ค๋ฅ˜ ๋ณต๊ตฌ ์ตœ์ดˆ 1ํšŒ + try { + recover(); + } catch (error) { + console.warn('๐Ÿšจ ๋ฆฌ์Šค๋„ˆ ๋ณต๊ตฌ 1์ฐจ ์‹คํŒจ, 1์ดˆ ํ›„ ์žฌ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.', error); + + // 1์ดˆ ํ›„ 2์ฐจ ๋ณต๊ตฌ ์‹œ๋„ + setTimeout(() => { + try { + recover(); + } catch (retryError) { + console.error( + '๐Ÿšจ ์žฌ์‹œ๋„ ์‹คํŒจ! ๋ณต๊ตฌ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.', + retryError, + ); + // ๐Ÿ’ก ํ›…์ด ์ž์ฒด์ ์œผ๋กœ ์—๋Ÿฌ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ + setError( + retryError instanceof Error + ? retryError + : new Error(String(retryError)), + ); + } + }, 1000); + } }; // ์ด ํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜๋ฅผ ๋ฐœํ–‰์ž(SocketManager)์— ๋“ฑ๋ก @@ -152,5 +183,6 @@ export const useSocket = () => { subscribe, unsubscribe, publish, + error, }; };