diff --git a/package-lock.json b/package-lock.json
index e738d32ba..93092b07e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -51,7 +51,7 @@
                 "nyc": "^17.1.0",
                 "prettier": "^3.0.0",
                 "rollup": "^4.3.0",
-                "sinon": "^15.0.0",
+                "sinon": "^20.0.0",
                 "source-map-support": "^0.5.19",
                 "stream-browserify": "^3.0.0",
                 "ts-node": "^10.4.0",
@@ -2777,48 +2777,46 @@
             ]
         },
         "node_modules/@sinonjs/commons": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
-            "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+            "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
             "dev": true,
+            "license": "BSD-3-Clause",
             "dependencies": {
                 "type-detect": "4.0.8"
             }
         },
         "node_modules/@sinonjs/fake-timers": {
-            "version": "10.3.0",
-            "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
-            "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
-            "dev": true,
-            "dependencies": {
-                "@sinonjs/commons": "^3.0.0"
-            }
-        },
-        "node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
-            "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
+            "version": "13.0.5",
+            "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
+            "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
             "dev": true,
+            "license": "BSD-3-Clause",
             "dependencies": {
-                "type-detect": "4.0.8"
+                "@sinonjs/commons": "^3.0.1"
             }
         },
         "node_modules/@sinonjs/samsam": {
-            "version": "8.0.0",
-            "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz",
-            "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==",
+            "version": "8.0.2",
+            "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz",
+            "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==",
             "dev": true,
+            "license": "BSD-3-Clause",
             "dependencies": {
-                "@sinonjs/commons": "^2.0.0",
+                "@sinonjs/commons": "^3.0.1",
                 "lodash.get": "^4.4.2",
-                "type-detect": "^4.0.8"
+                "type-detect": "^4.1.0"
             }
         },
-        "node_modules/@sinonjs/text-encoding": {
-            "version": "0.7.2",
-            "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz",
-            "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
-            "dev": true
+        "node_modules/@sinonjs/samsam/node_modules/type-detect": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+            "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
         },
         "node_modules/@socket.io/component-emitter": {
             "version": "3.1.0",
@@ -7455,12 +7453,6 @@
                 "node": ">=10"
             }
         },
-        "node_modules/just-extend": {
-            "version": "4.2.1",
-            "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
-            "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
-            "dev": true
-        },
         "node_modules/jwa": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
@@ -7978,7 +7970,9 @@
             "version": "4.4.2",
             "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
             "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
-            "dev": true
+            "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/lodash.includes": {
             "version": "4.3.0",
@@ -8785,19 +8779,6 @@
                 "node": ">= 0.6"
             }
         },
-        "node_modules/nise": {
-            "version": "5.1.4",
-            "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz",
-            "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==",
-            "dev": true,
-            "dependencies": {
-                "@sinonjs/commons": "^2.0.0",
-                "@sinonjs/fake-timers": "^10.0.2",
-                "@sinonjs/text-encoding": "^0.7.1",
-                "just-extend": "^4.0.2",
-                "path-to-regexp": "^1.7.0"
-            }
-        },
         "node_modules/node-fetch": {
             "version": "2.6.7",
             "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
@@ -9568,21 +9549,6 @@
             "dev": true,
             "license": "ISC"
         },
-        "node_modules/path-to-regexp": {
-            "version": "1.8.0",
-            "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
-            "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
-            "dev": true,
-            "dependencies": {
-                "isarray": "0.0.1"
-            }
-        },
-        "node_modules/path-to-regexp/node_modules/isarray": {
-            "version": "0.0.1",
-            "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-            "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
-            "dev": true
-        },
         "node_modules/pathval": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
@@ -10672,16 +10638,16 @@
             "dev": true
         },
         "node_modules/sinon": {
-            "version": "15.2.0",
-            "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz",
-            "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==",
+            "version": "20.0.0",
+            "resolved": "https://registry.npmjs.org/sinon/-/sinon-20.0.0.tgz",
+            "integrity": "sha512-+FXOAbdnj94AQIxH0w1v8gzNxkawVvNqE3jUzRLptR71Oykeu2RrQXXl/VQjKay+Qnh73fDt/oDfMo6xMeDQbQ==",
             "dev": true,
+            "license": "BSD-3-Clause",
             "dependencies": {
-                "@sinonjs/commons": "^3.0.0",
-                "@sinonjs/fake-timers": "^10.3.0",
-                "@sinonjs/samsam": "^8.0.0",
-                "diff": "^5.1.0",
-                "nise": "^5.1.4",
+                "@sinonjs/commons": "^3.0.1",
+                "@sinonjs/fake-timers": "^13.0.5",
+                "@sinonjs/samsam": "^8.0.1",
+                "diff": "^7.0.0",
                 "supports-color": "^7.2.0"
             },
             "funding": {
@@ -10689,20 +10655,12 @@
                 "url": "https://opencollective.com/sinon"
             }
         },
-        "node_modules/sinon/node_modules/@sinonjs/commons": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
-            "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
-            "dev": true,
-            "dependencies": {
-                "type-detect": "4.0.8"
-            }
-        },
         "node_modules/sinon/node_modules/diff": {
-            "version": "5.1.0",
-            "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
-            "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+            "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
             "dev": true,
+            "license": "BSD-3-Clause",
             "engines": {
                 "node": ">=0.3.1"
             }
@@ -13979,51 +13937,42 @@
             "optional": true
         },
         "@sinonjs/commons": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
-            "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+            "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
             "dev": true,
             "requires": {
                 "type-detect": "4.0.8"
             }
         },
         "@sinonjs/fake-timers": {
-            "version": "10.3.0",
-            "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
-            "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
+            "version": "13.0.5",
+            "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
+            "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
             "dev": true,
             "requires": {
-                "@sinonjs/commons": "^3.0.0"
-            },
-            "dependencies": {
-                "@sinonjs/commons": {
-                    "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
-                    "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
-                    "dev": true,
-                    "requires": {
-                        "type-detect": "4.0.8"
-                    }
-                }
+                "@sinonjs/commons": "^3.0.1"
             }
         },
         "@sinonjs/samsam": {
-            "version": "8.0.0",
-            "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz",
-            "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==",
+            "version": "8.0.2",
+            "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz",
+            "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==",
             "dev": true,
             "requires": {
-                "@sinonjs/commons": "^2.0.0",
+                "@sinonjs/commons": "^3.0.1",
                 "lodash.get": "^4.4.2",
-                "type-detect": "^4.0.8"
+                "type-detect": "^4.1.0"
+            },
+            "dependencies": {
+                "type-detect": {
+                    "version": "4.1.0",
+                    "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+                    "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
+                    "dev": true
+                }
             }
         },
-        "@sinonjs/text-encoding": {
-            "version": "0.7.2",
-            "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz",
-            "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
-            "dev": true
-        },
         "@socket.io/component-emitter": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
@@ -17408,12 +17357,6 @@
                 }
             }
         },
-        "just-extend": {
-            "version": "4.2.1",
-            "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
-            "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
-            "dev": true
-        },
         "jwa": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
@@ -18404,19 +18347,6 @@
             "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
             "dev": true
         },
-        "nise": {
-            "version": "5.1.4",
-            "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz",
-            "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==",
-            "dev": true,
-            "requires": {
-                "@sinonjs/commons": "^2.0.0",
-                "@sinonjs/fake-timers": "^10.0.2",
-                "@sinonjs/text-encoding": "^0.7.1",
-                "just-extend": "^4.0.2",
-                "path-to-regexp": "^1.7.0"
-            }
-        },
         "node-fetch": {
             "version": "2.6.7",
             "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
@@ -18986,23 +18916,6 @@
                 }
             }
         },
-        "path-to-regexp": {
-            "version": "1.8.0",
-            "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
-            "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
-            "dev": true,
-            "requires": {
-                "isarray": "0.0.1"
-            },
-            "dependencies": {
-                "isarray": {
-                    "version": "0.0.1",
-                    "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-                    "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
-                    "dev": true
-                }
-            }
-        },
         "pathval": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
@@ -19783,32 +19696,22 @@
             "dev": true
         },
         "sinon": {
-            "version": "15.2.0",
-            "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz",
-            "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==",
+            "version": "20.0.0",
+            "resolved": "https://registry.npmjs.org/sinon/-/sinon-20.0.0.tgz",
+            "integrity": "sha512-+FXOAbdnj94AQIxH0w1v8gzNxkawVvNqE3jUzRLptR71Oykeu2RrQXXl/VQjKay+Qnh73fDt/oDfMo6xMeDQbQ==",
             "dev": true,
             "requires": {
-                "@sinonjs/commons": "^3.0.0",
-                "@sinonjs/fake-timers": "^10.3.0",
-                "@sinonjs/samsam": "^8.0.0",
-                "diff": "^5.1.0",
-                "nise": "^5.1.4",
+                "@sinonjs/commons": "^3.0.1",
+                "@sinonjs/fake-timers": "^13.0.5",
+                "@sinonjs/samsam": "^8.0.1",
+                "diff": "^7.0.0",
                 "supports-color": "^7.2.0"
             },
             "dependencies": {
-                "@sinonjs/commons": {
-                    "version": "3.0.0",
-                    "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz",
-                    "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==",
-                    "dev": true,
-                    "requires": {
-                        "type-detect": "4.0.8"
-                    }
-                },
                 "diff": {
-                    "version": "5.1.0",
-                    "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
-                    "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
+                    "version": "7.0.0",
+                    "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+                    "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
                     "dev": true
                 },
                 "has-flag": {
diff --git a/package.json b/package.json
index 211595d57..6b213d734 100644
--- a/package.json
+++ b/package.json
@@ -124,7 +124,7 @@
         "nyc": "^17.1.0",
         "prettier": "^3.0.0",
         "rollup": "^4.3.0",
-        "sinon": "^15.0.0",
+        "sinon": "^20.0.0",
         "source-map-support": "^0.5.19",
         "stream-browserify": "^3.0.0",
         "ts-node": "^10.4.0",