mediawiki/libs/LangConv (main)

sourcepatches
From f86bf41c06fe93490ec6f34f542389b6e0ea3a3b Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Thu, 18 Apr 2024 11:46:21 +0000
Subject: [PATCH] build: Updating eslint-config-wikimedia to 0.27.0

Change-Id: I26a3a2b33192867913a536fd0f1cf6a7256b2e3f
---
 lib/FST.js                  |    4 +
 lib/ReplacementMachine.js   |    6 +
 package-lock.json           | 1020 +++++++++++++++--------------------
 package.json                |    2 +-
 tools/build-langconv-fst.js |    1 +
 5 files changed, 434 insertions(+), 599 deletions(-)

diff --git a/lib/FST.js b/lib/FST.js
index 668ee5a..ecc26e8 100644
--- a/lib/FST.js
+++ b/lib/FST.js
@@ -1,6 +1,7 @@
 /**
  * Load and execute a finite-state transducer (FST) based converter or
  * bracketing machine from a compact JSON description.
+ *
  * @module
  */
 
@@ -21,6 +22,7 @@ const BYTE_EPSILON  = 0x00; // Always appears first in sorted order
 
 /**
  * A FST conversion machine.
+ *
  * @callback module:language/FST~ConversionMachine
  * @param {Buffer} buffer UTF-8 encoded input buffer.
  * @param {number} [start] Start position in the buffer, default 0.
@@ -31,6 +33,7 @@ const BYTE_EPSILON  = 0x00; // Always appears first in sorted order
 
 /**
  * A FST bracket machine.
+ *
  * @callback module:language/FST~BracketMachine
  * @param {Buffer} buffer UTF-8 encoded input buffer.
  * @param {number} [start] Start position in the buffer, default 0.
@@ -41,6 +44,7 @@ const BYTE_EPSILON  = 0x00; // Always appears first in sorted order
 
 /**
  * Load an FST description and return a function which runs the machine.
+ *
  * @param {Buffer|Utf8Array|string} file The FST description, either as a
  *  filename (to be loaded synchronously) or a loaded byte array.
  * @param {boolean} [justBrackets] The machine will return an array of
diff --git a/lib/ReplacementMachine.js b/lib/ReplacementMachine.js
index 87a577c..d8d7b93 100644
--- a/lib/ReplacementMachine.js
+++ b/lib/ReplacementMachine.js
@@ -1,6 +1,7 @@
 /**
  * This is a wrapper around functionality similar to PHP's `ReplacementArray`,
  * but built on (reversible) Finite-State Transducers.
+ *
  * @module
  */
 
@@ -12,6 +13,7 @@ class ReplacementMachine {
 	/**
 	 * Create a new ReplacementArray, which holds a given source->destination
 	 * transformation.
+	 *
 	 * @param baseLanguage
 	 * @param {...any} codes
 	 */
@@ -45,6 +47,7 @@ class ReplacementMachine {
 	 * possible code pairs bracketed.  (For example, zh has a large
 	 * number of variants, but we typically want to use only a limited
 	 * number of these as possible invert codes.)
+	 *
 	 * @param {string} destCode
 	 * @param {string} invertCode
 	 * @return {boolean} whether this is a valid bracketing pair.
@@ -63,6 +66,7 @@ class ReplacementMachine {
 	 * the number of codepoints we wouldn't have to escape, and `len` is
 	 * the total number of codepoints in `s`.  Generally lower values of
 	 * `nonsafe` indicate a better guess for `invertCode`.
+	 *
 	 * @param s
 	 * @param destCode
 	 * @param invertCode
@@ -96,6 +100,7 @@ class ReplacementMachine {
 	 * Replace the given text Node with converted text, protecting any
 	 * markup which can't be round-tripped back to `invertCode` with
 	 * appropriate synthetic language-converter markup.
+	 *
 	 * @param {Node} textNode
 	 * @param {string} destCode
 	 * @param {string} invertCode
@@ -127,6 +132,7 @@ class ReplacementMachine {
 	 * markup which can't be round-tripped back to `invertCode` with
 	 * appropriate synthetic language-converter markup.  Returns
 	 * a DocumentFragment.
+	 *
 	 * @param {Document} document
 	 *   Owner of the resulting DocumentFragment.
 	 * @param {string} s
diff --git a/package-lock.json b/package-lock.json
index 5358bd1..2f8b1fa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,7 @@
 				"babybird": "^0.0.1",
 				"chai": "^4.2.0",
 				"domino": "^2.1.0",
-				"eslint-config-wikimedia": "0.26.0",
+				"eslint-config-wikimedia": "0.27.0",
 				"jsdoc": "4.0.2",
 				"jsdoc-wmf-theme": "0.0.12",
 				"mocha": "^7.1.2",
@@ -30,32 +30,18 @@
 			}
 		},
 		"node_modules/@babel/code-frame": {
-			"version": "7.23.5",
-			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
-			"integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+			"integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
 			"dev": true,
 			"dependencies": {
-				"@babel/highlight": "^7.23.4",
-				"chalk": "^2.4.2"
+				"@babel/highlight": "^7.24.2",
+				"picocolors": "^1.0.0"
 			},
 			"engines": {
 				"node": ">=6.9.0"
 			}
 		},
-		"node_modules/@babel/code-frame/node_modules/chalk": {
-			"version": "2.4.2",
-			"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-			"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-			"dev": true,
-			"dependencies": {
-				"ansi-styles": "^3.2.1",
-				"escape-string-regexp": "^1.0.5",
-				"supports-color": "^5.3.0"
-			},
-			"engines": {
-				"node": ">=4"
-			}
-		},
 		"node_modules/@babel/helper-validator-identifier": {
 			"version": "7.22.20",
 			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
@@ -66,14 +52,15 @@
 			}
 		},
 		"node_modules/@babel/highlight": {
-			"version": "7.23.4",
-			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
-			"integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
+			"integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
 			"dev": true,
 			"dependencies": {
 				"@babel/helper-validator-identifier": "^7.22.20",
 				"chalk": "^2.4.2",
-				"js-tokens": "^4.0.0"
+				"js-tokens": "^4.0.0",
+				"picocolors": "^1.0.0"
 			},
 			"engines": {
 				"node": ">=6.9.0"
@@ -106,17 +93,17 @@
 			}
 		},
 		"node_modules/@es-joy/jsdoccomment": {
-			"version": "0.37.1",
-			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.37.1.tgz",
-			"integrity": "sha512-5vxWJ1gEkEF0yRd0O+uK6dHJf7adrxwQSX8PuRiPfFSAbNLnY0ZJfXaZucoz14Jj2N11xn2DnlEPwWRpYpvRjg==",
+			"version": "0.42.0",
+			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz",
+			"integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==",
 			"dev": true,
 			"dependencies": {
-				"comment-parser": "1.3.1",
+				"comment-parser": "1.4.1",
 				"esquery": "^1.5.0",
 				"jsdoc-type-pratt-parser": "~4.0.0"
 			},
 			"engines": {
-				"node": "^14 || ^16 || ^17 || ^18 || ^19 || ^20"
+				"node": ">=16"
 			}
 		},
 		"node_modules/@eslint-community/eslint-utils": {
@@ -134,15 +121,6 @@
 				"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
 			}
 		},
-		"node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
-			"version": "3.3.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-			"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			}
-		},
 		"node_modules/@eslint-community/regexpp": {
 			"version": "4.10.0",
 			"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
@@ -188,9 +166,9 @@
 			}
 		},
 		"node_modules/@eslint/js": {
-			"version": "8.56.0",
-			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
-			"integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+			"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
 			"dev": true,
 			"engines": {
 				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -329,9 +307,9 @@
 			"dev": true
 		},
 		"node_modules/@types/semver": {
-			"version": "7.5.6",
-			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz",
-			"integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==",
+			"version": "7.5.8",
+			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+			"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
 			"dev": true
 		},
 		"node_modules/@typescript-eslint/scope-manager": {
@@ -456,18 +434,6 @@
 				"url": "https://opencollective.com/typescript-eslint"
 			}
 		},
-		"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
 		"node_modules/@ungap/structured-clone": {
 			"version": "1.2.0",
 			"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
@@ -672,9 +638,9 @@
 			"dev": true
 		},
 		"node_modules/browserslist": {
-			"version": "4.21.10",
-			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
-			"integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==",
+			"version": "4.23.0",
+			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+			"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
 			"dev": true,
 			"funding": [
 				{
@@ -691,10 +657,10 @@
 				}
 			],
 			"dependencies": {
-				"caniuse-lite": "^1.0.30001517",
-				"electron-to-chromium": "^1.4.477",
-				"node-releases": "^2.0.13",
-				"update-browserslist-db": "^1.0.11"
+				"caniuse-lite": "^1.0.30001587",
+				"electron-to-chromium": "^1.4.668",
+				"node-releases": "^2.0.14",
+				"update-browserslist-db": "^1.0.13"
 			},
 			"bin": {
 				"browserslist": "cli.js"
@@ -704,9 +670,9 @@
 			}
 		},
 		"node_modules/browserslist-config-wikimedia": {
-			"version": "0.5.1",
-			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.5.1.tgz",
-			"integrity": "sha512-jf532fUf/gaxiKdHgGCQUT552P5up3RpG+CzLixOQBJ5FwDmYQSRLYHCFUA9s3KMOHh4P3xVp+NUaGNxvtoT9g==",
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.6.1.tgz",
+			"integrity": "sha512-F3O+12ud7ZwBaiB/RZIMGDgz3nEuXz8RhtdPB4Lkd/WVP5Vy77EqBWRMz4vJ64x8LTTH3BOaHCD2ZuUcgShqyQ==",
 			"dev": true
 		},
 		"node_modules/builtin-modules": {
@@ -749,9 +715,9 @@
 			}
 		},
 		"node_modules/caniuse-lite": {
-			"version": "1.0.30001583",
-			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001583.tgz",
-			"integrity": "sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==",
+			"version": "1.0.30001611",
+			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001611.tgz",
+			"integrity": "sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==",
 			"dev": true,
 			"funding": [
 				{
@@ -898,9 +864,9 @@
 			}
 		},
 		"node_modules/ci-info": {
-			"version": "3.9.0",
-			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
-			"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz",
+			"integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==",
 			"dev": true,
 			"funding": [
 				{
@@ -972,9 +938,9 @@
 			"dev": true
 		},
 		"node_modules/comment-parser": {
-			"version": "1.3.1",
-			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
-			"integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+			"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
 			"dev": true,
 			"engines": {
 				"node": ">= 12.0.0"
@@ -994,6 +960,19 @@
 			"hasInstallScript": true,
 			"optional": true
 		},
+		"node_modules/core-js-compat": {
+			"version": "3.37.0",
+			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz",
+			"integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==",
+			"dev": true,
+			"dependencies": {
+				"browserslist": "^4.23.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/core-js"
+			}
+		},
 		"node_modules/cross-spawn": {
 			"version": "7.0.3",
 			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -1116,9 +1095,9 @@
 			"dev": true
 		},
 		"node_modules/electron-to-chromium": {
-			"version": "1.4.499",
-			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.499.tgz",
-			"integrity": "sha512-0NmjlYBLKVHva4GABWAaHuPJolnDuL0AhV3h1hES6rcLCWEIbRL6/8TghfsVwkx6TEroQVdliX7+aLysUpKvjw==",
+			"version": "1.4.740",
+			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.740.tgz",
+			"integrity": "sha512-Yvg5i+iyv7Xm18BRdVPVm8lc7kgxM3r6iwqCH2zB7QZy1kZRNmd0Zqm0zcD9XoFREE5/5rwIuIAOT+/mzGcnZg==",
 			"dev": true
 		},
 		"node_modules/emoji-regex": {
@@ -1182,9 +1161,9 @@
 			}
 		},
 		"node_modules/escalade": {
-			"version": "3.1.1",
-			"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-			"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+			"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
 			"dev": true,
 			"engines": {
 				"node": ">=6"
@@ -1200,16 +1179,16 @@
 			}
 		},
 		"node_modules/eslint": {
-			"version": "8.56.0",
-			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
-			"integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+			"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
 			"dev": true,
 			"dependencies": {
 				"@eslint-community/eslint-utils": "^4.2.0",
 				"@eslint-community/regexpp": "^4.6.1",
 				"@eslint/eslintrc": "^2.1.4",
-				"@eslint/js": "8.56.0",
-				"@humanwhocodes/config-array": "^0.11.13",
+				"@eslint/js": "8.57.0",
+				"@humanwhocodes/config-array": "^0.11.14",
 				"@humanwhocodes/module-importer": "^1.0.1",
 				"@nodelib/fs.walk": "^1.2.8",
 				"@ungap/structured-clone": "^1.2.0",
@@ -1255,10 +1234,13 @@
 			}
 		},
 		"node_modules/eslint-compat-utils": {
-			"version": "0.1.2",
-			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz",
-			"integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==",
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz",
+			"integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==",
 			"dev": true,
+			"dependencies": {
+				"semver": "^7.5.4"
+			},
 			"engines": {
 				"node": ">=12"
 			},
@@ -1267,85 +1249,28 @@
 			}
 		},
 		"node_modules/eslint-config-wikimedia": {
-			"version": "0.26.0",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.26.0.tgz",
-			"integrity": "sha512-TAXTySls9k3oWs754rIjlcd9PBLvYeMvjqjiuU8u4gweu0UDgBJGslf+zcvVNXEooAtyLZdENjrzDDjG8ssS7Q==",
+			"version": "0.27.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.27.0.tgz",
+			"integrity": "sha512-KkZ54+MUnggz17C/RCEMXQSpiiqZRF7p9fjrz4phaaeKlTrjg0B+QbM5zcDWcjGiAWaJUptHaH17+RZldadkUw==",
 			"dev": true,
 			"dependencies": {
-				"browserslist-config-wikimedia": "^0.5.1",
-				"eslint": "^8.53.0",
+				"browserslist-config-wikimedia": "^0.6.1",
+				"eslint": "^8.57.0",
 				"eslint-plugin-compat": "^4.2.0",
-				"eslint-plugin-es-x": "^7.3.0",
-				"eslint-plugin-jest": "^27.6.0",
-				"eslint-plugin-jsdoc": "^42.0.0",
+				"eslint-plugin-es-x": "^7.6.0",
+				"eslint-plugin-jest": "^27.9.0",
+				"eslint-plugin-jsdoc": "48.2.1",
 				"eslint-plugin-json-es": "^1.5.7",
-				"eslint-plugin-mediawiki": "^0.5.0",
-				"eslint-plugin-mocha": "^10.2.0",
-				"eslint-plugin-n": "^16.0.1",
+				"eslint-plugin-mediawiki": "^0.6.0",
+				"eslint-plugin-mocha": "^10.4.1",
+				"eslint-plugin-n": "^16.6.2",
 				"eslint-plugin-no-jquery": "^2.7.0",
-				"eslint-plugin-qunit": "^7.3.4",
+				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
-				"eslint-plugin-unicorn": "^47.0.0",
-				"eslint-plugin-vue": "^9.18.1",
-				"eslint-plugin-wdio": "^7.19.4",
-				"eslint-plugin-yml": "^1.10.0"
-			}
-		},
-		"node_modules/eslint-config-wikimedia/node_modules/eslint-plugin-vue": {
-			"version": "9.21.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz",
-			"integrity": "sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==",
-			"dev": true,
-			"dependencies": {
-				"@eslint-community/eslint-utils": "^4.4.0",
-				"natural-compare": "^1.4.0",
-				"nth-check": "^2.1.1",
-				"postcss-selector-parser": "^6.0.13",
-				"semver": "^7.5.4",
-				"vue-eslint-parser": "^9.4.2",
-				"xml-name-validator": "^4.0.0"
-			},
-			"engines": {
-				"node": "^14.17.0 || >=16.0.0"
-			},
-			"peerDependencies": {
-				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
-			}
-		},
-		"node_modules/eslint-config-wikimedia/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
-		"node_modules/eslint-config-wikimedia/node_modules/vue-eslint-parser": {
-			"version": "9.4.2",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
-			"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
-			"dev": true,
-			"dependencies": {
-				"debug": "^4.3.4",
-				"eslint-scope": "^7.1.1",
-				"eslint-visitor-keys": "^3.3.0",
-				"espree": "^9.3.1",
-				"esquery": "^1.4.0",
-				"lodash": "^4.17.21",
-				"semver": "^7.3.6"
-			},
-			"engines": {
-				"node": "^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
-			},
-			"peerDependencies": {
-				"eslint": ">=6.0.0"
+				"eslint-plugin-unicorn": "^51.0.1",
+				"eslint-plugin-vue": "^9.23.0",
+				"eslint-plugin-wdio": "^8.24.12",
+				"eslint-plugin-yml": "^1.13.2"
 			}
 		},
 		"node_modules/eslint-plugin-compat": {
@@ -1440,14 +1365,14 @@
 			}
 		},
 		"node_modules/eslint-plugin-es-x": {
-			"version": "7.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz",
-			"integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz",
+			"integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==",
 			"dev": true,
 			"dependencies": {
 				"@eslint-community/eslint-utils": "^4.1.2",
 				"@eslint-community/regexpp": "^4.6.0",
-				"eslint-compat-utils": "^0.1.2"
+				"eslint-compat-utils": "^0.5.0"
 			},
 			"engines": {
 				"node": "^14.18.0 || >=16.0.0"
@@ -1460,9 +1385,9 @@
 			}
 		},
 		"node_modules/eslint-plugin-jest": {
-			"version": "27.6.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.6.3.tgz",
-			"integrity": "sha512-+YsJFVH6R+tOiO3gCJon5oqn4KWc+mDq2leudk8mrp8RFubLOo9CVyi3cib4L7XMpxExmkmBZQTPDYVBzgpgOA==",
+			"version": "27.9.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz",
+			"integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==",
 			"dev": true,
 			"dependencies": {
 				"@typescript-eslint/utils": "^5.10.0"
@@ -1471,7 +1396,7 @@
 				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
 			},
 			"peerDependencies": {
-				"@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0",
+				"@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0",
 				"eslint": "^7.0.0 || ^8.0.0",
 				"jest": "*"
 			},
@@ -1485,25 +1410,26 @@
 			}
 		},
 		"node_modules/eslint-plugin-jsdoc": {
-			"version": "42.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-42.0.0.tgz",
-			"integrity": "sha512-qXYr45G8atPKowZbIOdmABukMzu9IMjAlj6j5Fe0iuUItznWSXUDiBj57ejXcbt8bkPrg83333nuz+cqGKFgcQ==",
+			"version": "48.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz",
+			"integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==",
 			"dev": true,
 			"dependencies": {
-				"@es-joy/jsdoccomment": "~0.37.0",
+				"@es-joy/jsdoccomment": "~0.42.0",
 				"are-docs-informative": "^0.0.2",
-				"comment-parser": "1.3.1",
+				"comment-parser": "1.4.1",
 				"debug": "^4.3.4",
 				"escape-string-regexp": "^4.0.0",
 				"esquery": "^1.5.0",
-				"semver": "^7.3.8",
-				"spdx-expression-parse": "^3.0.1"
+				"is-builtin-module": "^3.2.1",
+				"semver": "^7.6.0",
+				"spdx-expression-parse": "^4.0.0"
 			},
 			"engines": {
-				"node": "^14 || ^16 || ^17 || ^18 || ^19"
+				"node": ">=18"
 			},
 			"peerDependencies": {
-				"eslint": "^7.0.0 || ^8.0.0"
+				"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": {
@@ -1531,22 +1457,13 @@
 				"eslint": ">= 7"
 			}
 		},
-		"node_modules/eslint-plugin-json-es/node_modules/eslint-visitor-keys": {
-			"version": "3.3.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-			"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			}
-		},
 		"node_modules/eslint-plugin-mediawiki": {
-			"version": "0.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.5.0.tgz",
-			"integrity": "sha512-rjkHFyv3VDan/dmu7YpD1Rl9h64NOlz4mqqesRN316R+571+ymmb6lXVOdNMbT8H1iPhmtHc+nijVLVkn7pYDw==",
+			"version": "0.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.6.0.tgz",
+			"integrity": "sha512-a2Zm18N5nPyflBajM2ZWATxucIpYPEmOSjFzUR1OBH3hAL0GY9fx1mpezEwzqAQ862d+kPkolgQOzktnZe8nKA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-plugin-vue": "^8.7.1",
+				"eslint-plugin-vue": "^9.23.0",
 				"upath": "^2.0.1"
 			},
 			"peerDependencies": {
@@ -1554,12 +1471,13 @@
 			}
 		},
 		"node_modules/eslint-plugin-mocha": {
-			"version": "10.2.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.2.0.tgz",
-			"integrity": "sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ==",
+			"version": "10.4.2",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.2.tgz",
+			"integrity": "sha512-cur4dVYnSEWTBwdqIBQFxa/9siAhesu0TX+lbJ4ClE9j0eNMNe6BSx3vkFFNz6tGoveyMyELFXa30f3fvuAVDg==",
 			"dev": true,
 			"dependencies": {
 				"eslint-utils": "^3.0.0",
+				"globals": "^13.24.0",
 				"rambda": "^7.4.0"
 			},
 			"engines": {
@@ -1619,16 +1537,16 @@
 			}
 		},
 		"node_modules/eslint-plugin-qunit": {
-			"version": "7.3.4",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.3.4.tgz",
-			"integrity": "sha512-EbDM0zJerH9zVdUswMJpcFF7wrrpvsGuYfNexUpa5hZkkdFhaFcX+yD+RSK4Nrauw4psMGlcqeWUMhaVo+Manw==",
+			"version": "8.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-8.1.1.tgz",
+			"integrity": "sha512-j3xhiAf2Wvr8Dfwl5T6tlJ+F55vqYE9ZdAHUOTzq1lGerYrXzOS46RvK4SSWug2D8sl3ZYr2lA4/hgVXgLloxw==",
 			"dev": true,
 			"dependencies": {
 				"eslint-utils": "^3.0.0",
 				"requireindex": "^1.2.0"
 			},
 			"engines": {
-				"node": "12.x || 14.x || >=16.0.0"
+				"node": "^16.0.0 || ^18.0.0 || >=20.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-security": {
@@ -1641,26 +1559,26 @@
 			}
 		},
 		"node_modules/eslint-plugin-unicorn": {
-			"version": "47.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-47.0.0.tgz",
-			"integrity": "sha512-ivB3bKk7fDIeWOUmmMm9o3Ax9zbMz1Bsza/R2qm46ufw4T6VBFBaJIR1uN3pCKSmSXm8/9Nri8V+iUut1NhQGA==",
+			"version": "51.0.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz",
+			"integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-validator-identifier": "^7.19.1",
+				"@babel/helper-validator-identifier": "^7.22.20",
 				"@eslint-community/eslint-utils": "^4.4.0",
-				"ci-info": "^3.8.0",
+				"@eslint/eslintrc": "^2.1.4",
+				"ci-info": "^4.0.0",
 				"clean-regexp": "^1.0.0",
+				"core-js-compat": "^3.34.0",
 				"esquery": "^1.5.0",
 				"indent-string": "^4.0.0",
 				"is-builtin-module": "^3.2.1",
 				"jsesc": "^3.0.2",
-				"lodash": "^4.17.21",
 				"pluralize": "^8.0.0",
 				"read-pkg-up": "^7.0.1",
-				"regexp-tree": "^0.1.24",
+				"regexp-tree": "^0.1.27",
 				"regjsparser": "^0.10.0",
-				"safe-regex": "^2.1.1",
-				"semver": "^7.3.8",
+				"semver": "^7.5.4",
 				"strip-indent": "^3.0.0"
 			},
 			"engines": {
@@ -1670,46 +1588,48 @@
 				"url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1"
 			},
 			"peerDependencies": {
-				"eslint": ">=8.38.0"
+				"eslint": ">=8.56.0"
 			}
 		},
 		"node_modules/eslint-plugin-vue": {
-			"version": "8.7.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz",
-			"integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==",
+			"version": "9.25.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz",
+			"integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-utils": "^3.0.0",
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"globals": "^13.24.0",
 				"natural-compare": "^1.4.0",
-				"nth-check": "^2.0.1",
-				"postcss-selector-parser": "^6.0.9",
-				"semver": "^7.3.5",
-				"vue-eslint-parser": "^8.0.1"
+				"nth-check": "^2.1.1",
+				"postcss-selector-parser": "^6.0.15",
+				"semver": "^7.6.0",
+				"vue-eslint-parser": "^9.4.2",
+				"xml-name-validator": "^4.0.0"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"peerDependencies": {
-				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
+				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-wdio": {
-			"version": "7.25.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.25.3.tgz",
-			"integrity": "sha512-2zbYwV14Md9FNlyhaIILVGPB6w4bu2eJdOTywDUs2Qy4ebcQNwrxB0qCaf7Rm4O+T0Ir+tdYHYBBfbDocSLKng==",
+			"version": "8.24.12",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-8.24.12.tgz",
+			"integrity": "sha512-OmzGteXFOQnJDdkTNnTfksaVa18WlFCyeLjZXHvDpkbomLWAg9wc296Pr0wnTCagqNj8qfEHpy+N2XVew5VCMA==",
 			"dev": true,
 			"engines": {
-				"node": ">=12.0.0"
+				"node": "^16.13 || >=18"
 			}
 		},
 		"node_modules/eslint-plugin-yml": {
-			"version": "1.12.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.12.2.tgz",
-			"integrity": "sha512-hvS9p08FhPT7i/ynwl7/Wt7ke7Rf4P2D6fT8lZlL43peZDTsHtH2A0SIFQ7Kt7+mJ6if6P+FX3iJhMkdnxQwpg==",
+			"version": "1.14.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz",
+			"integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==",
 			"dev": true,
 			"dependencies": {
 				"debug": "^4.3.2",
-				"eslint-compat-utils": "^0.4.0",
+				"eslint-compat-utils": "^0.5.0",
 				"lodash": "^4.17.21",
 				"natural-compare": "^1.4.0",
 				"yaml-eslint-parser": "^1.2.1"
@@ -1724,21 +1644,6 @@
 				"eslint": ">=6.0.0"
 			}
 		},
-		"node_modules/eslint-plugin-yml/node_modules/eslint-compat-utils": {
-			"version": "0.4.1",
-			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.4.1.tgz",
-			"integrity": "sha512-5N7ZaJG5pZxUeNNJfUchurLVrunD1xJvyg5kYOIVF8kg1f3ajTikmAu/5fZ9w100omNPOoMjngRszh/Q/uFGMg==",
-			"dev": true,
-			"dependencies": {
-				"semver": "^7.5.4"
-			},
-			"engines": {
-				"node": ">=12"
-			},
-			"peerDependencies": {
-				"eslint": ">=6.0.0"
-			}
-		},
 		"node_modules/eslint-scope": {
 			"version": "7.2.2",
 			"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
@@ -1773,7 +1678,7 @@
 				"eslint": ">=5"
 			}
 		},
-		"node_modules/eslint-visitor-keys": {
+		"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
 			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
@@ -1782,28 +1687,28 @@
 				"node": ">=10"
 			}
 		},
-		"node_modules/eslint/node_modules/escape-string-regexp": {
-			"version": "4.0.0",
-			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-			"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+		"node_modules/eslint-visitor-keys": {
+			"version": "3.4.3",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
 			"dev": true,
 			"engines": {
-				"node": ">=10"
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
 			},
 			"funding": {
-				"url": "https://github.com/sponsors/sindresorhus"
+				"url": "https://opencollective.com/eslint"
 			}
 		},
-		"node_modules/eslint/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+		"node_modules/eslint/node_modules/escape-string-regexp": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+			"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
 			"dev": true,
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": ">=10"
 			},
 			"funding": {
-				"url": "https://opencollective.com/eslint"
+				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
 		"node_modules/eslint/node_modules/find-up": {
@@ -1917,18 +1822,6 @@
 				"url": "https://opencollective.com/eslint"
 			}
 		},
-		"node_modules/espree/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
 		"node_modules/esprima": {
 			"version": "4.0.1",
 			"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
@@ -3043,9 +2936,9 @@
 			}
 		},
 		"node_modules/node-releases": {
-			"version": "2.0.13",
-			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
-			"integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+			"version": "2.0.14",
+			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+			"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
 			"dev": true
 		},
 		"node_modules/normalize-package-data": {
@@ -3313,9 +3206,9 @@
 			"dev": true
 		},
 		"node_modules/postcss-selector-parser": {
-			"version": "6.0.15",
-			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
-			"integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
+			"version": "6.0.16",
+			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
+			"integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
 			"dev": true,
 			"dependencies": {
 				"cssesc": "^3.0.0",
@@ -3487,9 +3380,9 @@
 			}
 		},
 		"node_modules/regexp-tree": {
-			"version": "0.1.24",
-			"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz",
-			"integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==",
+			"version": "0.1.27",
+			"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
+			"integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==",
 			"dev": true,
 			"bin": {
 				"regexp-tree": "bin/regexp-tree"
@@ -3642,9 +3535,9 @@
 			}
 		},
 		"node_modules/semver": {
-			"version": "7.5.4",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-			"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+			"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
 			"dev": true,
 			"dependencies": {
 				"lru-cache": "^6.0.0"
@@ -3702,16 +3595,26 @@
 				"spdx-license-ids": "^3.0.0"
 			}
 		},
+		"node_modules/spdx-correct/node_modules/spdx-expression-parse": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"dev": true,
+			"dependencies": {
+				"spdx-exceptions": "^2.1.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
 		"node_modules/spdx-exceptions": {
-			"version": "2.4.0",
-			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz",
-			"integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==",
+			"version": "2.5.0",
+			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+			"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
 			"dev": true
 		},
 		"node_modules/spdx-expression-parse": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
-			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+			"integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
 			"dev": true,
 			"dependencies": {
 				"spdx-exceptions": "^2.1.0",
@@ -3921,9 +3824,9 @@
 			}
 		},
 		"node_modules/typescript": {
-			"version": "5.3.3",
-			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
-			"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+			"version": "5.4.5",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+			"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
 			"dev": true,
 			"peer": true,
 			"bin": {
@@ -3957,9 +3860,9 @@
 			}
 		},
 		"node_modules/update-browserslist-db": {
-			"version": "1.0.11",
-			"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
-			"integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+			"version": "1.0.13",
+			"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+			"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
 			"dev": true,
 			"funding": [
 				{
@@ -4011,22 +3914,32 @@
 				"spdx-expression-parse": "^3.0.0"
 			}
 		},
+		"node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"dev": true,
+			"dependencies": {
+				"spdx-exceptions": "^2.1.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
 		"node_modules/vue-eslint-parser": {
-			"version": "8.3.0",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
-			"integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==",
+			"version": "9.4.2",
+			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+			"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
 			"dev": true,
 			"dependencies": {
-				"debug": "^4.3.2",
-				"eslint-scope": "^7.0.0",
-				"eslint-visitor-keys": "^3.1.0",
-				"espree": "^9.0.0",
+				"debug": "^4.3.4",
+				"eslint-scope": "^7.1.1",
+				"eslint-visitor-keys": "^3.3.0",
+				"espree": "^9.3.1",
 				"esquery": "^1.4.0",
 				"lodash": "^4.17.21",
-				"semver": "^7.3.5"
+				"semver": "^7.3.6"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/mysticatea"
@@ -4035,18 +3948,6 @@
 				"eslint": ">=6.0.0"
 			}
 		},
-		"node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": {
-			"version": "3.4.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
-			"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
 		"node_modules/which": {
 			"version": "2.0.2",
 			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -4180,10 +4081,13 @@
 			"dev": true
 		},
 		"node_modules/yaml": {
-			"version": "2.3.4",
-			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
-			"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
+			"version": "2.4.1",
+			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
+			"integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
 			"dev": true,
+			"bin": {
+				"yaml": "bin.mjs"
+			},
 			"engines": {
 				"node": ">= 14"
 			}
@@ -4205,18 +4109,6 @@
 				"url": "https://github.com/sponsors/ota-meshi"
 			}
 		},
-		"node_modules/yaml-eslint-parser/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
 		"node_modules/yargs": {
 			"version": "13.3.2",
 			"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
@@ -4280,26 +4172,13 @@
 			"dev": true
 		},
 		"@babel/code-frame": {
-			"version": "7.23.5",
-			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
-			"integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+			"integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
 			"dev": true,
 			"requires": {
-				"@babel/highlight": "^7.23.4",
-				"chalk": "^2.4.2"
-			},
-			"dependencies": {
-				"chalk": {
-					"version": "2.4.2",
-					"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-					"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-					"dev": true,
-					"requires": {
-						"ansi-styles": "^3.2.1",
-						"escape-string-regexp": "^1.0.5",
-						"supports-color": "^5.3.0"
-					}
-				}
+				"@babel/highlight": "^7.24.2",
+				"picocolors": "^1.0.0"
 			}
 		},
 		"@babel/helper-validator-identifier": {
@@ -4309,14 +4188,15 @@
 			"dev": true
 		},
 		"@babel/highlight": {
-			"version": "7.23.4",
-			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
-			"integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
+			"integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
 			"dev": true,
 			"requires": {
 				"@babel/helper-validator-identifier": "^7.22.20",
 				"chalk": "^2.4.2",
-				"js-tokens": "^4.0.0"
+				"js-tokens": "^4.0.0",
+				"picocolors": "^1.0.0"
 			},
 			"dependencies": {
 				"chalk": {
@@ -4339,12 +4219,12 @@
 			"dev": true
 		},
 		"@es-joy/jsdoccomment": {
-			"version": "0.37.1",
-			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.37.1.tgz",
-			"integrity": "sha512-5vxWJ1gEkEF0yRd0O+uK6dHJf7adrxwQSX8PuRiPfFSAbNLnY0ZJfXaZucoz14Jj2N11xn2DnlEPwWRpYpvRjg==",
+			"version": "0.42.0",
+			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz",
+			"integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==",
 			"dev": true,
 			"requires": {
-				"comment-parser": "1.3.1",
+				"comment-parser": "1.4.1",
 				"esquery": "^1.5.0",
 				"jsdoc-type-pratt-parser": "~4.0.0"
 			}
@@ -4356,14 +4236,6 @@
 			"dev": true,
 			"requires": {
 				"eslint-visitor-keys": "^3.3.0"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.3.0",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-					"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-					"dev": true
-				}
 			}
 		},
 		"@eslint-community/regexpp": {
@@ -4401,9 +4273,9 @@
 			}
 		},
 		"@eslint/js": {
-			"version": "8.56.0",
-			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
-			"integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+			"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
 			"dev": true
 		},
 		"@humanwhocodes/config-array": {
@@ -4516,9 +4388,9 @@
 			"dev": true
 		},
 		"@types/semver": {
-			"version": "7.5.6",
-			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz",
-			"integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==",
+			"version": "7.5.8",
+			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+			"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
 			"dev": true
 		},
 		"@typescript-eslint/scope-manager": {
@@ -4594,14 +4466,6 @@
 			"requires": {
 				"@typescript-eslint/types": "5.62.0",
 				"eslint-visitor-keys": "^3.3.0"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				}
 			}
 		},
 		"@ungap/structured-clone": {
@@ -4768,21 +4632,21 @@
 			"dev": true
 		},
 		"browserslist": {
-			"version": "4.21.10",
-			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
-			"integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==",
+			"version": "4.23.0",
+			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+			"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
 			"dev": true,
 			"requires": {
-				"caniuse-lite": "^1.0.30001517",
-				"electron-to-chromium": "^1.4.477",
-				"node-releases": "^2.0.13",
-				"update-browserslist-db": "^1.0.11"
+				"caniuse-lite": "^1.0.30001587",
+				"electron-to-chromium": "^1.4.668",
+				"node-releases": "^2.0.14",
+				"update-browserslist-db": "^1.0.13"
 			}
 		},
 		"browserslist-config-wikimedia": {
-			"version": "0.5.1",
-			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.5.1.tgz",
-			"integrity": "sha512-jf532fUf/gaxiKdHgGCQUT552P5up3RpG+CzLixOQBJ5FwDmYQSRLYHCFUA9s3KMOHh4P3xVp+NUaGNxvtoT9g==",
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.6.1.tgz",
+			"integrity": "sha512-F3O+12ud7ZwBaiB/RZIMGDgz3nEuXz8RhtdPB4Lkd/WVP5Vy77EqBWRMz4vJ64x8LTTH3BOaHCD2ZuUcgShqyQ==",
 			"dev": true
 		},
 		"builtin-modules": {
@@ -4813,9 +4677,9 @@
 			"dev": true
 		},
 		"caniuse-lite": {
-			"version": "1.0.30001583",
-			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001583.tgz",
-			"integrity": "sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==",
+			"version": "1.0.30001611",
+			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001611.tgz",
+			"integrity": "sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==",
 			"dev": true
 		},
 		"catharsis": {
@@ -4915,9 +4779,9 @@
 			}
 		},
 		"ci-info": {
-			"version": "3.9.0",
-			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
-			"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz",
+			"integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==",
 			"dev": true
 		},
 		"clean-regexp": {
@@ -4973,9 +4837,9 @@
 			"dev": true
 		},
 		"comment-parser": {
-			"version": "1.3.1",
-			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
-			"integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+			"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
 			"dev": true
 		},
 		"concat-map": {
@@ -4991,6 +4855,15 @@
 			"dev": true,
 			"optional": true
 		},
+		"core-js-compat": {
+			"version": "3.37.0",
+			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz",
+			"integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==",
+			"dev": true,
+			"requires": {
+				"browserslist": "^4.23.0"
+			}
+		},
 		"cross-spawn": {
 			"version": "7.0.3",
 			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -5078,9 +4951,9 @@
 			"dev": true
 		},
 		"electron-to-chromium": {
-			"version": "1.4.499",
-			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.499.tgz",
-			"integrity": "sha512-0NmjlYBLKVHva4GABWAaHuPJolnDuL0AhV3h1hES6rcLCWEIbRL6/8TghfsVwkx6TEroQVdliX7+aLysUpKvjw==",
+			"version": "1.4.740",
+			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.740.tgz",
+			"integrity": "sha512-Yvg5i+iyv7Xm18BRdVPVm8lc7kgxM3r6iwqCH2zB7QZy1kZRNmd0Zqm0zcD9XoFREE5/5rwIuIAOT+/mzGcnZg==",
 			"dev": true
 		},
 		"emoji-regex": {
@@ -5135,9 +5008,9 @@
 			}
 		},
 		"escalade": {
-			"version": "3.1.1",
-			"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-			"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+			"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
 			"dev": true
 		},
 		"escape-string-regexp": {
@@ -5147,16 +5020,16 @@
 			"dev": true
 		},
 		"eslint": {
-			"version": "8.56.0",
-			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
-			"integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+			"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
 			"dev": true,
 			"requires": {
 				"@eslint-community/eslint-utils": "^4.2.0",
 				"@eslint-community/regexpp": "^4.6.1",
 				"@eslint/eslintrc": "^2.1.4",
-				"@eslint/js": "8.56.0",
-				"@humanwhocodes/config-array": "^0.11.13",
+				"@eslint/js": "8.57.0",
+				"@humanwhocodes/config-array": "^0.11.14",
 				"@humanwhocodes/module-importer": "^1.0.1",
 				"@nodelib/fs.walk": "^1.2.8",
 				"@ungap/structured-clone": "^1.2.0",
@@ -5198,12 +5071,6 @@
 					"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
 					"dev": true
 				},
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				},
 				"find-up": {
 					"version": "5.0.0",
 					"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -5268,73 +5135,37 @@
 			}
 		},
 		"eslint-compat-utils": {
-			"version": "0.1.2",
-			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz",
-			"integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==",
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz",
+			"integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==",
 			"dev": true,
-			"requires": {}
+			"requires": {
+				"semver": "^7.5.4"
+			}
 		},
 		"eslint-config-wikimedia": {
-			"version": "0.26.0",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.26.0.tgz",
-			"integrity": "sha512-TAXTySls9k3oWs754rIjlcd9PBLvYeMvjqjiuU8u4gweu0UDgBJGslf+zcvVNXEooAtyLZdENjrzDDjG8ssS7Q==",
+			"version": "0.27.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.27.0.tgz",
+			"integrity": "sha512-KkZ54+MUnggz17C/RCEMXQSpiiqZRF7p9fjrz4phaaeKlTrjg0B+QbM5zcDWcjGiAWaJUptHaH17+RZldadkUw==",
 			"dev": true,
 			"requires": {
-				"browserslist-config-wikimedia": "^0.5.1",
-				"eslint": "^8.53.0",
+				"browserslist-config-wikimedia": "^0.6.1",
+				"eslint": "^8.57.0",
 				"eslint-plugin-compat": "^4.2.0",
-				"eslint-plugin-es-x": "^7.3.0",
-				"eslint-plugin-jest": "^27.6.0",
-				"eslint-plugin-jsdoc": "^42.0.0",
+				"eslint-plugin-es-x": "^7.6.0",
+				"eslint-plugin-jest": "^27.9.0",
+				"eslint-plugin-jsdoc": "48.2.1",
 				"eslint-plugin-json-es": "^1.5.7",
-				"eslint-plugin-mediawiki": "^0.5.0",
-				"eslint-plugin-mocha": "^10.2.0",
-				"eslint-plugin-n": "^16.0.1",
+				"eslint-plugin-mediawiki": "^0.6.0",
+				"eslint-plugin-mocha": "^10.4.1",
+				"eslint-plugin-n": "^16.6.2",
 				"eslint-plugin-no-jquery": "^2.7.0",
-				"eslint-plugin-qunit": "^7.3.4",
+				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
-				"eslint-plugin-unicorn": "^47.0.0",
-				"eslint-plugin-vue": "^9.18.1",
-				"eslint-plugin-wdio": "^7.19.4",
-				"eslint-plugin-yml": "^1.10.0"
-			},
-			"dependencies": {
-				"eslint-plugin-vue": {
-					"version": "9.21.1",
-					"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz",
-					"integrity": "sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==",
-					"dev": true,
-					"requires": {
-						"@eslint-community/eslint-utils": "^4.4.0",
-						"natural-compare": "^1.4.0",
-						"nth-check": "^2.1.1",
-						"postcss-selector-parser": "^6.0.13",
-						"semver": "^7.5.4",
-						"vue-eslint-parser": "^9.4.2",
-						"xml-name-validator": "^4.0.0"
-					}
-				},
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				},
-				"vue-eslint-parser": {
-					"version": "9.4.2",
-					"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
-					"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
-					"dev": true,
-					"requires": {
-						"debug": "^4.3.4",
-						"eslint-scope": "^7.1.1",
-						"eslint-visitor-keys": "^3.3.0",
-						"espree": "^9.3.1",
-						"esquery": "^1.4.0",
-						"lodash": "^4.17.21",
-						"semver": "^7.3.6"
-					}
-				}
+				"eslint-plugin-unicorn": "^51.0.1",
+				"eslint-plugin-vue": "^9.23.0",
+				"eslint-plugin-wdio": "^8.24.12",
+				"eslint-plugin-yml": "^1.13.2"
 			}
 		},
 		"eslint-plugin-compat": {
@@ -5398,39 +5229,40 @@
 			}
 		},
 		"eslint-plugin-es-x": {
-			"version": "7.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz",
-			"integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz",
+			"integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==",
 			"dev": true,
 			"requires": {
 				"@eslint-community/eslint-utils": "^4.1.2",
 				"@eslint-community/regexpp": "^4.6.0",
-				"eslint-compat-utils": "^0.1.2"
+				"eslint-compat-utils": "^0.5.0"
 			}
 		},
 		"eslint-plugin-jest": {
-			"version": "27.6.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.6.3.tgz",
-			"integrity": "sha512-+YsJFVH6R+tOiO3gCJon5oqn4KWc+mDq2leudk8mrp8RFubLOo9CVyi3cib4L7XMpxExmkmBZQTPDYVBzgpgOA==",
+			"version": "27.9.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz",
+			"integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==",
 			"dev": true,
 			"requires": {
 				"@typescript-eslint/utils": "^5.10.0"
 			}
 		},
 		"eslint-plugin-jsdoc": {
-			"version": "42.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-42.0.0.tgz",
-			"integrity": "sha512-qXYr45G8atPKowZbIOdmABukMzu9IMjAlj6j5Fe0iuUItznWSXUDiBj57ejXcbt8bkPrg83333nuz+cqGKFgcQ==",
+			"version": "48.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz",
+			"integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==",
 			"dev": true,
 			"requires": {
-				"@es-joy/jsdoccomment": "~0.37.0",
+				"@es-joy/jsdoccomment": "~0.42.0",
 				"are-docs-informative": "^0.0.2",
-				"comment-parser": "1.3.1",
+				"comment-parser": "1.4.1",
 				"debug": "^4.3.4",
 				"escape-string-regexp": "^4.0.0",
 				"esquery": "^1.5.0",
-				"semver": "^7.3.8",
-				"spdx-expression-parse": "^3.0.1"
+				"is-builtin-module": "^3.2.1",
+				"semver": "^7.6.0",
+				"spdx-expression-parse": "^4.0.0"
 			},
 			"dependencies": {
 				"escape-string-regexp": {
@@ -5449,33 +5281,26 @@
 			"requires": {
 				"eslint-visitor-keys": "^3.3.0",
 				"espree": "^9.3.1"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.3.0",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-					"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-					"dev": true
-				}
 			}
 		},
 		"eslint-plugin-mediawiki": {
-			"version": "0.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.5.0.tgz",
-			"integrity": "sha512-rjkHFyv3VDan/dmu7YpD1Rl9h64NOlz4mqqesRN316R+571+ymmb6lXVOdNMbT8H1iPhmtHc+nijVLVkn7pYDw==",
+			"version": "0.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.6.0.tgz",
+			"integrity": "sha512-a2Zm18N5nPyflBajM2ZWATxucIpYPEmOSjFzUR1OBH3hAL0GY9fx1mpezEwzqAQ862d+kPkolgQOzktnZe8nKA==",
 			"dev": true,
 			"requires": {
-				"eslint-plugin-vue": "^8.7.1",
+				"eslint-plugin-vue": "^9.23.0",
 				"upath": "^2.0.1"
 			}
 		},
 		"eslint-plugin-mocha": {
-			"version": "10.2.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.2.0.tgz",
-			"integrity": "sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ==",
+			"version": "10.4.2",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.2.tgz",
+			"integrity": "sha512-cur4dVYnSEWTBwdqIBQFxa/9siAhesu0TX+lbJ4ClE9j0eNMNe6BSx3vkFFNz6tGoveyMyELFXa30f3fvuAVDg==",
 			"dev": true,
 			"requires": {
 				"eslint-utils": "^3.0.0",
+				"globals": "^13.24.0",
 				"rambda": "^7.4.0"
 			}
 		},
@@ -5517,9 +5342,9 @@
 			"requires": {}
 		},
 		"eslint-plugin-qunit": {
-			"version": "7.3.4",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.3.4.tgz",
-			"integrity": "sha512-EbDM0zJerH9zVdUswMJpcFF7wrrpvsGuYfNexUpa5hZkkdFhaFcX+yD+RSK4Nrauw4psMGlcqeWUMhaVo+Manw==",
+			"version": "8.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-8.1.1.tgz",
+			"integrity": "sha512-j3xhiAf2Wvr8Dfwl5T6tlJ+F55vqYE9ZdAHUOTzq1lGerYrXzOS46RvK4SSWug2D8sl3ZYr2lA4/hgVXgLloxw==",
 			"dev": true,
 			"requires": {
 				"eslint-utils": "^3.0.0",
@@ -5536,71 +5361,62 @@
 			}
 		},
 		"eslint-plugin-unicorn": {
-			"version": "47.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-47.0.0.tgz",
-			"integrity": "sha512-ivB3bKk7fDIeWOUmmMm9o3Ax9zbMz1Bsza/R2qm46ufw4T6VBFBaJIR1uN3pCKSmSXm8/9Nri8V+iUut1NhQGA==",
+			"version": "51.0.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz",
+			"integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==",
 			"dev": true,
 			"requires": {
-				"@babel/helper-validator-identifier": "^7.19.1",
+				"@babel/helper-validator-identifier": "^7.22.20",
 				"@eslint-community/eslint-utils": "^4.4.0",
-				"ci-info": "^3.8.0",
+				"@eslint/eslintrc": "^2.1.4",
+				"ci-info": "^4.0.0",
 				"clean-regexp": "^1.0.0",
+				"core-js-compat": "^3.34.0",
 				"esquery": "^1.5.0",
 				"indent-string": "^4.0.0",
 				"is-builtin-module": "^3.2.1",
 				"jsesc": "^3.0.2",
-				"lodash": "^4.17.21",
 				"pluralize": "^8.0.0",
 				"read-pkg-up": "^7.0.1",
-				"regexp-tree": "^0.1.24",
+				"regexp-tree": "^0.1.27",
 				"regjsparser": "^0.10.0",
-				"safe-regex": "^2.1.1",
-				"semver": "^7.3.8",
+				"semver": "^7.5.4",
 				"strip-indent": "^3.0.0"
 			}
 		},
 		"eslint-plugin-vue": {
-			"version": "8.7.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz",
-			"integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==",
+			"version": "9.25.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz",
+			"integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==",
 			"dev": true,
 			"requires": {
-				"eslint-utils": "^3.0.0",
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"globals": "^13.24.0",
 				"natural-compare": "^1.4.0",
-				"nth-check": "^2.0.1",
-				"postcss-selector-parser": "^6.0.9",
-				"semver": "^7.3.5",
-				"vue-eslint-parser": "^8.0.1"
+				"nth-check": "^2.1.1",
+				"postcss-selector-parser": "^6.0.15",
+				"semver": "^7.6.0",
+				"vue-eslint-parser": "^9.4.2",
+				"xml-name-validator": "^4.0.0"
 			}
 		},
 		"eslint-plugin-wdio": {
-			"version": "7.25.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.25.3.tgz",
-			"integrity": "sha512-2zbYwV14Md9FNlyhaIILVGPB6w4bu2eJdOTywDUs2Qy4ebcQNwrxB0qCaf7Rm4O+T0Ir+tdYHYBBfbDocSLKng==",
+			"version": "8.24.12",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-8.24.12.tgz",
+			"integrity": "sha512-OmzGteXFOQnJDdkTNnTfksaVa18WlFCyeLjZXHvDpkbomLWAg9wc296Pr0wnTCagqNj8qfEHpy+N2XVew5VCMA==",
 			"dev": true
 		},
 		"eslint-plugin-yml": {
-			"version": "1.12.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.12.2.tgz",
-			"integrity": "sha512-hvS9p08FhPT7i/ynwl7/Wt7ke7Rf4P2D6fT8lZlL43peZDTsHtH2A0SIFQ7Kt7+mJ6if6P+FX3iJhMkdnxQwpg==",
+			"version": "1.14.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz",
+			"integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==",
 			"dev": true,
 			"requires": {
 				"debug": "^4.3.2",
-				"eslint-compat-utils": "^0.4.0",
+				"eslint-compat-utils": "^0.5.0",
 				"lodash": "^4.17.21",
 				"natural-compare": "^1.4.0",
 				"yaml-eslint-parser": "^1.2.1"
-			},
-			"dependencies": {
-				"eslint-compat-utils": {
-					"version": "0.4.1",
-					"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.4.1.tgz",
-					"integrity": "sha512-5N7ZaJG5pZxUeNNJfUchurLVrunD1xJvyg5kYOIVF8kg1f3ajTikmAu/5fZ9w100omNPOoMjngRszh/Q/uFGMg==",
-					"dev": true,
-					"requires": {
-						"semver": "^7.5.4"
-					}
-				}
 			}
 		},
 		"eslint-scope": {
@@ -5620,12 +5436,20 @@
 			"dev": true,
 			"requires": {
 				"eslint-visitor-keys": "^2.0.0"
+			},
+			"dependencies": {
+				"eslint-visitor-keys": {
+					"version": "2.1.0",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+					"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+					"dev": true
+				}
 			}
 		},
 		"eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+			"version": "3.4.3",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
 			"dev": true
 		},
 		"espree": {
@@ -5637,14 +5461,6 @@
 				"acorn": "^8.9.0",
 				"acorn-jsx": "^5.3.2",
 				"eslint-visitor-keys": "^3.4.1"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				}
 			}
 		},
 		"esprima": {
@@ -6521,9 +6337,9 @@
 			}
 		},
 		"node-releases": {
-			"version": "2.0.13",
-			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
-			"integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+			"version": "2.0.14",
+			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+			"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
 			"dev": true
 		},
 		"normalize-package-data": {
@@ -6730,9 +6546,9 @@
 			"dev": true
 		},
 		"postcss-selector-parser": {
-			"version": "6.0.15",
-			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
-			"integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
+			"version": "6.0.16",
+			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
+			"integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
 			"dev": true,
 			"requires": {
 				"cssesc": "^3.0.0",
@@ -6855,9 +6671,9 @@
 			}
 		},
 		"regexp-tree": {
-			"version": "0.1.24",
-			"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz",
-			"integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==",
+			"version": "0.1.27",
+			"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
+			"integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==",
 			"dev": true
 		},
 		"regjsparser": {
@@ -6961,9 +6777,9 @@
 			}
 		},
 		"semver": {
-			"version": "7.5.4",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-			"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+			"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
 			"dev": true,
 			"requires": {
 				"lru-cache": "^6.0.0"
@@ -7004,18 +6820,30 @@
 			"requires": {
 				"spdx-expression-parse": "^3.0.0",
 				"spdx-license-ids": "^3.0.0"
+			},
+			"dependencies": {
+				"spdx-expression-parse": {
+					"version": "3.0.1",
+					"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+					"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+					"dev": true,
+					"requires": {
+						"spdx-exceptions": "^2.1.0",
+						"spdx-license-ids": "^3.0.0"
+					}
+				}
 			}
 		},
 		"spdx-exceptions": {
-			"version": "2.4.0",
-			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz",
-			"integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==",
+			"version": "2.5.0",
+			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+			"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
 			"dev": true
 		},
 		"spdx-expression-parse": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
-			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+			"integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
 			"dev": true,
 			"requires": {
 				"spdx-exceptions": "^2.1.0",
@@ -7179,9 +7007,9 @@
 			"dev": true
 		},
 		"typescript": {
-			"version": "5.3.3",
-			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
-			"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+			"version": "5.4.5",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+			"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
 			"dev": true,
 			"peer": true
 		},
@@ -7204,9 +7032,9 @@
 			"dev": true
 		},
 		"update-browserslist-db": {
-			"version": "1.0.11",
-			"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
-			"integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+			"version": "1.0.13",
+			"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+			"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
 			"dev": true,
 			"requires": {
 				"escalade": "^3.1.1",
@@ -7236,29 +7064,33 @@
 			"requires": {
 				"spdx-correct": "^3.0.0",
 				"spdx-expression-parse": "^3.0.0"
+			},
+			"dependencies": {
+				"spdx-expression-parse": {
+					"version": "3.0.1",
+					"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+					"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+					"dev": true,
+					"requires": {
+						"spdx-exceptions": "^2.1.0",
+						"spdx-license-ids": "^3.0.0"
+					}
+				}
 			}
 		},
 		"vue-eslint-parser": {
-			"version": "8.3.0",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
-			"integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==",
+			"version": "9.4.2",
+			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+			"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
 			"dev": true,
 			"requires": {
-				"debug": "^4.3.2",
-				"eslint-scope": "^7.0.0",
-				"eslint-visitor-keys": "^3.1.0",
-				"espree": "^9.0.0",
+				"debug": "^4.3.4",
+				"eslint-scope": "^7.1.1",
+				"eslint-visitor-keys": "^3.3.0",
+				"espree": "^9.3.1",
 				"esquery": "^1.4.0",
 				"lodash": "^4.17.21",
-				"semver": "^7.3.5"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.4.0",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
-					"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
-					"dev": true
-				}
+				"semver": "^7.3.6"
 			}
 		},
 		"which": {
@@ -7371,9 +7203,9 @@
 			"dev": true
 		},
 		"yaml": {
-			"version": "2.3.4",
-			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
-			"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
+			"version": "2.4.1",
+			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
+			"integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
 			"dev": true
 		},
 		"yaml-eslint-parser": {
@@ -7385,14 +7217,6 @@
 				"eslint-visitor-keys": "^3.0.0",
 				"lodash": "^4.17.21",
 				"yaml": "^2.0.0"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				}
 			}
 		},
 		"yargs": {
diff --git a/package.json b/package.json
index 9c17e48..b5f34d6 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
 		"babybird": "^0.0.1",
 		"chai": "^4.2.0",
 		"domino": "^2.1.0",
-		"eslint-config-wikimedia": "0.26.0",
+		"eslint-config-wikimedia": "0.27.0",
 		"jsdoc": "4.0.2",
 		"jsdoc-wmf-theme": "0.0.12",
 		"mocha": "^7.1.2",
diff --git a/tools/build-langconv-fst.js b/tools/build-langconv-fst.js
index a5abb9d..36835c7 100755
--- a/tools/build-langconv-fst.js
+++ b/tools/build-langconv-fst.js
@@ -8,6 +8,7 @@
  * The input is expected to be a "byte machine", that is, unicode code units
  * have already been decomposed into code points corresponding to UTF-8
  * bytes.  Symbols used in the ATT file:
+ *
  *  @0@      Epsilon ("no character").  Used in both input and output edges;
  *           as an input edge this introduced nondeterminism.
  *  <hh>    The input byte with hexadecimal value <hh>
-- 
2.39.2

$ date
--- stdout ---
Thu Apr 18 11:45:33 UTC 2024

--- end ---
$ git clone file:///srv/git/mediawiki-libs-LangConv.git repo --depth=1 -b master
--- stderr ---
Cloning into 'repo'...
Updating files:  72% (127/175)
Updating files:  73% (128/175)
Updating files:  74% (130/175)
Updating files:  75% (132/175)
Updating files:  76% (133/175)
Updating files:  77% (135/175)
Updating files:  78% (137/175)
Updating files:  79% (139/175)
Updating files:  80% (140/175)
Updating files:  81% (142/175)
Updating files:  82% (144/175)
Updating files:  83% (146/175)
Updating files:  84% (147/175)
Updating files:  85% (149/175)
Updating files:  86% (151/175)
Updating files:  87% (153/175)
Updating files:  88% (154/175)
Updating files:  89% (156/175)
Updating files:  90% (158/175)
Updating files:  91% (160/175)
Updating files:  92% (161/175)
Updating files:  93% (163/175)
Updating files:  94% (165/175)
Updating files:  95% (167/175)
Updating files:  96% (168/175)
Updating files:  97% (170/175)
Updating files:  98% (172/175)
Updating files:  99% (174/175)
Updating files: 100% (175/175)
Updating files: 100% (175/175), done.
--- stdout ---

--- end ---
$ git config user.name libraryupgrader
--- stdout ---

--- end ---
$ git config user.email tools.libraryupgrader@tools.wmflabs.org
--- stdout ---

--- end ---
$ git submodule update --init
--- stdout ---

--- end ---
$ grr init
--- stdout ---
Installed commit-msg hook.

--- end ---
$ git show-ref refs/heads/master
--- stdout ---
37634e4a1d9e3029bc2f19b6a7a4216bca2499fe refs/heads/master

--- end ---
$ /usr/bin/npm audit --json
--- stdout ---
{
  "auditReportVersion": 2,
  "vulnerabilities": {
    "debug": {
      "name": "debug",
      "severity": "low",
      "isDirect": false,
      "via": [
        {
          "source": 1096793,
          "name": "debug",
          "dependency": "debug",
          "title": "Regular Expression Denial of Service in debug",
          "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c",
          "severity": "low",
          "cwe": [
            "CWE-400"
          ],
          "cvss": {
            "score": 3.7,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": ">=3.2.0 <3.2.7"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "3.2.0 - 3.2.6",
      "nodes": [
        "node_modules/mocha/node_modules/debug"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "flat": {
      "name": "flat",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1089152,
          "name": "flat",
          "dependency": "flat",
          "title": "flat vulnerable to Prototype Pollution",
          "url": "https://github.com/advisories/GHSA-2j2x-2gpw-g8fm",
          "severity": "critical",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": "<5.0.1"
        }
      ],
      "effects": [
        "yargs-unparser"
      ],
      "range": "<5.0.1",
      "nodes": [
        "node_modules/flat"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "jsdoc-wmf-theme": {
      "name": "jsdoc-wmf-theme",
      "severity": "high",
      "isDirect": true,
      "via": [
        "taffydb"
      ],
      "effects": [],
      "range": "<=0.0.12",
      "nodes": [
        "node_modules/jsdoc-wmf-theme"
      ],
      "fixAvailable": {
        "name": "jsdoc-wmf-theme",
        "version": "1.0.0",
        "isSemVerMajor": true
      }
    },
    "minimatch": {
      "name": "minimatch",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096485,
          "name": "minimatch",
          "dependency": "minimatch",
          "title": "minimatch ReDoS vulnerability",
          "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3",
          "severity": "high",
          "cwe": [
            "CWE-400",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": "<3.0.5"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "<3.0.5",
      "nodes": [
        "node_modules/minimatch"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "mocha": {
      "name": "mocha",
      "severity": "critical",
      "isDirect": true,
      "via": [
        "debug",
        "minimatch",
        "yargs-unparser"
      ],
      "effects": [],
      "range": "5.1.0 - 9.2.1",
      "nodes": [
        "node_modules/mocha"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "taffydb": {
      "name": "taffydb",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1089386,
          "name": "taffydb",
          "dependency": "taffydb",
          "title": "TaffyDB can allow access to any data items in the DB",
          "url": "https://github.com/advisories/GHSA-mxhp-79qh-mcx6",
          "severity": "high",
          "cwe": [
            "CWE-20",
            "CWE-668"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
          },
          "range": "<=2.7.3"
        }
      ],
      "effects": [
        "jsdoc-wmf-theme"
      ],
      "range": "*",
      "nodes": [
        "node_modules/taffydb"
      ],
      "fixAvailable": {
        "name": "jsdoc-wmf-theme",
        "version": "1.0.0",
        "isSemVerMajor": true
      }
    },
    "yargs-unparser": {
      "name": "yargs-unparser",
      "severity": "critical",
      "isDirect": false,
      "via": [
        "flat"
      ],
      "effects": [
        "mocha"
      ],
      "range": "<=1.6.3",
      "nodes": [
        "node_modules/yargs-unparser"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    }
  },
  "metadata": {
    "vulnerabilities": {
      "info": 0,
      "low": 1,
      "moderate": 0,
      "high": 3,
      "critical": 3,
      "total": 7
    },
    "dependencies": {
      "prod": 1,
      "dev": 371,
      "optional": 2,
      "peer": 1,
      "peerOptional": 0,
      "total": 371
    }
  }
}

--- end ---
$ /usr/bin/composer install
--- stderr ---
No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
Loading composer repositories with package information
Updating dependencies
Lock file operations: 70 installs, 0 updates, 0 removals
  - Locking composer/pcre (3.1.3)
  - Locking composer/semver (3.4.0)
  - Locking composer/spdx-licenses (1.5.8)
  - Locking composer/xdebug-handler (3.0.4)
  - Locking dealerdirect/phpcodesniffer-composer-installer (v1.0.0)
  - Locking doctrine/deprecations (1.1.3)
  - Locking doctrine/instantiator (2.0.0)
  - Locking felixfbecker/advanced-json-rpc (v3.2.1)
  - Locking mediawiki/mediawiki-codesniffer (v43.0.0)
  - Locking mediawiki/mediawiki-phan-config (0.14.0)
  - Locking mediawiki/minus-x (1.1.1)
  - Locking mediawiki/phan-taint-check-plugin (6.0.0)
  - Locking microsoft/tolerant-php-parser (v0.1.2)
  - Locking myclabs/deep-copy (1.11.1)
  - Locking netresearch/jsonmapper (v4.4.1)
  - Locking nikic/php-parser (v5.0.2)
  - Locking ockcyp/covers-validator (v1.6.0)
  - Locking phan/phan (5.4.3)
  - Locking phar-io/manifest (2.0.4)
  - Locking phar-io/version (3.2.1)
  - Locking php-parallel-lint/php-console-color (v1.0.1)
  - Locking php-parallel-lint/php-console-highlighter (v1.0.0)
  - Locking php-parallel-lint/php-parallel-lint (v1.3.2)
  - Locking phpcsstandards/phpcsextra (1.1.2)
  - Locking phpcsstandards/phpcsutils (1.0.9)
  - Locking phpdocumentor/reflection-common (2.2.0)
  - Locking phpdocumentor/reflection-docblock (5.4.0)
  - Locking phpdocumentor/type-resolver (1.8.2)
  - Locking phpstan/phpdoc-parser (1.28.0)
  - Locking phpunit/php-code-coverage (9.2.31)
  - Locking phpunit/php-file-iterator (3.0.6)
  - Locking phpunit/php-invoker (3.1.1)
  - Locking phpunit/php-text-template (2.0.4)
  - Locking phpunit/php-timer (5.0.3)
  - Locking phpunit/phpunit (9.6.16)
  - Locking psr/container (2.0.2)
  - Locking psr/log (2.0.0)
  - Locking sabre/event (5.1.4)
  - Locking sebastian/cli-parser (1.0.2)
  - Locking sebastian/code-unit (1.0.8)
  - Locking sebastian/code-unit-reverse-lookup (2.0.3)
  - Locking sebastian/comparator (4.0.8)
  - Locking sebastian/complexity (2.0.3)
  - Locking sebastian/diff (4.0.6)
  - Locking sebastian/environment (5.1.5)
  - Locking sebastian/exporter (4.0.6)
  - Locking sebastian/global-state (5.0.7)
  - Locking sebastian/lines-of-code (1.0.4)
  - Locking sebastian/object-enumerator (4.0.4)
  - Locking sebastian/object-reflector (2.0.4)
  - Locking sebastian/recursion-context (4.0.5)
  - Locking sebastian/resource-operations (3.0.4)
  - Locking sebastian/type (3.2.1)
  - Locking sebastian/version (3.0.2)
  - Locking squizlabs/php_codesniffer (3.8.1)
  - Locking symfony/console (v5.4.36)
  - Locking symfony/deprecation-contracts (v3.4.0)
  - Locking symfony/polyfill-ctype (v1.29.0)
  - Locking symfony/polyfill-intl-grapheme (v1.29.0)
  - Locking symfony/polyfill-intl-normalizer (v1.29.0)
  - Locking symfony/polyfill-mbstring (v1.29.0)
  - Locking symfony/polyfill-php73 (v1.29.0)
  - Locking symfony/polyfill-php80 (v1.29.0)
  - Locking symfony/service-contracts (v3.4.2)
  - Locking symfony/string (v6.4.4)
  - Locking theseer/tokenizer (1.2.3)
  - Locking tysonandre/var_representation_polyfill (0.1.3)
  - Locking webmozart/assert (1.11.0)
  - Locking wikimedia/assert (v0.5.1)
  - Locking wikimedia/update-history (1.0.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 70 installs, 0 updates, 0 removals
    0 [>---------------------------]    0 [->--------------------------]
  - Installing squizlabs/php_codesniffer (3.8.1): Extracting archive
  - Installing dealerdirect/phpcodesniffer-composer-installer (v1.0.0): Extracting archive
  - Installing composer/pcre (3.1.3): Extracting archive
  - Installing symfony/polyfill-php80 (v1.29.0): Extracting archive
  - Installing phpcsstandards/phpcsutils (1.0.9): Extracting archive
  - Installing phpcsstandards/phpcsextra (1.1.2): Extracting archive
  - Installing symfony/polyfill-mbstring (v1.29.0): Extracting archive
  - Installing composer/spdx-licenses (1.5.8): Extracting archive
  - Installing composer/semver (3.4.0): Extracting archive
  - Installing mediawiki/mediawiki-codesniffer (v43.0.0): Extracting archive
  - Installing tysonandre/var_representation_polyfill (0.1.3): Extracting archive
  - Installing symfony/polyfill-intl-normalizer (v1.29.0): Extracting archive
  - Installing symfony/polyfill-intl-grapheme (v1.29.0): Extracting archive
  - Installing symfony/polyfill-ctype (v1.29.0): Extracting archive
  - Installing symfony/string (v6.4.4): Extracting archive
  - Installing psr/container (2.0.2): Extracting archive
  - Installing symfony/service-contracts (v3.4.2): Extracting archive
  - Installing symfony/polyfill-php73 (v1.29.0): Extracting archive
  - Installing symfony/deprecation-contracts (v3.4.0): Extracting archive
  - Installing symfony/console (v5.4.36): Extracting archive
  - Installing sabre/event (5.1.4): Extracting archive
  - Installing netresearch/jsonmapper (v4.4.1): Extracting archive
  - Installing microsoft/tolerant-php-parser (v0.1.2): Extracting archive
  - Installing webmozart/assert (1.11.0): Extracting archive
  - Installing phpstan/phpdoc-parser (1.28.0): Extracting archive
  - Installing phpdocumentor/reflection-common (2.2.0): Extracting archive
  - Installing doctrine/deprecations (1.1.3): Extracting archive
  - Installing phpdocumentor/type-resolver (1.8.2): Extracting archive
  - Installing phpdocumentor/reflection-docblock (5.4.0): Extracting archive
  - Installing felixfbecker/advanced-json-rpc (v3.2.1): Extracting archive
  - Installing psr/log (2.0.0): Extracting archive
  - Installing composer/xdebug-handler (3.0.4): Extracting archive
  - Installing phan/phan (5.4.3): Extracting archive
  - Installing mediawiki/phan-taint-check-plugin (6.0.0): Extracting archive
  - Installing mediawiki/mediawiki-phan-config (0.14.0): Extracting archive
  - Installing mediawiki/minus-x (1.1.1): Extracting archive
  - Installing sebastian/version (3.0.2): Extracting archive
  - Installing sebastian/type (3.2.1): Extracting archive
  - Installing sebastian/resource-operations (3.0.4): Extracting archive
  - Installing sebastian/recursion-context (4.0.5): Extracting archive
  - Installing sebastian/object-reflector (2.0.4): Extracting archive
  - Installing sebastian/object-enumerator (4.0.4): Extracting archive
  - Installing sebastian/global-state (5.0.7): Extracting archive
  - Installing sebastian/exporter (4.0.6): Extracting archive
  - Installing sebastian/environment (5.1.5): Extracting archive
  - Installing sebastian/diff (4.0.6): Extracting archive
  - Installing sebastian/comparator (4.0.8): Extracting archive
  - Installing sebastian/code-unit (1.0.8): Extracting archive
  - Installing sebastian/cli-parser (1.0.2): Extracting archive
  - Installing phpunit/php-timer (5.0.3): Extracting archive
  - Installing phpunit/php-text-template (2.0.4): Extracting archive
  - Installing phpunit/php-invoker (3.1.1): Extracting archive
  - Installing phpunit/php-file-iterator (3.0.6): Extracting archive
  - Installing theseer/tokenizer (1.2.3): Extracting archive
  - Installing nikic/php-parser (v5.0.2): Extracting archive
  - Installing sebastian/lines-of-code (1.0.4): Extracting archive
  - Installing sebastian/complexity (2.0.3): Extracting archive
  - Installing sebastian/code-unit-reverse-lookup (2.0.3): Extracting archive
  - Installing phpunit/php-code-coverage (9.2.31): Extracting archive
  - Installing phar-io/version (3.2.1): Extracting archive
  - Installing phar-io/manifest (2.0.4): Extracting archive
  - Installing myclabs/deep-copy (1.11.1): Extracting archive
  - Installing doctrine/instantiator (2.0.0): Extracting archive
  - Installing phpunit/phpunit (9.6.16): Extracting archive
  - Installing ockcyp/covers-validator (v1.6.0): Extracting archive
  - Installing php-parallel-lint/php-console-color (v1.0.1): Extracting archive
  - Installing php-parallel-lint/php-console-highlighter (v1.0.0): Extracting archive
  - Installing php-parallel-lint/php-parallel-lint (v1.3.2): Extracting archive
  - Installing wikimedia/assert (v0.5.1): Extracting archive
  - Installing wikimedia/update-history (1.0.1): Extracting archive
  0/68 [>---------------------------]   0%
 21/68 [========>-------------------]  30%
 34/68 [==============>-------------]  50%
 48/68 [===================>--------]  70%
 59/68 [========================>---]  86%
 68/68 [============================] 100%
7 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating optimized autoload files
42 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
--- stdout ---
PHP CodeSniffer Config installed_paths set to ../../mediawiki/mediawiki-codesniffer,../../phpcsstandards/phpcsextra,../../phpcsstandards/phpcsutils

--- end ---
Upgrading n:eslint-config-wikimedia from 0.26.0 -> 0.27.0
$ /usr/bin/npm install
--- stdout ---

added 362 packages, and audited 363 packages in 7s

53 packages are looking for funding
  run `npm fund` for details

7 vulnerabilities (1 low, 3 high, 3 critical)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

--- end ---
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json

--- end ---
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json

--- end ---
$ ./node_modules/.bin/eslint . --fix
--- stdout ---

/src/repo/lib/FST.js
  48:1  warning  The type 'Utf8Array' is undefined          jsdoc/no-undefined-types
  52:1  warning  The type 'BracketMachine' is undefined     jsdoc/no-undefined-types
  52:1  warning  The type 'ConversionMachine' is undefined  jsdoc/no-undefined-types

/src/repo/lib/ReplacementMachine.js
   17:1  warning  Missing JSDoc @param "baseLanguage" type  jsdoc/require-param-type
   36:2  warning  Missing JSDoc @return declaration         jsdoc/require-returns
   37:1  warning  Missing JSDoc @param "filename" type      jsdoc/require-param-type
   38:1  warning  Missing JSDoc @param "bracket" type       jsdoc/require-param-type
   59:2  warning  Found more than one @return declaration   jsdoc/require-returns
   59:2  warning  Found more than one @return declaration   jsdoc/require-returns-check
   70:1  warning  Missing JSDoc @param "s" type             jsdoc/require-param-type
   71:1  warning  Missing JSDoc @param "destCode" type      jsdoc/require-param-type
   72:1  warning  Missing JSDoc @param "invertCode" type    jsdoc/require-param-type
  104:1  warning  The type 'Node' is undefined              jsdoc/no-undefined-types
  107:1  warning  The type 'Node' is undefined              jsdoc/no-undefined-types
  136:1  warning  The type 'Document' is undefined          jsdoc/no-undefined-types
  144:1  warning  The type 'DocumentFragment' is undefined  jsdoc/no-undefined-types

/src/repo/tools/build-langconv-fst.js
   1:1  warning  ES2023 Hashbang comments are forbidden       es-x/no-hashbang
  12:1  warning  Invalid JSDoc tag name "0@"                  jsdoc/check-tag-names
  16:1  warning  Invalid JSDoc tag name "_IDENTITY_SYMBOL_@"  jsdoc/check-tag-names

✖ 19 problems (0 errors, 19 warnings)


--- end ---
$ ./node_modules/.bin/eslint . -f json
--- stdout ---
[{"filePath":"/src/repo/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]}]},{"filePath":"/src/repo/composer.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]}]},{"filePath":"/src/repo/lib/FST.js","messages":[{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Utf8Array' is undefined.","line":48,"column":1,"nodeType":"Block","endLine":48,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'BracketMachine' is undefined.","line":52,"column":1,"nodeType":"Block","endLine":52,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'ConversionMachine' is undefined.","line":52,"column":1,"nodeType":"Block","endLine":52,"endColumn":1}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Load and execute a finite-state transducer (FST) based converter or\n * bracketing machine from a compact JSON description.\n *\n * @module\n */\n\n'use strict';\n\nconst { StringDecoder } = require('string_decoder');\n\nconst MAGIC_BYTES   = 8; // 8 byte header w/ magic bytes\n\n// These pseudo-characters appear in the \"output\" side of the FST only.\nconst BYTE_IDENTITY = 0xFF;\nconst BYTE_RBRACKET = 0xFE;\nconst BYTE_LBRACKET = 0xFD;\nconst BYTE_FAIL     = 0xFC;\n// These pseudo-characters appear in the \"input\" side of the FST.\nconst BYTE_EOF      = 0xF8; // The highest possible input char\nconst BYTE_EPSILON  = 0x00; // Always appears first in sorted order\n\n/**\n * A FST conversion machine.\n *\n * @callback module:language/FST~ConversionMachine\n * @param {Buffer} buffer UTF-8 encoded input buffer.\n * @param {number} [start] Start position in the buffer, default 0.\n * @param {number} [end] End position in the buffer, defaults to\n *   `buffer.length`.\n * @return {string} The converted string.\n */\n\n/**\n * A FST bracket machine.\n *\n * @callback module:language/FST~BracketMachine\n * @param {Buffer} buffer UTF-8 encoded input buffer.\n * @param {number} [start] Start position in the buffer, default 0.\n * @param {number} [end] End position in the buffer, defaults to\n *   `buffer.length`.\n * @return {number[]} An array of bracket locations in the input buffer.\n */\n\n/**\n * Load an FST description and return a function which runs the machine.\n *\n * @param {Buffer|Utf8Array|string} file The FST description, either as a\n *  filename (to be loaded synchronously) or a loaded byte array.\n * @param {boolean} [justBrackets] The machine will return an array of\n *  bracket locations in the input buffer, instead of a converted buffer.\n * @return {BracketMachine|ConversionMachine}\n */\nfunction compile(file, justBrackets) {\n\tif (typeof file === 'string') {\n\t\tfile = require('fs').readFileSync(file);\n\t}\n\t// Verify the magic number\n\tif (\n\t\tfile.length < (MAGIC_BYTES + 2/* states, min*/) ||\n\t\t\tfile.slice(0,8).toString('utf8') !== 'pFST\\0WM\\0'\n\t) {\n\t\tthrow new Error(\"Invalid pFST file.\");\n\t}\n\tif (justBrackets === 'split') {\n\t\t// Debugging helper: instead of an array of positions, split the\n\t\t// input at the bracket locations and return an array of strings.\n\t\tconst bfunc = compile(file, true);\n\t\treturn (buf,start,end) => {\n\t\t\tend = end === undefined ? buf.length : end;\n\t\t\tconst r = bfunc(buf,start,end);\n\t\t\tr.push(end);\n\t\t\tlet i = 0;\n\t\t\treturn r.map((j) => {\n\t\t\t\tconst b = buf.slice(i,j);\n\t\t\t\ti = j;\n\t\t\t\treturn b.toString('utf8');\n\t\t\t});\n\t\t};\n\t}\n\treturn (buf, start, end, unicode) => {\n\t\tstart = start === undefined ? 0 : start;\n\t\tend = end === undefined ? buf.length : end;\n\t\tconsole.assert(start >= 0 && end <= buf.length, \"Bad start/end\");\n\t\tconst countCodePoints = justBrackets && unicode;\n\t\tconst STATE_INITIAL = MAGIC_BYTES + 2/* eof state*/;\n\t\tlet state = STATE_INITIAL;\n\t\tlet idx = start;\n\t\tlet outpos = 0;\n\t\tconst brackets = [0];\n\t\tconst stack = [];\n\t\tlet chunk = { buf: justBrackets ? null : Buffer.alloc(256), next: null };\n\t\tlet firstChunk = chunk;\n\n\t\t// Read zig-zag encoded variable length integers\n\t\t// (See [en:Variable-length_quantity#Zigzag_encoding])\n\t\tconst readUnsignedV = () => {\n\t\t\tlet b = file[state++];\n\t\t\t/* eslint-disable no-bitwise */\n\t\t\tlet val = b & 127;\n\t\t\twhile (b & 128) {\n\t\t\t\tval += 1;\n\t\t\t\tb = file[state++];\n\t\t\t\tval = (val << 7) + (b & 127);\n\t\t\t}\n\t\t\t/* eslint-enable no-bitwise */\n\t\t\treturn val;\n\t\t};\n\t\tconst readSignedV = () => {\n\t\t\tconst v = readUnsignedV();\n\t\t\t/* eslint-disable no-bitwise */\n\t\t\tif (v & 1) { // sign bit is in LSB\n\t\t\t\treturn -(v >>> 1) - 1;\n\t\t\t} else {\n\t\t\t\treturn (v >>> 1);\n\t\t\t}\n\t\t\t/* eslint-enable no-bitwise */\n\t\t};\n\n\t\t// Add a character to the output.\n\t\tconst emit = justBrackets ? (code) => {\n\t\t\tif (code === BYTE_LBRACKET || code === BYTE_RBRACKET) {\n\t\t\t\tbrackets.push(outpos);\n\t\t\t} else if (countCodePoints && code >= 0x80 && code < 0xC0) {\n\t\t\t\t/* Ignore UTF-8 continuation characters */\n\t\t\t} else {\n\t\t\t\toutpos++;\n\t\t\t}\n\t\t} : (code) => {\n\t\t\t// console.assert(code !== 0 && code < 0xF8, code);\n\t\t\tif (outpos >= chunk.buf.length) {\n\t\t\t\t// Make another chunk, bigger than the last one.\n\t\t\t\tchunk.next = {\n\t\t\t\t\tbuf: Buffer.alloc(chunk.buf.length * 2),\n\t\t\t\t\tnext: null\n\t\t\t\t};\n\t\t\t\tchunk = chunk.next;\n\t\t\t\toutpos = 0;\n\t\t\t}\n\t\t\tchunk.buf[outpos++] = code;\n\t\t};\n\t\t// Save the current machine state before taking a non-deterministic\n\t\t// edge; if the machine fails, restart at the given `state`\n\t\tconst save = (epsEdge) => {\n\t\t\tstack.push({\n\t\t\t\tepsEdge,\n\t\t\t\toutpos,\n\t\t\t\tidx,\n\t\t\t\tchunk,\n\t\t\t\tblen: brackets.length,\n\t\t\t});\n\t\t};\n\t\t// When the machine has failed, restart at the saved state.\n\t\tconst reset = () => {\n\t\t\tconst s = stack.pop();\n\t\t\toutpos = s.outpos;\n\t\t\tchunk = s.chunk;\n\t\t\tchunk.next = null;\n\t\t\tidx = s.idx;\n\t\t\tbrackets.length = s.blen;\n\t\t\t// Get outByte from this edge, then jump to next state\n\t\t\tstate = s.epsEdge + 1/* skip over inByte */;\n\t\t\tconst edgeOut = file[state++];\n\t\t\tif (edgeOut !== BYTE_EPSILON) {\n\t\t\t\temit(edgeOut);\n\t\t\t}\n\t\t\tlet edgeDest = state;\n\t\t\tedgeDest += readSignedV();\n\t\t\tstate = edgeDest;\n\t\t};\n\n\t\t// This runs the machine until we reach the EOF state\n\t\t/* eslint-disable no-labels, no-extra-label */\n\t\tNEXTSTATE:\n\t\twhile (state >= STATE_INITIAL) {\n\t\t\tif (state === STATE_INITIAL) {\n\t\t\t\t// Memory efficiency: since the machine is universal\n\t\t\t\t// we know we'll never fail as long as we're in the\n\t\t\t\t// initial state.\n\t\t\t\tstack.length = 0;\n\t\t\t}\n\t\t\tconst edgeWidth = readUnsignedV();\n\t\t\tlet nEdges = readUnsignedV();\n\t\t\tif (nEdges === 0) {\n\t\t\t\treset();\n\t\t\t\tcontinue NEXTSTATE;\n\t\t\t}\n\t\t\t// Read first edge to see if there are any epsilon edges\n\t\t\tlet edge0 = state;\n\t\t\twhile (file[edge0] === BYTE_EPSILON) {\n\t\t\t\t// If this is an epsilon edge, then save a backtrack state\n\t\t\t\tsave(edge0);\n\t\t\t\tedge0 += edgeWidth;\n\t\t\t\tnEdges--;\n\t\t\t\tif (nEdges === 0) {\n\t\t\t\t\treset();\n\t\t\t\t\tcontinue NEXTSTATE;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Binary search for an edge matching c\n\t\t\tconst c = (idx < end) ? buf[idx++] : /* pseudo-character: */ BYTE_EOF;\n\t\t\tlet minIndex = 0;\n\t\t\tlet maxIndex = nEdges;\n\t\t\twhile (minIndex !== maxIndex) {\n\t\t\t\t/* eslint-disable no-bitwise */\n\t\t\t\tconst currentIndex = (minIndex + maxIndex) >>> 1;\n\t\t\t\tconst targetEdge = edge0 + (edgeWidth * currentIndex);\n\t\t\t\tconst inByte = file[targetEdge];\n\t\t\t\tif (inByte <= c) {\n\t\t\t\t\tminIndex = currentIndex + 1;\n\t\t\t\t} else {\n\t\t\t\t\tmaxIndex = currentIndex;\n\t\t\t\t}\n\t\t\t\t/* eslint-enable no-bitwise */\n\t\t\t}\n\t\t\t// (minIndex-1).inByte <= c, and maxIndex.inByte > c\n\t\t\tconst targetEdge = edge0 + (edgeWidth * (minIndex - 1));\n\t\t\tlet outByte = (minIndex > 0) ? file[targetEdge + 1] : BYTE_FAIL;\n\t\t\tif (outByte === BYTE_FAIL) {\n\t\t\t\treset();\n\t\t\t\tcontinue NEXTSTATE;\n\t\t\t}\n\t\t\tif (outByte !== BYTE_EPSILON) {\n\t\t\t\tif (outByte === BYTE_IDENTITY) {\n\t\t\t\t\toutByte = c; // Copy input byte to output\n\t\t\t\t}\n\t\t\t\temit(outByte);\n\t\t\t}\n\t\t\tstate = targetEdge + 2; // skip over inByte/outByte\n\t\t\tstate = readSignedV() + (targetEdge + 2);\n\t\t}\n\t\t/* eslint-enable no-labels, no-extra-label */\n\n\t\t// Ok, process the final state and return something.\n\t\tif (justBrackets) {\n\t\t\tbrackets.push(outpos);\n\t\t\treturn brackets;\n\t\t}\n\t\t// Convert the chunked UTF-8 output back into a JavaScript string.\n\t\tchunk.buf = chunk.buf.slice(0, outpos);\n\t\tchunk = null; // free memory as we go along\n\t\tvar decoder = new StringDecoder('utf8');\n\t\tvar result = '';\n\t\tfor (; firstChunk; firstChunk = firstChunk.next) {\n\t\t\tresult += decoder.write(firstChunk.buf);\n\t\t}\n\t\tresult += decoder.end();\n\t\treturn result;\n\t};\n}\n\nmodule.exports = {\n\tconstants: {\n\t\tBYTE_IDENTITY,\n\t\tBYTE_RBRACKET,\n\t\tBYTE_LBRACKET,\n\t\tBYTE_FAIL,\n\t\tBYTE_EOF,\n\t\tBYTE_EPSILON,\n\t},\n\tcompile,\n};\n","usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/lib/ReplacementMachine.js","messages":[{"ruleId":"jsdoc/require-param-type","severity":1,"message":"Missing JSDoc @param \"baseLanguage\" type.","line":17,"column":1,"nodeType":"Block","endLine":17,"endColumn":1},{"ruleId":"jsdoc/require-returns","severity":1,"message":"Missing JSDoc @return declaration.","line":36,"column":2,"nodeType":"Block","endLine":40,"endColumn":5},{"ruleId":"jsdoc/require-param-type","severity":1,"message":"Missing JSDoc @param \"filename\" type.","line":37,"column":1,"nodeType":"Block","endLine":37,"endColumn":1},{"ruleId":"jsdoc/require-param-type","severity":1,"message":"Missing JSDoc @param \"bracket\" type.","line":38,"column":1,"nodeType":"Block","endLine":38,"endColumn":1},{"ruleId":"jsdoc/require-returns","severity":1,"message":"Found more than one @return declaration.","line":59,"column":2,"nodeType":"Block","endLine":78,"endColumn":5},{"ruleId":"jsdoc/require-returns-check","severity":1,"message":"Found more than one @return declaration.","line":59,"column":2,"nodeType":"Block","endLine":78,"endColumn":5},{"ruleId":"jsdoc/require-param-type","severity":1,"message":"Missing JSDoc @param \"s\" type.","line":70,"column":1,"nodeType":"Block","endLine":70,"endColumn":1},{"ruleId":"jsdoc/require-param-type","severity":1,"message":"Missing JSDoc @param \"destCode\" type.","line":71,"column":1,"nodeType":"Block","endLine":71,"endColumn":1},{"ruleId":"jsdoc/require-param-type","severity":1,"message":"Missing JSDoc @param \"invertCode\" type.","line":72,"column":1,"nodeType":"Block","endLine":72,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Node' is undefined.","line":104,"column":1,"nodeType":"Block","endLine":104,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Node' is undefined.","line":107,"column":1,"nodeType":"Block","endLine":107,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'Document' is undefined.","line":136,"column":1,"nodeType":"Block","endLine":136,"endColumn":1},{"ruleId":"jsdoc/no-undefined-types","severity":1,"message":"The type 'DocumentFragment' is undefined.","line":144,"column":1,"nodeType":"Block","endLine":144,"endColumn":1}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":13,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This is a wrapper around functionality similar to PHP's `ReplacementArray`,\n * but built on (reversible) Finite-State Transducers.\n *\n * @module\n */\n\n'use strict';\n\nconst FST = require('./FST.js');\n\nclass ReplacementMachine {\n\t/**\n\t * Create a new ReplacementArray, which holds a given source->destination\n\t * transformation.\n\t *\n\t * @param baseLanguage\n\t * @param {...any} codes\n\t */\n\tconstructor(baseLanguage, ...codes) {\n\t\tthis.baseLanguage = baseLanguage;\n\t\tthis.codes = codes.slice(0);\n\t\tthis.machine = new Map(codes.map((c) => [c, {\n\t\t\tconvert: ReplacementMachine.loadFST(`trans-${ c }`),\n\t\t\tbracket: new Map(\n\t\t\t\tcodes.filter((cc) => this.validCodePair(c, cc)).map((cc) => [\n\t\t\t\t\tcc,\n\t\t\t\t\tReplacementMachine.loadFST(\n\t\t\t\t\t\t`brack-${ c }-${ c === cc ? 'noop' : cc }`,\n\t\t\t\t\t\t'bracket'\n\t\t\t\t\t)\n\t\t\t\t])),\n\t\t}]));\n\t}\n\n\t/**\n\t * @param filename\n\t * @param bracket\n\t * @private\n\t */\n\tstatic loadFST(filename, bracket) {\n\t\treturn FST.compile(`${ __dirname }/../fst/${ filename }.pfst`, bracket);\n\t}\n\n\t/**\n\t * Override this method in subclass if you want to limit the\n\t * possible code pairs bracketed.  (For example, zh has a large\n\t * number of variants, but we typically want to use only a limited\n\t * number of these as possible invert codes.)\n\t *\n\t * @param {string} destCode\n\t * @param {string} invertCode\n\t * @return {boolean} whether this is a valid bracketing pair.\n\t */\n\tvalidCodePair(destCode, invertCode) {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Quantify a guess about the \"native\" language of string `s`.\n\t * We will be converting *to* `destCode`, and our guess is that\n\t * when we round trip we'll want to convert back to `invertCode`\n\t * (so `invertCode` is our guess about the actual language of `s`).\n\t * If we were to make this encoding, the returned value `unsafe` is\n\t * the number of codepoints we'd have to specially-escape, `safe` is\n\t * the number of codepoints we wouldn't have to escape, and `len` is\n\t * the total number of codepoints in `s`.  Generally lower values of\n\t * `nonsafe` indicate a better guess for `invertCode`.\n\t *\n\t * @param s\n\t * @param destCode\n\t * @param invertCode\n\t * @return {Object} Statistics about the given guess.\n\t * @return {number} return.safe\n\t * @return {number} return.unsafe\n\t * @return {number} return.length (Should be `safe+unsafe`.)\n\t * @private\n\t */\n\tcountBrackets(s, destCode, invertCode) {\n\t\tconsole.assert(\n\t\t\tthis.validCodePair(destCode, invertCode),\n\t\t\t`Invalid code pair: ${ destCode }/${ invertCode }`\n\t\t);\n\t\tconst m = this.machine.get(destCode).bracket.get(invertCode);\n\t\tconst buf = Buffer.from(s, 'utf8');\n\t\tconst brackets = m(buf, 0, buf.length, 'unicode'/* codepoints*/);\n\t\tlet safe = 0;\n\t\tlet unsafe = 0;\n\t\tfor (let i = 1; i < brackets.length; i++) {\n\t\t\tsafe += (brackets[i] - brackets[i - 1]);\n\t\t\tif (++i < brackets.length) {\n\t\t\t\tunsafe += (brackets[i] - brackets[i - 1]);\n\t\t\t}\n\t\t}\n\t\t// Note that this is counting codepoints, not UTF-8 code units.\n\t\treturn { safe, unsafe, length: brackets[brackets.length - 1] };\n\t}\n\n\t/**\n\t * Replace the given text Node with converted text, protecting any\n\t * markup which can't be round-tripped back to `invertCode` with\n\t * appropriate synthetic language-converter markup.\n\t *\n\t * @param {Node} textNode\n\t * @param {string} destCode\n\t * @param {string} invertCode\n\t * @return {Node|null} the next sibling of textNode (for traversal)\n\t */\n\treplace(textNode, destCode, invertCode) {\n\t\tconst fragment = this.convert(\n\t\t\ttextNode.ownerDocument, textNode.textContent, destCode, invertCode\n\t\t);\n\t\t// Was a change made?\n\t\tconst next = textNode.nextSibling;\n\t\tif (\n\t\t\t// `fragment` has exactly 1 child.\n\t\t\tfragment.firstChild && !fragment.firstChild.nextSibling &&\n\t\t\t// `fragment.firstChild` is a DOM text node\n\t\t\tfragment.firstChild.nodeType === 3 &&\n\t\t\t// `textNode` is a DOM text node\n\t\t\ttextNode.nodeType === 3 &&\n\t\t\ttextNode.textContent === fragment.textContent\n\t\t) {\n\t\t\treturn next; // No change.\n\t\t}\n\t\ttextNode.replaceWith(fragment);\n\t\treturn next;\n\t}\n\n\t/**\n\t * Convert the given string, protecting any\n\t * markup which can't be round-tripped back to `invertCode` with\n\t * appropriate synthetic language-converter markup.  Returns\n\t * a DocumentFragment.\n\t *\n\t * @param {Document} document\n\t *   Owner of the resulting DocumentFragment.\n\t * @param {string} s\n\t *   Text to convert.\n\t * @param {string} destCode\n\t *   Target language code for the conversion.\n\t * @param {string} invertCode\n\t *   Language code which will be used to round-trip the result.\n\t * @return {DocumentFragment}\n\t */\n\tconvert(document, s, destCode, invertCode) {\n\t\tconst machine = this.machine.get(destCode);\n\t\tconst convertM = machine.convert;\n\t\tconst bracketM = machine.bracket.get(invertCode);\n\t\tconst result = document.createDocumentFragment();\n\t\tconst buf = Buffer.from(s, 'utf8');\n\t\tconst brackets = bracketM(buf);\n\t\tfor (let i = 1; i < brackets.length; i++) {\n\t\t\t// A safe string\n\t\t\tconst safe = convertM(buf, brackets[i - 1], brackets[i]);\n\t\t\tif (safe.length > 0) {\n\t\t\t\tresult.appendChild(document.createTextNode(safe));\n\t\t\t}\n\t\t\tif (++i < brackets.length) {\n\t\t\t\t// An unsafe string\n\t\t\t\tconst orig = buf.toString('utf8', brackets[i - 1], brackets[i]);\n\t\t\t\tconst unsafe = convertM(buf, brackets[i - 1], brackets[i]);\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tspan.textContent = unsafe;\n\t\t\t\tspan.setAttribute('typeof', 'mw:LanguageVariant');\n\t\t\t\t// If this is an anomalous piece of text in a paragraph\n\t\t\t\t// otherwise written in destCode, then it's possible\n\t\t\t\t// invertCode === destCode.  In this case try to pick a\n\t\t\t\t// more appropriate invertCode !== destCode.\n\t\t\t\tlet ic = invertCode;\n\t\t\t\tif (ic === destCode) {\n\t\t\t\t\tconst cs = this.codes.filter((c) => c !== destCode).map((code) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcode,\n\t\t\t\t\t\t\tstats: this.countBrackets(orig, code, code)\n\t\t\t\t\t\t};\n\t\t\t\t\t}).sort((a,b) => a.stats.unsafe - b.stats.unsafe);\n\t\t\t\t\tif (cs.length === 0) {\n\t\t\t\t\t\tic = '-';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tic = cs[0].code;\n\t\t\t\t\t\tspan.setAttribute('data-mw-variant-lang', ic);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tspan.setAttribute('data-mw-variant', JSON.stringify({\n\t\t\t\t\ttwoway: [\n\t\t\t\t\t\t{ l: ic, t: orig },\n\t\t\t\t\t\t{ l: destCode, t: unsafe },\n\t\t\t\t\t],\n\t\t\t\t\trt: true, /* Synthetic markup used for round-tripping */\n\t\t\t\t}));\n\t\t\t\tif (unsafe.length > 0) {\n\t\t\t\t\tresult.appendChild(span);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Merge Text nodes, just in case we had zero-length brackets.\n\t\tresult.normalize();\n\t\treturn result;\n\t}\n}\n\nmodule.exports.ReplacementMachine = ReplacementMachine;\n","usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/lib/ZhReplacementMachine.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/lib/index.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/package-lock.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]}]},{"filePath":"/src/repo/package.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]}]},{"filePath":"/src/repo/tests/mocha/foma.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/tests/mocha/language/crh.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/tests/mocha/language/en.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/tests/mocha/language/ku.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/tests/mocha/language/sr.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/tests/mocha/language/zh.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]},{"filePath":"/src/repo/tools/build-langconv-fst.js","messages":[{"ruleId":"es-x/no-hashbang","severity":1,"message":"ES2023 Hashbang comments are forbidden.","line":1,"column":1,"nodeType":"Shebang","messageId":"forbidden","endLine":1,"endColumn":20},{"ruleId":"jsdoc/check-tag-names","severity":1,"message":"Invalid JSDoc tag name \"0@\".","line":12,"column":1,"nodeType":"Block","endLine":12,"endColumn":1},{"ruleId":"jsdoc/check-tag-names","severity":1,"message":"Invalid JSDoc tag name \"_IDENTITY_SYMBOL_@\".","line":16,"column":1,"nodeType":"Block","endLine":16,"endColumn":1}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"#!/usr/bin/env node\n\n'use strict';\n\n/**\n * Compile an .att-format finite state transducer (as output by foma)\n * into a compact byte-array representation which is directly executable.\n * The input is expected to be a \"byte machine\", that is, unicode code units\n * have already been decomposed into code points corresponding to UTF-8\n * bytes.  Symbols used in the ATT file:\n *\n *  @0@      Epsilon (\"no character\").  Used in both input and output edges;\n *           as an input edge this introduced nondeterminism.\n *  <hh>    The input byte with hexadecimal value <hh>\n *             (\"00\" should never appear in the ATT file; see below.)\n *  @_IDENTITY_SYMBOL_@   Any character not named in the (implicit) alphabet\n *  [[       Bracket characters, used to delimit \"unsafe\" strings in\n *  ]]       \"bracket machines'.\n *\n * The output is a byte array.  We use a variable-length integer encoding:\n *   0xxx xxxy -> the directly-encoded value (xxx xxxx)\n *   1xxx xxxx -> (xxx xxxx) + 128 * ( 1 + <the value encoded by subsequent bytes>)\n * For signed quantities, the least significant digit is used for a sign\n * bit.  That is, to encode first:\n *   from_signed(x) = (x >= 0) ? (2*x) : (-2*(x + 1) + 1);\n * and when decoding:\n *   to_signed(x) = (x & 1) ? (((x-1)/-2)-1) : (x/2);\n * See [en:Variable-length_quantity#Zigzag_encoding] for details.\n *\n * Byte value 0x00 is used for \"epsilon\" edges.  Null characters are\n *  disallowed in wikitext, and foma would have trouble handling them\n *  natively since it is written in C with null-terminated strings.\n *  As an input character this represents a non-deterministic transition;\n *  as an output character it represents \"no output\".\n *  If you wanted (for some reason) to allow null characters in the\n *  input (which are not included in the \"anything else\" case), then\n *  encode them as 0xC0 0x80 (aka \"Modified UTF-8\").  [Similarly, if\n *  you wanted to emit a null character, you could emit 0xC0 0x80.]\n *\n * Byte values 0xF8 - 0xFF are disallowed in UTF-8.  We use them for\n * special cases, as follows:\n *  0xFF: EOF (the end of the input string).  Final states in the machine\n *   are represented with an inchar=0xFF outchar=0x00 transition to a\n *   unique \"stop state\" (aka state #0).  Non-final states have no outgoing\n *   edge for input 0xFF.\n *  0xFE: IDENTITY.  As an output character it copies the input character.\n *  0xFD: ]]\n *  0xFC: [[  These bracketing characters should only appear as output\n *   characters; they will never appear in the input.\n *\n * The byte array begins with eight \"magic bytes\" to help identify the\n * file format.\n *\n * Following this, we have an array of states.  State #0 is the unique\n * \"final state\"; state #1 is the unique start state.  Each state is:\n *   <# of bytes in each edge: variable unsigned int>\n *   <# edges: variable unsigned int>\n *   <edge #0>\n *   <edge #1>\n *   etc\n * Each edge is:\n *   <in byte: 1 byte>\n *   <out byte: 1 byte>\n *   <target state: variable signed int>\n *   <padding, if necessary to reach proper # of bytes in each edge>\n *\n * Edges are sorted by <in byte> to allow binary search. All target\n * states are relative, refer to the start position of that state in\n * the byte array, and are padded to the same size within each state.\n * If the first edge(s) have <in byte> = 0x00 then these edges\n * represent possible epsilon transitions from this state (aka, these\n * edge should be tried if subsequent execution from this state\n * fails).\n */\n\nconst fs = require('fs');\nconst path = require('path');\nconst yargs = require('yargs');\nconst { StringDecoder } = require('string_decoder');\n\nconst FST = require('../lib/FST.js');\n\nconst BYTE_IDENTITY = FST.constants.BYTE_IDENTITY;\nconst BYTE_RBRACKET = FST.constants.BYTE_RBRACKET;\nconst BYTE_LBRACKET = FST.constants.BYTE_LBRACKET;\nconst BYTE_FAIL     = FST.constants.BYTE_FAIL;\nconst BYTE_EOF      = FST.constants.BYTE_EOF;\nconst BYTE_EPSILON  = FST.constants.BYTE_EPSILON;\n\nclass DefaultMap extends Map {\n\tconstructor(makeDefaultValue) {\n\t\tsuper();\n\t\tthis.makeDefaultValue = makeDefaultValue;\n\t}\n\n\tgetDefault(key) {\n\t\tif (!this.has(key)) {\n\t\t\tthis.set(key, this.makeDefaultValue());\n\t\t}\n\t\treturn this.get(key);\n\t}\n}\n\n// Splits input on `\\r\\n?|\\n` without holding entire file in memory at once.\nfunction *readLines(inFile) {\n\tconst fd = fs.openSync(inFile, 'r');\n\ttry {\n\t\tconst buf = Buffer.alloc(1024);\n\t\tconst decoder = new StringDecoder('utf8');\n\t\tlet line = '';\n\t\tlet sawCR = false;\n\t\twhile (true) {\n\t\t\tconst bytesRead = fs.readSync(fd, buf, 0, buf.length);\n\t\t\tif (bytesRead === 0) { break; }\n\t\t\tlet lineStart = 0;\n\t\t\tfor (let i = 0; i < bytesRead; i++) {\n\t\t\t\tif (buf[i] === 13 || buf[i] === 10) {\n\t\t\t\t\tline += decoder.write(buf.slice(lineStart, i));\n\t\t\t\t\tif (!(buf[i] === 10 && sawCR)) {\n\t\t\t\t\t\t// skip over the zero-length \"lines\" caused by \\r\\n\n\t\t\t\t\t\tyield line;\n\t\t\t\t\t}\n\t\t\t\t\tline = '';\n\t\t\t\t\tlineStart = i + 1;\n\t\t\t\t\tsawCR = (buf[i] === 13);\n\t\t\t\t} else {\n\t\t\t\t\tsawCR = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tline += decoder.write(buf.slice(lineStart, bytesRead));\n\t\t}\n\t\tline += decoder.end();\n\t\tyield line;\n\t} finally {\n\t\tfs.closeSync(fd);\n\t}\n}\n\nfunction readAttFile(inFile, handleState, handleFinal) {\n\tlet lastState = 0;\n\tlet edges = [];\n\tconst finalStates = [];\n\tfor (const line of readLines(inFile)) {\n\t\tif (line.length === 0) { continue; }\n\t\tconst fields = line.split(/\\t/g);\n\t\tconst state = +fields[0];\n\t\tif (fields.length === 1 || state !== lastState) {\n\t\t\tif (lastState >= 0) {\n\t\t\t\thandleState(lastState, edges);\n\t\t\t\tedges = [];\n\t\t\t\tlastState = -1;\n\t\t\t}\n\t\t}\n\t\tif (fields.length === 1) {\n\t\t\tfinalStates.push(state);\n\t\t} else {\n\t\t\tconsole.assert(fields.length === 4);\n\t\t\tconst to = +fields[1];\n\t\t\tconst inChar = fields[2];\n\t\t\tconst outChar = fields[3];\n\t\t\tedges.push({ to, inChar, outChar });\n\t\t\tlastState = state;\n\t\t}\n\t}\n\tif (lastState >= 0) {\n\t\thandleState(lastState, edges);\n\t}\n\tif (handleFinal) {\n\t\thandleFinal(finalStates);\n\t}\n}\n\nclass DynamicBuffer {\n\tconstructor(chunkLength) {\n\t\tthis.chunkLength = chunkLength || 16384;\n\t\tthis.currBuff = Buffer.alloc(this.chunkLength);\n\t\tthis.buffNum = 0;\n\t\tthis.offset = 0;\n\t\tthis.buffers = [ this.currBuff ];\n\t\tthis.lastLength = 0;\n\t}\n\n\temit(b) {\n\t\tconsole.assert(b !== undefined);\n\t\tif (this.offset >= this.currBuff.length) {\n\t\t\tthis.buffNum++; this.offset = 0;\n\t\t\tthis._maybeCreateBuffers();\n\t\t\tthis.currBuff = this.buffers[this.buffNum];\n\t\t}\n\t\tthis.currBuff[this.offset++] = b;\n\t\tthis._maybeUpdateLength();\n\t}\n\n\temitUnsignedV(val, pad) {\n\t\tconst o = [];\n\t\t/* eslint-disable no-bitwise */\n\t\to.push(val & 127);\n\t\tfor (val >>>= 7; val; val >>>= 7) {\n\t\t\to.push(128 | (--val & 127));\n\t\t}\n\t\t/* eslint-enable no-bitwise */\n\t\tfor (let j = o.length - 1; j >= 0; j--) {\n\t\t\tthis.emit(o[j]);\n\t\t}\n\t\tif (pad !== undefined) {\n\t\t\tfor (let j = o.length; j < pad; j++) {\n\t\t\t\tthis.emit(0 /* padding */);\n\t\t\t}\n\t\t}\n\t}\n\n\temitSignedV(val, pad) {\n\t\tif (val >= 0) {\n\t\t\tval *= 2;\n\t\t} else {\n\t\t\tval = (-val) * 2 - 1;\n\t\t}\n\t\tthis.emitUnsignedV(val, pad);\n\t}\n\n\tposition() {\n\t\treturn this.offset + this.buffNum * this.chunkLength;\n\t}\n\n\tlength() {\n\t\treturn this.lastLength + (this.buffers.length - 1) * this.chunkLength;\n\t}\n\n\ttruncate() {\n\t\tthis.lastLength = this.offset;\n\t\tthis.buffers.length = this.buffNum + 1;\n\t}\n\n\t_maybeCreateBuffers() {\n\t\twhile (this.buffNum >= this.buffers.length) {\n\t\t\tthis.buffers.push(Buffer.alloc(this.chunkLength));\n\t\t\tthis.lastLength = 0;\n\t\t}\n\t}\n\n\t_maybeUpdateLength() {\n\t\tif (\n\t\t\tthis.offset > this.lastLength &&\n\t\t\tthis.buffNum === this.buffers.length - 1\n\t\t) {\n\t\t\tthis.lastLength = this.offset;\n\t\t}\n\t}\n\n\tseek(pos) {\n\t\tconsole.assert(pos !== undefined);\n\t\tthis.buffNum = Math.floor(pos / this.chunkLength);\n\t\tthis.offset = pos - (this.buffNum * this.chunkLength);\n\t\tthis._maybeCreateBuffers();\n\t\tthis.currBuff = this.buffers[this.buffNum];\n\t\tthis._maybeUpdateLength();\n\t}\n\n\tread() {\n\t\tif (this.offset >= this.currBuff.length) {\n\t\t\tthis.buffNum++; this.offset = 0;\n\t\t\tthis._maybeCreateBuffers();\n\t\t\tthis.currBuff = this.buffers[this.buffNum];\n\t\t}\n\t\tconst b = this.currBuff[this.offset++];\n\t\tthis._maybeUpdateLength();\n\t\treturn b;\n\t}\n\n\treadUnsignedV() {\n\t\tlet b = this.read();\n\t\t/* eslint-disable no-bitwise */\n\t\tlet val = b & 127;\n\t\twhile (b & 128) {\n\t\t\tval += 1;\n\t\t\tb = this.read();\n\t\t\tval = (val << 7) + (b & 127);\n\t\t}\n\t\t/* eslint-enable no-bitwise */\n\t\treturn val;\n\t}\n\n\treadSignedV() {\n\t\tconst v = this.readUnsignedV();\n\t\t/* eslint-disable no-bitwise */\n\t\tif (v & 1) {\n\t\t\treturn -(v >>> 1) - 1;\n\t\t} else {\n\t\t\treturn (v >>> 1);\n\t\t}\n\t\t/* eslint-enable no-bitwise */\n\t}\n\n\twriteFile(outFile) {\n\t\tconst fd = fs.openSync(outFile, 'w');\n\t\ttry {\n\t\t\tlet i;\n\t\t\tfor (i = 0; i < this.buffers.length - 1; i++) {\n\t\t\t\tfs.writeSync(fd, this.buffers[i]);\n\t\t\t}\n\t\t\tfs.writeSync(fd, this.buffers[i], 0, this.lastLength);\n\t\t} finally {\n\t\t\tfs.closeSync(fd);\n\t\t}\n\t}\n}\n\nfunction processOne(inFile, outFile, verbose, justBrackets, maxEdgeBytes) {\n\tif (justBrackets === undefined) {\n\t\tjustBrackets = /\\bbrack-/.test(inFile);\n\t}\n\tif (maxEdgeBytes === undefined) {\n\t\tmaxEdgeBytes = 10;\n\t}\n\n\tlet finalStates;\n\tconst alphabet = new Set();\n\tconst sym2byte = function(sym) {\n\t\tif (sym === '@_IDENTITY_SYMBOL_@') { return BYTE_IDENTITY; }\n\t\tif (sym === '@0@') { return BYTE_EPSILON; }\n\t\tif (sym === '[[') { return BYTE_LBRACKET; }\n\t\tif (sym === ']]') { return BYTE_RBRACKET; }\n\t\tif (/^[0-9A-F][0-9A-F]$/i.test(sym)) {\n\t\t\tconst b = Number.parseInt(sym, 16);\n\t\t\tconsole.assert(b !== 0 && b < 0xF8);\n\t\t\treturn b;\n\t\t}\n\t\tconsole.assert(false, `Bad symbol: ${ sym }`);\n\t};\n\t// Quickly read through once in order to pull out the set of final states\n\t// and the alphabet\n\treadAttFile(inFile, (state, edges) => {\n\t\tfor (const e of edges) {\n\t\t\talphabet.add(sym2byte(e.inChar));\n\t\t\talphabet.add(sym2byte(e.outChar));\n\t\t}\n\t}, (fs) => {\n\t\tfinalStates = new Set(fs);\n\t});\n\t// Anything not in `alphabet` is going to be treated as 'anything else'\n\t// but we want to force 0x00 and 0xF8-0xFF to be treated as 'anything else'\n\talphabet.delete(0);\n\tfor (let i = 0xF8; i <= 0xFF; i++) { alphabet.delete(i); }\n\t// Emit a magic number.\n\tconst out = new DynamicBuffer();\n\tout.emit(0x70); out.emit(0x46); out.emit(0x53); out.emit(0x54);\n\tout.emit(0x00); out.emit(0x57); out.emit(0x4D); out.emit(0x00);\n\t// Ok, now read through and build the output array\n\tlet synState = -1;\n\tconst stateMap = new Map();\n\t// Reserve the EOF state (0 in output)\n\tstateMap.set(synState--, out.position());\n\tout.emitUnsignedV(0);\n\tout.emitUnsignedV(0);\n\tconst processState = (state, edges) => {\n\t\tconsole.assert(!stateMap.has(state));\n\t\tstateMap.set(state, out.position());\n\t\tout.emitUnsignedV(maxEdgeBytes);\n\t\t// First emit epsilon edges\n\t\tconst r = edges.filter((e) => e.inByte === BYTE_EPSILON);\n\t\t// Then emit a sorted table of inByte transitions, omitting repeated\n\t\t// entries (so it's a range map)\n\t\t// Note that BYTE_EOF is always either FAIL or a transition to a unique\n\t\t// state, so we can always treat values lower than the first entry\n\t\t// or higher than the last entry as FAIL.\n\t\tconst edgeMap = new Map(edges.map((e) => [e.inByte, e]));\n\t\tlet lastEdge = { outByte: BYTE_FAIL, to: state };\n\t\tfor (let i = 1; i <= BYTE_EOF; i++) {\n\t\t\tlet e = (alphabet.has(i) || i === BYTE_EOF) ?\n\t\t\t\tedgeMap.get(i) : edgeMap.get(BYTE_IDENTITY);\n\t\t\tif (!e) { e = { outByte: BYTE_FAIL, to: state }; }\n\t\t\t// where possible remap outByte to IDENTITY to maximize chances\n\t\t\t// of adjacent states matching\n\t\t\tconst out = (i === e.outByte) ? BYTE_IDENTITY : e.outByte;\n\t\t\tif (out !== lastEdge.outByte || e.to !== lastEdge.to) {\n\t\t\t\tlastEdge = { inByte: i, outByte: out, to: e.to };\n\t\t\t\tr.push(lastEdge);\n\t\t\t}\n\t\t}\n\t\tout.emitUnsignedV(r.length);\n\t\tr.forEach((e) => {\n\t\t\tout.emit(e.inByte);\n\t\t\tout.emit(e.outByte);\n\t\t\tout.emitSignedV(e.to, maxEdgeBytes - 2 /* for inByte/outByte */);\n\t\t});\n\t};\n\treadAttFile(inFile, (state, edges) => {\n\t\t// Map characters to bytes\n\t\tedges = edges.map((e) => {\n\t\t\treturn {\n\t\t\t\tto: e.to,\n\t\t\t\tinByte: sym2byte(e.inChar),\n\t\t\t\toutByte: sym2byte(e.outChar),\n\t\t\t};\n\t\t});\n\t\t// If this is a final state, add a synthetic EOF edge\n\t\tif (finalStates.has(state)) {\n\t\t\tedges.push({ to: -1, inByte: BYTE_EOF, outByte: BYTE_EPSILON });\n\t\t}\n\t\t// Collect edges and figure out if we need to split the state\n\t\t// (if there are multiple edges with the same non-epsilon inByte).\n\t\tconst edgeMap = new DefaultMap(() => []);\n\t\tfor (const e of edges) {\n\t\t\tedgeMap.getDefault(e.inByte).push(e);\n\t\t}\n\t\t// For each inByte with multiple outgoing edges, replace those\n\t\t// edges with a single edge:\n\t\t//  { to: newState, inChar: e.inByte, outChar: BYTE_EPSILON }\n\t\t// ...and then create a new state with edges:\n\t\t//  [{ to: e[n].to, inChar: BYTE_EPSILON, outChar: e[n].outChar},...]\n\t\tconst extraStates = [];\n\t\tfor (const [inByte, e] of edgeMap.entries()) {\n\t\t\tif (inByte !== BYTE_EPSILON && e.length > 1) {\n\t\t\t\tconst nstate = synState--;\n\t\t\t\textraStates.push({\n\t\t\t\t\tstate: nstate,\n\t\t\t\t\tedges: e.map((ee) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tto: ee.to,\n\t\t\t\t\t\t\tinByte: BYTE_EPSILON,\n\t\t\t\t\t\t\toutByte: ee.outByte,\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\tedgeMap.set(inByte, [{\n\t\t\t\t\tto: nstate,\n\t\t\t\t\tinByte: inByte,\n\t\t\t\t\toutByte: BYTE_EPSILON\n\t\t\t\t}]);\n\t\t\t}\n\t\t}\n\t\tprocessState(state, [].concat.apply([], Array.from(edgeMap.values())));\n\t\textraStates.forEach((extra) => {\n\t\t\tprocessState(extra.state, extra.edges);\n\t\t});\n\t});\n\t// Rarely a state will not be mentioned in the .att file except\n\t// in the list of final states; check this & process at the end.\n\tfinalStates.forEach((state) => {\n\t\tif (!stateMap.has(state)) {\n\t\t\tprocessState(state, [\n\t\t\t\t{ to: -1, inByte: BYTE_EOF, outByte: BYTE_EPSILON }\n\t\t\t]);\n\t\t}\n\t});\n\t// Fixup buffer to include relative offsets to states\n\tconst state0pos = stateMap.get(-1);\n\tout.seek(state0pos);\n\twhile (out.position() < out.length()) {\n\t\tconst edgeWidth = out.readUnsignedV();\n\t\tconst nEdges = out.readUnsignedV();\n\t\tconst edge0 = out.position();\n\t\tfor (let i = 0; i < nEdges; i++) {\n\t\t\tconst p = edge0 + i * edgeWidth + /* inByte/outByte: */ 2;\n\t\t\tout.seek(p);\n\t\t\tconst state = out.readSignedV();\n\t\t\tout.seek(p);\n\t\t\tconsole.assert(stateMap.has(state), `${ state } not found`);\n\t\t\tout.emitSignedV(stateMap.get(state) - p, edgeWidth - 2);\n\t\t}\n\t\tout.seek(edge0 + nEdges * edgeWidth);\n\t}\n\t// Now iteratively narrow the field widths until the file is as small\n\t// as it can be.\n\twhile (true) {\n\t\tlet trimmed = 0;\n\t\tstateMap.clear();\n\t\tconst widthMap = new Map();\n\t\tout.seek(state0pos);\n\t\twhile (out.position() < out.length()) {\n\t\t\tconst statePos = out.position();\n\t\t\tstateMap.set(statePos, statePos - trimmed);\n\t\t\tconst edgeWidth = out.readUnsignedV();\n\t\t\tconst widthPos = out.position();\n\t\t\tconst nEdges = out.readUnsignedV();\n\t\t\tlet maxWidth = 0;\n\t\t\tconst edge0 = out.position();\n\t\t\tfor (let i = 0; i < nEdges; i++) {\n\t\t\t\tconst p = edge0 + i * edgeWidth;\n\t\t\t\tout.seek(p);\n\t\t\t\tout.read(); out.read(); out.readSignedV();\n\t\t\t\tconst thisWidth = out.position() - p;\n\t\t\t\tmaxWidth = Math.max(maxWidth, thisWidth);\n\t\t\t}\n\t\t\twidthMap.set(statePos, maxWidth);\n\t\t\ttrimmed += (edgeWidth - maxWidth) * nEdges;\n\t\t\tif (maxWidth !== edgeWidth) {\n\t\t\t\tout.seek(statePos);\n\t\t\t\tout.emitUnsignedV(maxWidth);\n\t\t\t\ttrimmed += (out.position() - widthPos);\n\t\t\t\tout.seek(statePos);\n\t\t\t\tout.emitUnsignedV(edgeWidth);\n\t\t\t}\n\t\t\tout.seek(edge0 + nEdges * edgeWidth);\n\t\t}\n\t\tstateMap.set(out.position(), out.position() - trimmed);\n\n\t\tif (trimmed === 0) { break; /* nothing left to do */ }\n\t\tif (verbose) { console.log('.'); }\n\n\t\tout.seek(state0pos);\n\t\twhile (out.position() < out.length()) {\n\t\t\tconst statePos = out.position();\n\t\t\tconsole.assert(stateMap.has(statePos) && widthMap.has(statePos));\n\t\t\tconst nWidth = widthMap.get(statePos);\n\n\t\t\tconst oldWidth = out.readUnsignedV();\n\t\t\tconst nEdges = out.readUnsignedV();\n\t\t\tconst edge0 = out.position();\n\n\t\t\tlet nPos = stateMap.get(statePos);\n\t\t\tout.seek(nPos);\n\t\t\tout.emitUnsignedV(nWidth);\n\t\t\tout.emitUnsignedV(nEdges);\n\t\t\tnPos = out.position();\n\n\t\t\tfor (let i = 0; i < nEdges; i++) {\n\t\t\t\tout.seek(edge0 + i * oldWidth);\n\t\t\t\tconst inByte = out.read();\n\t\t\t\tconst outByte = out.read();\n\t\t\t\tlet toPos = out.position();\n\t\t\t\ttoPos += out.readSignedV();\n\t\t\t\tconsole.assert(stateMap.has(toPos), toPos);\n\t\t\t\ttoPos = stateMap.get(toPos);\n\n\t\t\t\tout.seek(nPos);\n\t\t\t\tout.emit(inByte);\n\t\t\t\tout.emit(outByte);\n\t\t\t\ttoPos -= out.position();\n\t\t\t\tout.emitSignedV(toPos, nWidth - 2);\n\t\t\t\tnPos = out.position();\n\t\t\t}\n\t\t\tout.seek(edge0 + nEdges * oldWidth);\n\t\t}\n\t\tout.seek(stateMap.get(out.position()));\n\t\tout.truncate();\n\t}\n\n\t// Done!\n\tout.writeFile(outFile);\n}\n\nfunction main() {\n\tconst yopts = yargs.usage(\n\t\t'Usage: $0 [options] <conversion> <inverse>\\n' +\n\t\t'Converts a finite-state transducer in .att format.', {\n\t\t\t'output': {\n\t\t\t\tdescription: 'Output filename (or base name)',\n\t\t\t\talias: 'o',\n\t\t\t\tnargs: 1,\n\t\t\t\tnormalize: true,\n\t\t\t},\n\t\t\t'file': {\n\t\t\t\tdescription: 'Input .att filename',\n\t\t\t\talias: 'f',\n\t\t\t\tconflicts: 'language',\n\t\t\t\timplies: 'output',\n\t\t\t\tnargs: 1,\n\t\t\t\tnormalize: true,\n\t\t\t},\n\t\t\t'language': {\n\t\t\t\tdescription: 'Converts trans-{conversion}, brack-{conversion}-noop, and brack-{conversion}-{inverse} in default locations',\n\t\t\t\talias: 'l',\n\t\t\t\tconflicts: 'file',\n\t\t\t\tarray: true,\n\t\t\t},\n\t\t\t'brackets': {\n\t\t\t\tdescription: 'Emit a bracket-location machine',\n\t\t\t\talias: 'b',\n\t\t\t\tboolean: true,\n\t\t\t\tdefault: undefined,\n\t\t\t},\n\t\t\t'verbose': {\n\t\t\t\tdescription: 'Show progress',\n\t\t\t\talias: 'v',\n\t\t\t\tboolean: true,\n\t\t\t},\n\t\t}).example('$0 -l sr-ec sr-el');\n\tconst argv = yopts.argv;\n\tif (argv.help) {\n\t\tyopts.showHelp();\n\t\treturn;\n\t}\n\n\tif (argv.file) {\n\t\tprocessOne(argv.file, argv.output, argv.brackets);\n\t} else if (argv.language) {\n\t\tconst convertLang = argv.language[0];\n\t\tconst inverseLangs = argv.language.slice(1);\n\t\tconst baseDir = path.join(__dirname, '..', 'fst');\n\t\tfor (const f of [\n\t\t\t`trans-${ convertLang }`,\n\t\t\t`brack-${ convertLang }-noop`,\n\t\t].concat(inverseLangs.map((inv) => `brack-${ convertLang }-${ inv }`))) {\n\t\t\tif (argv.verbose) {\n\t\t\t\tconsole.log(f);\n\t\t\t}\n\t\t\tprocessOne(\n\t\t\t\tpath.join(baseDir, `${ f }.att`),\n\t\t\t\tpath.join(baseDir, `${ f }.pfst`),\n\t\t\t\targv.verbose\n\t\t\t);\n\t\t}\n\t} else {\n\t\tyopts.showHelp();\n\t}\n}\n\nif (require.main === module) {\n\tmain();\n}\n","usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"no-buffer-constructor","replacedBy":[]},{"ruleId":"arrow-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]}]}]

--- end ---
$ /usr/bin/npm ci
--- stdout ---

added 362 packages, and audited 363 packages in 6s

53 packages are looking for funding
  run `npm fund` for details

7 vulnerabilities (1 low, 3 high, 3 critical)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

--- end ---
$ /usr/bin/npm test
--- stderr ---
(node:479) DeprecationWarning: Configuration via mocha.opts is DEPRECATED and will be removed from a future version of Mocha. Use RC files or package.json instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
--- stdout ---

> wikimedia-langconv@0.4.1+git test
> npm run eslint && npm run mocha


> wikimedia-langconv@0.4.1+git eslint
> eslint lib


/src/repo/lib/FST.js
  48:1  warning  The type 'Utf8Array' is undefined          jsdoc/no-undefined-types
  52:1  warning  The type 'BracketMachine' is undefined     jsdoc/no-undefined-types
  52:1  warning  The type 'ConversionMachine' is undefined  jsdoc/no-undefined-types

/src/repo/lib/ReplacementMachine.js
   17:1  warning  Missing JSDoc @param "baseLanguage" type  jsdoc/require-param-type
   36:2  warning  Missing JSDoc @return declaration         jsdoc/require-returns
   37:1  warning  Missing JSDoc @param "filename" type      jsdoc/require-param-type
   38:1  warning  Missing JSDoc @param "bracket" type       jsdoc/require-param-type
   59:2  warning  Found more than one @return declaration   jsdoc/require-returns
   59:2  warning  Found more than one @return declaration   jsdoc/require-returns-check
   70:1  warning  Missing JSDoc @param "s" type             jsdoc/require-param-type
   71:1  warning  Missing JSDoc @param "destCode" type      jsdoc/require-param-type
   72:1  warning  Missing JSDoc @param "invertCode" type    jsdoc/require-param-type
  104:1  warning  The type 'Node' is undefined              jsdoc/no-undefined-types
  107:1  warning  The type 'Node' is undefined              jsdoc/no-undefined-types
  136:1  warning  The type 'Document' is undefined          jsdoc/no-undefined-types
  144:1  warning  The type 'DocumentFragment' is undefined  jsdoc/no-undefined-types

✖ 16 problems (0 errors, 16 warnings)


> wikimedia-langconv@0.4.1+git mocha
> mocha --opts tests/mocha/mocha.opts tests/mocha



  Foma FST verification
    - LANGCONV_TEST_FOMA is not set, skipping

  Language/CRH tests
    ✓ general words, covering more of the alphabet (1) [crh-cyrl]
    ✓ general words, covering more of the alphabet (2) [crh-cyrl]
    ✓ general words, covering more of the alphabet (3) [crh-cyrl]
    ✓ general words, covering more of the alphabet (4) [crh-cyrl]
    ✓ exception words [crh-cyrl]
    ✓ recent problem words, part 1 [crh-cyrl]
    ✓ recent problem words, part 2 [crh-cyrl]
    ✓ recent problem words, part 3 [crh-cyrl]
    ✓ recent problem words, part 4 [crh-cyrl]
    ✓ recent problem words, part 5 [crh-cyrl]
    ✓ recent problem words, part 6 [crh-cyrl]
    ✓ recent problem words, part 7 [crh-cyrl]
    ✓ regex pattern words [crh-cyrl]
    ✓ multi part words [crh-cyrl]
    ✓ affix patterns [crh-cyrl]
    ✓ Roman numerals and quotes, esp. single-letter Roman numerals at the end of a string [crh-cyrl]
    ✓ Roman numerals vs Initials, part 1 - Roman numeral initials without spaces [crh-cyrl]
    ✓ Roman numerals vs Initials, part 2 - Roman numeral initials with spaces [crh-cyrl]
    ✓ ALL CAPS, made up acronyms [crh-cyrl]
    ✓ Many-to-one mappings: many Cyrillic to one Latin [crh-cyrl]
    ✓ Many-to-one mappings: many Latin to one Cyrillic [crh-cyrl]
    ✓ general words, covering more of the alphabet (1) [crh-latn]
    ✓ general words, covering more of the alphabet (2) [crh-latn]
    ✓ general words, covering more of the alphabet (3) [crh-latn]
    ✓ general words, covering more of the alphabet (4) [crh-latn]
    ✓ exception words [crh-latn]
    ✓ recent problem words, part 1 [crh-latn]
    ✓ recent problem words, part 2 [crh-latn]
    ✓ recent problem words, part 3 [crh-latn]
    ✓ recent problem words, part 4 [crh-latn]
    ✓ recent problem words, part 5 [crh-latn]
    ✓ recent problem words, part 6 [crh-latn]
    ✓ recent problem words, part 7 [crh-latn]
    ✓ regex pattern words [crh-latn]
    ✓ multi part words [crh-latn]
    ✓ affix patterns [crh-latn]
    ✓ Roman numerals and quotes, esp. single-letter Roman numerals at the end of a string [crh-latn]
    ✓ Roman numerals vs Initials, part 1 - Roman numeral initials without spaces [crh-latn]
    ✓ Roman numerals vs Initials, part 2 - Roman numeral initials with spaces [crh-latn]
    ✓ ALL CAPS, made up acronyms [crh-latn]
    ✓ Many-to-one mappings: many Cyrillic to one Latin [crh-latn]
    ✓ Many-to-one mappings: many Latin to one Cyrillic [crh-latn]

  LanguageEn tests
    ✓ Converting to Pig Latin [en]
    ✓ Converting from Pig Latin [en]
    ✓ Converting to Pig Latin [en-x-piglatin]
    ✓ Converting from Pig Latin [en-x-piglatin]

  LanguageKu tests
    ✓ Test (1) [ku-arab]
    ✓ Test (3) [ku-arab]
    ✓ Test (1) [ku-latn]
    ✓ Test (2) [ku-latn]
    ✓ Test (3) [ku-latn]

  LanguageSr tests
    ✓ A simple conversion of Latin to Cyrillic [sr-ec]

  LanguageZh tests
    ✓ Plain hant -> hans [zh-cn]
    ✓ Plain hans -> hant [zh-cn]
    ✓ zh-cn specific [zh-cn]
    ✓ zh-hk specific [zh-cn]
    ✓ zh-tw specific [zh-cn]
    ✓ zh-tw overrides zh-hant [zh-cn]
    ✓ zh-hk overrides zh-hant [zh-cn]
    ✓ Plain hant -> hans [zh-sg]
    ✓ Plain hans -> hant [zh-sg]
    ✓ zh-cn specific [zh-sg]
    ✓ zh-hk specific [zh-sg]
    ✓ zh-tw specific [zh-sg]
    ✓ zh-tw overrides zh-hant [zh-sg]
    ✓ zh-hk overrides zh-hant [zh-sg]
    ✓ Plain hant -> hans [zh-my]
    ✓ Plain hans -> hant [zh-my]
    ✓ zh-cn specific [zh-my]
    ✓ zh-hk specific [zh-my]
    ✓ zh-tw specific [zh-my]
    ✓ zh-tw overrides zh-hant [zh-my]
    ✓ zh-hk overrides zh-hant [zh-my]
    ✓ Plain hant -> hans [zh-hans]
    ✓ Plain hans -> hant [zh-hans]
    ✓ zh-cn specific [zh-hans]
    ✓ zh-hk specific [zh-hans]
    ✓ zh-tw specific [zh-hans]
    ✓ zh-tw overrides zh-hant [zh-hans]
    ✓ zh-hk overrides zh-hant [zh-hans]
    ✓ Plain hant -> hans [zh-tw]
    ✓ Plain hans -> hant [zh-tw]
    ✓ zh-cn specific [zh-tw]
    ✓ zh-hk specific [zh-tw]
    ✓ zh-tw specific [zh-tw]
    ✓ zh-tw overrides zh-hant [zh-tw]
    ✓ zh-hk overrides zh-hant [zh-tw]
    ✓ Plain hant -> hans [zh-hk]
    ✓ Plain hans -> hant [zh-hk]
    ✓ zh-cn specific [zh-hk]
    ✓ zh-hk specific [zh-hk]
    ✓ zh-tw specific [zh-hk]
    ✓ zh-tw overrides zh-hant [zh-hk]
    ✓ zh-hk overrides zh-hant [zh-hk]
    ✓ Plain hant -> hans [zh-mo]
    ✓ Plain hans -> hant [zh-mo]
    ✓ zh-cn specific [zh-mo]
    ✓ zh-hk specific [zh-mo]
    ✓ zh-tw specific [zh-mo]
    ✓ zh-tw overrides zh-hant [zh-mo]
    ✓ zh-hk overrides zh-hant [zh-mo]
    ✓ Plain hant -> hans [zh-hant]
    ✓ Plain hans -> hant [zh-hant]
    ✓ zh-cn specific [zh-hant]
    ✓ zh-hk specific [zh-hant]
    ✓ zh-tw specific [zh-hant]
    ✓ zh-tw overrides zh-hant [zh-hant]
    ✓ zh-hk overrides zh-hant [zh-hant]


  108 passing (60ms)
  1 pending


--- end ---
$ /usr/bin/npm audit --json
--- stdout ---
{
  "auditReportVersion": 2,
  "vulnerabilities": {
    "debug": {
      "name": "debug",
      "severity": "low",
      "isDirect": false,
      "via": [
        {
          "source": 1096793,
          "name": "debug",
          "dependency": "debug",
          "title": "Regular Expression Denial of Service in debug",
          "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c",
          "severity": "low",
          "cwe": [
            "CWE-400"
          ],
          "cvss": {
            "score": 3.7,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": ">=3.2.0 <3.2.7"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "3.2.0 - 3.2.6",
      "nodes": [
        "node_modules/mocha/node_modules/debug"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "flat": {
      "name": "flat",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1089152,
          "name": "flat",
          "dependency": "flat",
          "title": "flat vulnerable to Prototype Pollution",
          "url": "https://github.com/advisories/GHSA-2j2x-2gpw-g8fm",
          "severity": "critical",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": "<5.0.1"
        }
      ],
      "effects": [
        "yargs-unparser"
      ],
      "range": "<5.0.1",
      "nodes": [
        "node_modules/flat"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "jsdoc-wmf-theme": {
      "name": "jsdoc-wmf-theme",
      "severity": "high",
      "isDirect": true,
      "via": [
        "taffydb"
      ],
      "effects": [],
      "range": "<=0.0.12",
      "nodes": [
        "node_modules/jsdoc-wmf-theme"
      ],
      "fixAvailable": {
        "name": "jsdoc-wmf-theme",
        "version": "1.0.0",
        "isSemVerMajor": true
      }
    },
    "minimatch": {
      "name": "minimatch",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096485,
          "name": "minimatch",
          "dependency": "minimatch",
          "title": "minimatch ReDoS vulnerability",
          "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3",
          "severity": "high",
          "cwe": [
            "CWE-400",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": "<3.0.5"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "<3.0.5",
      "nodes": [
        "node_modules/minimatch"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "mocha": {
      "name": "mocha",
      "severity": "critical",
      "isDirect": true,
      "via": [
        "debug",
        "minimatch",
        "yargs-unparser"
      ],
      "effects": [],
      "range": "5.1.0 - 9.2.1",
      "nodes": [
        "node_modules/mocha"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "taffydb": {
      "name": "taffydb",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1089386,
          "name": "taffydb",
          "dependency": "taffydb",
          "title": "TaffyDB can allow access to any data items in the DB",
          "url": "https://github.com/advisories/GHSA-mxhp-79qh-mcx6",
          "severity": "high",
          "cwe": [
            "CWE-20",
            "CWE-668"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
          },
          "range": "<=2.7.3"
        }
      ],
      "effects": [
        "jsdoc-wmf-theme"
      ],
      "range": "*",
      "nodes": [
        "node_modules/taffydb"
      ],
      "fixAvailable": {
        "name": "jsdoc-wmf-theme",
        "version": "1.0.0",
        "isSemVerMajor": true
      }
    },
    "yargs-unparser": {
      "name": "yargs-unparser",
      "severity": "critical",
      "isDirect": false,
      "via": [
        "flat"
      ],
      "effects": [
        "mocha"
      ],
      "range": "<=1.6.3",
      "nodes": [
        "node_modules/yargs-unparser"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    }
  },
  "metadata": {
    "vulnerabilities": {
      "info": 0,
      "low": 1,
      "moderate": 0,
      "high": 3,
      "critical": 3,
      "total": 7
    },
    "dependencies": {
      "prod": 1,
      "dev": 363,
      "optional": 2,
      "peer": 1,
      "peerOptional": 0,
      "total": 363
    }
  }
}

--- end ---
Attempting to npm audit fix
$ /usr/bin/npm audit fix --dry-run --only=dev --json
--- stderr ---
npm WARN invalid config only="dev" set in command line options
npm WARN invalid config Must be one of: null, prod, production
--- stdout ---
{
  "added": 1,
  "removed": 0,
  "changed": 0,
  "audited": 364,
  "funding": 53,
  "audit": {
    "auditReportVersion": 2,
    "vulnerabilities": {
      "debug": {
        "name": "debug",
        "severity": "low",
        "isDirect": false,
        "via": [
          {
            "source": 1096793,
            "name": "debug",
            "dependency": "debug",
            "title": "Regular Expression Denial of Service in debug",
            "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c",
            "severity": "low",
            "cwe": [
              "CWE-400"
            ],
            "cvss": {
              "score": 3.7,
              "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
            },
            "range": ">=3.2.0 <3.2.7"
          }
        ],
        "effects": [
          "mocha"
        ],
        "range": "3.2.0 - 3.2.6",
        "nodes": [
          "node_modules/mocha/node_modules/debug"
        ],
        "fixAvailable": {
          "name": "mocha",
          "version": "10.4.0",
          "isSemVerMajor": true
        }
      },
      "flat": {
        "name": "flat",
        "severity": "critical",
        "isDirect": false,
        "via": [
          {
            "source": 1089152,
            "name": "flat",
            "dependency": "flat",
            "title": "flat vulnerable to Prototype Pollution",
            "url": "https://github.com/advisories/GHSA-2j2x-2gpw-g8fm",
            "severity": "critical",
            "cwe": [
              "CWE-1321"
            ],
            "cvss": {
              "score": 9.8,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
            },
            "range": "<5.0.1"
          }
        ],
        "effects": [
          "yargs-unparser"
        ],
        "range": "<5.0.1",
        "nodes": [
          "node_modules/flat"
        ],
        "fixAvailable": {
          "name": "mocha",
          "version": "10.4.0",
          "isSemVerMajor": true
        }
      },
      "jsdoc-wmf-theme": {
        "name": "jsdoc-wmf-theme",
        "severity": "high",
        "isDirect": true,
        "via": [
          "taffydb"
        ],
        "effects": [],
        "range": "<=0.0.12",
        "nodes": [
          "node_modules/jsdoc-wmf-theme"
        ],
        "fixAvailable": {
          "name": "jsdoc-wmf-theme",
          "version": "1.0.0",
          "isSemVerMajor": true
        }
      },
      "minimatch": {
        "name": "minimatch",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1096485,
            "name": "minimatch",
            "dependency": "minimatch",
            "title": "minimatch ReDoS vulnerability",
            "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3",
            "severity": "high",
            "cwe": [
              "CWE-400",
              "CWE-1333"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
            },
            "range": "<3.0.5"
          }
        ],
        "effects": [
          "mocha"
        ],
        "range": "<3.0.5",
        "nodes": [
          "node_modules/minimatch"
        ],
        "fixAvailable": {
          "name": "mocha",
          "version": "10.4.0",
          "isSemVerMajor": true
        }
      },
      "mocha": {
        "name": "mocha",
        "severity": "critical",
        "isDirect": true,
        "via": [
          "debug",
          "minimatch",
          "yargs-unparser"
        ],
        "effects": [],
        "range": "5.1.0 - 9.2.1",
        "nodes": [
          "node_modules/mocha"
        ],
        "fixAvailable": {
          "name": "mocha",
          "version": "10.4.0",
          "isSemVerMajor": true
        }
      },
      "taffydb": {
        "name": "taffydb",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1089386,
            "name": "taffydb",
            "dependency": "taffydb",
            "title": "TaffyDB can allow access to any data items in the DB",
            "url": "https://github.com/advisories/GHSA-mxhp-79qh-mcx6",
            "severity": "high",
            "cwe": [
              "CWE-20",
              "CWE-668"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
            },
            "range": "<=2.7.3"
          }
        ],
        "effects": [
          "jsdoc-wmf-theme"
        ],
        "range": "*",
        "nodes": [
          "node_modules/taffydb"
        ],
        "fixAvailable": {
          "name": "jsdoc-wmf-theme",
          "version": "1.0.0",
          "isSemVerMajor": true
        }
      },
      "yargs-unparser": {
        "name": "yargs-unparser",
        "severity": "critical",
        "isDirect": false,
        "via": [
          "flat"
        ],
        "effects": [
          "mocha"
        ],
        "range": "<=1.6.3",
        "nodes": [
          "node_modules/yargs-unparser"
        ],
        "fixAvailable": {
          "name": "mocha",
          "version": "10.4.0",
          "isSemVerMajor": true
        }
      }
    },
    "metadata": {
      "vulnerabilities": {
        "info": 0,
        "low": 1,
        "moderate": 0,
        "high": 3,
        "critical": 3,
        "total": 7
      },
      "dependencies": {
        "prod": 1,
        "dev": 363,
        "optional": 2,
        "peer": 1,
        "peerOptional": 0,
        "total": 363
      }
    }
  }
}

--- end ---
{"added": 1, "removed": 0, "changed": 0, "audited": 364, "funding": 53, "audit": {"auditReportVersion": 2, "vulnerabilities": {"debug": {"name": "debug", "severity": "low", "isDirect": false, "via": [{"source": 1096793, "name": "debug", "dependency": "debug", "title": "Regular Expression Denial of Service in debug", "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c", "severity": "low", "cwe": ["CWE-400"], "cvss": {"score": 3.7, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": ">=3.2.0 <3.2.7"}], "effects": ["mocha"], "range": "3.2.0 - 3.2.6", "nodes": ["node_modules/mocha/node_modules/debug"], "fixAvailable": {"name": "mocha", "version": "10.4.0", "isSemVerMajor": true}}, "flat": {"name": "flat", "severity": "critical", "isDirect": false, "via": [{"source": 1089152, "name": "flat", "dependency": "flat", "title": "flat vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-2j2x-2gpw-g8fm", "severity": "critical", "cwe": ["CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": "<5.0.1"}], "effects": ["yargs-unparser"], "range": "<5.0.1", "nodes": ["node_modules/flat"], "fixAvailable": {"name": "mocha", "version": "10.4.0", "isSemVerMajor": true}}, "jsdoc-wmf-theme": {"name": "jsdoc-wmf-theme", "severity": "high", "isDirect": true, "via": ["taffydb"], "effects": [], "range": "<=0.0.12", "nodes": ["node_modules/jsdoc-wmf-theme"], "fixAvailable": {"name": "jsdoc-wmf-theme", "version": "1.0.0", "isSemVerMajor": true}}, "minimatch": {"name": "minimatch", "severity": "high", "isDirect": false, "via": [{"source": 1096485, "name": "minimatch", "dependency": "minimatch", "title": "minimatch ReDoS vulnerability", "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3", "severity": "high", "cwe": ["CWE-400", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": "<3.0.5"}], "effects": ["mocha"], "range": "<3.0.5", "nodes": ["node_modules/minimatch"], "fixAvailable": {"name": "mocha", "version": "10.4.0", "isSemVerMajor": true}}, "mocha": {"name": "mocha", "severity": "critical", "isDirect": true, "via": ["debug", "minimatch", "yargs-unparser"], "effects": [], "range": "5.1.0 - 9.2.1", "nodes": ["node_modules/mocha"], "fixAvailable": {"name": "mocha", "version": "10.4.0", "isSemVerMajor": true}}, "taffydb": {"name": "taffydb", "severity": "high", "isDirect": false, "via": [{"source": 1089386, "name": "taffydb", "dependency": "taffydb", "title": "TaffyDB can allow access to any data items in the DB", "url": "https://github.com/advisories/GHSA-mxhp-79qh-mcx6", "severity": "high", "cwe": ["CWE-20", "CWE-668"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"}, "range": "<=2.7.3"}], "effects": ["jsdoc-wmf-theme"], "range": "*", "nodes": ["node_modules/taffydb"], "fixAvailable": {"name": "jsdoc-wmf-theme", "version": "1.0.0", "isSemVerMajor": true}}, "yargs-unparser": {"name": "yargs-unparser", "severity": "critical", "isDirect": false, "via": ["flat"], "effects": ["mocha"], "range": "<=1.6.3", "nodes": ["node_modules/yargs-unparser"], "fixAvailable": {"name": "mocha", "version": "10.4.0", "isSemVerMajor": true}}}, "metadata": {"vulnerabilities": {"info": 0, "low": 1, "moderate": 0, "high": 3, "critical": 3, "total": 7}, "dependencies": {"prod": 1, "dev": 363, "optional": 2, "peer": 1, "peerOptional": 0, "total": 363}}}}
$ /usr/bin/npm audit fix --only=dev
--- stderr ---
npm WARN invalid config only="dev" set in command line options
npm WARN invalid config Must be one of: null, prod, production
--- stdout ---

up to date, audited 363 packages in 1s

53 packages are looking for funding
  run `npm fund` for details

# npm audit report

debug  3.2.0 - 3.2.6
Regular Expression Denial of Service in debug - https://github.com/advisories/GHSA-gxpj-cx7g-858c
fix available via `npm audit fix --force`
Will install mocha@10.4.0, which is a breaking change
node_modules/mocha/node_modules/debug
  mocha  5.1.0 - 9.2.1
  Depends on vulnerable versions of debug
  Depends on vulnerable versions of minimatch
  Depends on vulnerable versions of yargs-unparser
  node_modules/mocha

flat  <5.0.1
Severity: critical
flat vulnerable to Prototype Pollution - https://github.com/advisories/GHSA-2j2x-2gpw-g8fm
fix available via `npm audit fix --force`
Will install mocha@10.4.0, which is a breaking change
node_modules/flat
  yargs-unparser  <=1.6.3
  Depends on vulnerable versions of flat
  node_modules/yargs-unparser

minimatch  <3.0.5
Severity: high
minimatch ReDoS vulnerability - https://github.com/advisories/GHSA-f8q6-p94x-37v3
fix available via `npm audit fix --force`
Will install mocha@10.4.0, which is a breaking change
node_modules/minimatch

taffydb  *
Severity: high
TaffyDB can allow access to any data items in the DB - https://github.com/advisories/GHSA-mxhp-79qh-mcx6
fix available via `npm audit fix --force`
Will install jsdoc-wmf-theme@1.0.0, which is a breaking change
node_modules/taffydb
  jsdoc-wmf-theme  <=0.0.12
  Depends on vulnerable versions of taffydb
  node_modules/jsdoc-wmf-theme

7 vulnerabilities (1 low, 3 high, 3 critical)

To address all issues (including breaking changes), run:
  npm audit fix --force

--- end ---
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json

--- end ---
Verifying that tests still pass
$ /usr/bin/npm ci
--- stdout ---

added 362 packages, and audited 363 packages in 5s

53 packages are looking for funding
  run `npm fund` for details

7 vulnerabilities (1 low, 3 high, 3 critical)

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

--- end ---
$ /usr/bin/npm test
--- stderr ---
(node:586) DeprecationWarning: Configuration via mocha.opts is DEPRECATED and will be removed from a future version of Mocha. Use RC files or package.json instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
--- stdout ---

> wikimedia-langconv@0.4.1+git test
> npm run eslint && npm run mocha


> wikimedia-langconv@0.4.1+git eslint
> eslint lib


/src/repo/lib/FST.js
  48:1  warning  The type 'Utf8Array' is undefined          jsdoc/no-undefined-types
  52:1  warning  The type 'BracketMachine' is undefined     jsdoc/no-undefined-types
  52:1  warning  The type 'ConversionMachine' is undefined  jsdoc/no-undefined-types

/src/repo/lib/ReplacementMachine.js
   17:1  warning  Missing JSDoc @param "baseLanguage" type  jsdoc/require-param-type
   36:2  warning  Missing JSDoc @return declaration         jsdoc/require-returns
   37:1  warning  Missing JSDoc @param "filename" type      jsdoc/require-param-type
   38:1  warning  Missing JSDoc @param "bracket" type       jsdoc/require-param-type
   59:2  warning  Found more than one @return declaration   jsdoc/require-returns
   59:2  warning  Found more than one @return declaration   jsdoc/require-returns-check
   70:1  warning  Missing JSDoc @param "s" type             jsdoc/require-param-type
   71:1  warning  Missing JSDoc @param "destCode" type      jsdoc/require-param-type
   72:1  warning  Missing JSDoc @param "invertCode" type    jsdoc/require-param-type
  104:1  warning  The type 'Node' is undefined              jsdoc/no-undefined-types
  107:1  warning  The type 'Node' is undefined              jsdoc/no-undefined-types
  136:1  warning  The type 'Document' is undefined          jsdoc/no-undefined-types
  144:1  warning  The type 'DocumentFragment' is undefined  jsdoc/no-undefined-types

✖ 16 problems (0 errors, 16 warnings)


> wikimedia-langconv@0.4.1+git mocha
> mocha --opts tests/mocha/mocha.opts tests/mocha



  Foma FST verification
    - LANGCONV_TEST_FOMA is not set, skipping

  Language/CRH tests
    ✓ general words, covering more of the alphabet (1) [crh-cyrl]
    ✓ general words, covering more of the alphabet (2) [crh-cyrl]
    ✓ general words, covering more of the alphabet (3) [crh-cyrl]
    ✓ general words, covering more of the alphabet (4) [crh-cyrl]
    ✓ exception words [crh-cyrl]
    ✓ recent problem words, part 1 [crh-cyrl]
    ✓ recent problem words, part 2 [crh-cyrl]
    ✓ recent problem words, part 3 [crh-cyrl]
    ✓ recent problem words, part 4 [crh-cyrl]
    ✓ recent problem words, part 5 [crh-cyrl]
    ✓ recent problem words, part 6 [crh-cyrl]
    ✓ recent problem words, part 7 [crh-cyrl]
    ✓ regex pattern words [crh-cyrl]
    ✓ multi part words [crh-cyrl]
    ✓ affix patterns [crh-cyrl]
    ✓ Roman numerals and quotes, esp. single-letter Roman numerals at the end of a string [crh-cyrl]
    ✓ Roman numerals vs Initials, part 1 - Roman numeral initials without spaces [crh-cyrl]
    ✓ Roman numerals vs Initials, part 2 - Roman numeral initials with spaces [crh-cyrl]
    ✓ ALL CAPS, made up acronyms [crh-cyrl]
    ✓ Many-to-one mappings: many Cyrillic to one Latin [crh-cyrl]
    ✓ Many-to-one mappings: many Latin to one Cyrillic [crh-cyrl]
    ✓ general words, covering more of the alphabet (1) [crh-latn]
    ✓ general words, covering more of the alphabet (2) [crh-latn]
    ✓ general words, covering more of the alphabet (3) [crh-latn]
    ✓ general words, covering more of the alphabet (4) [crh-latn]
    ✓ exception words [crh-latn]
    ✓ recent problem words, part 1 [crh-latn]
    ✓ recent problem words, part 2 [crh-latn]
    ✓ recent problem words, part 3 [crh-latn]
    ✓ recent problem words, part 4 [crh-latn]
    ✓ recent problem words, part 5 [crh-latn]
    ✓ recent problem words, part 6 [crh-latn]
    ✓ recent problem words, part 7 [crh-latn]
    ✓ regex pattern words [crh-latn]
    ✓ multi part words [crh-latn]
    ✓ affix patterns [crh-latn]
    ✓ Roman numerals and quotes, esp. single-letter Roman numerals at the end of a string [crh-latn]
    ✓ Roman numerals vs Initials, part 1 - Roman numeral initials without spaces [crh-latn]
    ✓ Roman numerals vs Initials, part 2 - Roman numeral initials with spaces [crh-latn]
    ✓ ALL CAPS, made up acronyms [crh-latn]
    ✓ Many-to-one mappings: many Cyrillic to one Latin [crh-latn]
    ✓ Many-to-one mappings: many Latin to one Cyrillic [crh-latn]

  LanguageEn tests
    ✓ Converting to Pig Latin [en]
    ✓ Converting from Pig Latin [en]
    ✓ Converting to Pig Latin [en-x-piglatin]
    ✓ Converting from Pig Latin [en-x-piglatin]

  LanguageKu tests
    ✓ Test (1) [ku-arab]
    ✓ Test (3) [ku-arab]
    ✓ Test (1) [ku-latn]
    ✓ Test (2) [ku-latn]
    ✓ Test (3) [ku-latn]

  LanguageSr tests
    ✓ A simple conversion of Latin to Cyrillic [sr-ec]

  LanguageZh tests
    ✓ Plain hant -> hans [zh-cn]
    ✓ Plain hans -> hant [zh-cn]
    ✓ zh-cn specific [zh-cn]
    ✓ zh-hk specific [zh-cn]
    ✓ zh-tw specific [zh-cn]
    ✓ zh-tw overrides zh-hant [zh-cn]
    ✓ zh-hk overrides zh-hant [zh-cn]
    ✓ Plain hant -> hans [zh-sg]
    ✓ Plain hans -> hant [zh-sg]
    ✓ zh-cn specific [zh-sg]
    ✓ zh-hk specific [zh-sg]
    ✓ zh-tw specific [zh-sg]
    ✓ zh-tw overrides zh-hant [zh-sg]
    ✓ zh-hk overrides zh-hant [zh-sg]
    ✓ Plain hant -> hans [zh-my]
    ✓ Plain hans -> hant [zh-my]
    ✓ zh-cn specific [zh-my]
    ✓ zh-hk specific [zh-my]
    ✓ zh-tw specific [zh-my]
    ✓ zh-tw overrides zh-hant [zh-my]
    ✓ zh-hk overrides zh-hant [zh-my]
    ✓ Plain hant -> hans [zh-hans]
    ✓ Plain hans -> hant [zh-hans]
    ✓ zh-cn specific [zh-hans]
    ✓ zh-hk specific [zh-hans]
    ✓ zh-tw specific [zh-hans]
    ✓ zh-tw overrides zh-hant [zh-hans]
    ✓ zh-hk overrides zh-hant [zh-hans]
    ✓ Plain hant -> hans [zh-tw]
    ✓ Plain hans -> hant [zh-tw]
    ✓ zh-cn specific [zh-tw]
    ✓ zh-hk specific [zh-tw]
    ✓ zh-tw specific [zh-tw]
    ✓ zh-tw overrides zh-hant [zh-tw]
    ✓ zh-hk overrides zh-hant [zh-tw]
    ✓ Plain hant -> hans [zh-hk]
    ✓ Plain hans -> hant [zh-hk]
    ✓ zh-cn specific [zh-hk]
    ✓ zh-hk specific [zh-hk]
    ✓ zh-tw specific [zh-hk]
    ✓ zh-tw overrides zh-hant [zh-hk]
    ✓ zh-hk overrides zh-hant [zh-hk]
    ✓ Plain hant -> hans [zh-mo]
    ✓ Plain hans -> hant [zh-mo]
    ✓ zh-cn specific [zh-mo]
    ✓ zh-hk specific [zh-mo]
    ✓ zh-tw specific [zh-mo]
    ✓ zh-tw overrides zh-hant [zh-mo]
    ✓ zh-hk overrides zh-hant [zh-mo]
    ✓ Plain hant -> hans [zh-hant]
    ✓ Plain hans -> hant [zh-hant]
    ✓ zh-cn specific [zh-hant]
    ✓ zh-hk specific [zh-hant]
    ✓ zh-tw specific [zh-hant]
    ✓ zh-tw overrides zh-hant [zh-hant]
    ✓ zh-hk overrides zh-hant [zh-hant]


  108 passing (59ms)
  1 pending


--- end ---
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json

--- end ---
build: Updating eslint-config-wikimedia to 0.27.0

$ git add .
--- stdout ---

--- end ---
$ git commit -F /tmp/tmpi2dj23ti
--- stdout ---
[master f86bf41] build: Updating eslint-config-wikimedia to 0.27.0
 5 files changed, 434 insertions(+), 599 deletions(-)

--- end ---
$ git format-patch HEAD~1 --stdout
--- stdout ---
From f86bf41c06fe93490ec6f34f542389b6e0ea3a3b Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Thu, 18 Apr 2024 11:46:21 +0000
Subject: [PATCH] build: Updating eslint-config-wikimedia to 0.27.0

Change-Id: I26a3a2b33192867913a536fd0f1cf6a7256b2e3f
---
 lib/FST.js                  |    4 +
 lib/ReplacementMachine.js   |    6 +
 package-lock.json           | 1020 +++++++++++++++--------------------
 package.json                |    2 +-
 tools/build-langconv-fst.js |    1 +
 5 files changed, 434 insertions(+), 599 deletions(-)

diff --git a/lib/FST.js b/lib/FST.js
index 668ee5a..ecc26e8 100644
--- a/lib/FST.js
+++ b/lib/FST.js
@@ -1,6 +1,7 @@
 /**
  * Load and execute a finite-state transducer (FST) based converter or
  * bracketing machine from a compact JSON description.
+ *
  * @module
  */
 
@@ -21,6 +22,7 @@ const BYTE_EPSILON  = 0x00; // Always appears first in sorted order
 
 /**
  * A FST conversion machine.
+ *
  * @callback module:language/FST~ConversionMachine
  * @param {Buffer} buffer UTF-8 encoded input buffer.
  * @param {number} [start] Start position in the buffer, default 0.
@@ -31,6 +33,7 @@ const BYTE_EPSILON  = 0x00; // Always appears first in sorted order
 
 /**
  * A FST bracket machine.
+ *
  * @callback module:language/FST~BracketMachine
  * @param {Buffer} buffer UTF-8 encoded input buffer.
  * @param {number} [start] Start position in the buffer, default 0.
@@ -41,6 +44,7 @@ const BYTE_EPSILON  = 0x00; // Always appears first in sorted order
 
 /**
  * Load an FST description and return a function which runs the machine.
+ *
  * @param {Buffer|Utf8Array|string} file The FST description, either as a
  *  filename (to be loaded synchronously) or a loaded byte array.
  * @param {boolean} [justBrackets] The machine will return an array of
diff --git a/lib/ReplacementMachine.js b/lib/ReplacementMachine.js
index 87a577c..d8d7b93 100644
--- a/lib/ReplacementMachine.js
+++ b/lib/ReplacementMachine.js
@@ -1,6 +1,7 @@
 /**
  * This is a wrapper around functionality similar to PHP's `ReplacementArray`,
  * but built on (reversible) Finite-State Transducers.
+ *
  * @module
  */
 
@@ -12,6 +13,7 @@ class ReplacementMachine {
 	/**
 	 * Create a new ReplacementArray, which holds a given source->destination
 	 * transformation.
+	 *
 	 * @param baseLanguage
 	 * @param {...any} codes
 	 */
@@ -45,6 +47,7 @@ class ReplacementMachine {
 	 * possible code pairs bracketed.  (For example, zh has a large
 	 * number of variants, but we typically want to use only a limited
 	 * number of these as possible invert codes.)
+	 *
 	 * @param {string} destCode
 	 * @param {string} invertCode
 	 * @return {boolean} whether this is a valid bracketing pair.
@@ -63,6 +66,7 @@ class ReplacementMachine {
 	 * the number of codepoints we wouldn't have to escape, and `len` is
 	 * the total number of codepoints in `s`.  Generally lower values of
 	 * `nonsafe` indicate a better guess for `invertCode`.
+	 *
 	 * @param s
 	 * @param destCode
 	 * @param invertCode
@@ -96,6 +100,7 @@ class ReplacementMachine {
 	 * Replace the given text Node with converted text, protecting any
 	 * markup which can't be round-tripped back to `invertCode` with
 	 * appropriate synthetic language-converter markup.
+	 *
 	 * @param {Node} textNode
 	 * @param {string} destCode
 	 * @param {string} invertCode
@@ -127,6 +132,7 @@ class ReplacementMachine {
 	 * markup which can't be round-tripped back to `invertCode` with
 	 * appropriate synthetic language-converter markup.  Returns
 	 * a DocumentFragment.
+	 *
 	 * @param {Document} document
 	 *   Owner of the resulting DocumentFragment.
 	 * @param {string} s
diff --git a/package-lock.json b/package-lock.json
index 5358bd1..2f8b1fa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,7 @@
 				"babybird": "^0.0.1",
 				"chai": "^4.2.0",
 				"domino": "^2.1.0",
-				"eslint-config-wikimedia": "0.26.0",
+				"eslint-config-wikimedia": "0.27.0",
 				"jsdoc": "4.0.2",
 				"jsdoc-wmf-theme": "0.0.12",
 				"mocha": "^7.1.2",
@@ -30,32 +30,18 @@
 			}
 		},
 		"node_modules/@babel/code-frame": {
-			"version": "7.23.5",
-			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
-			"integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+			"integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
 			"dev": true,
 			"dependencies": {
-				"@babel/highlight": "^7.23.4",
-				"chalk": "^2.4.2"
+				"@babel/highlight": "^7.24.2",
+				"picocolors": "^1.0.0"
 			},
 			"engines": {
 				"node": ">=6.9.0"
 			}
 		},
-		"node_modules/@babel/code-frame/node_modules/chalk": {
-			"version": "2.4.2",
-			"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-			"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-			"dev": true,
-			"dependencies": {
-				"ansi-styles": "^3.2.1",
-				"escape-string-regexp": "^1.0.5",
-				"supports-color": "^5.3.0"
-			},
-			"engines": {
-				"node": ">=4"
-			}
-		},
 		"node_modules/@babel/helper-validator-identifier": {
 			"version": "7.22.20",
 			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
@@ -66,14 +52,15 @@
 			}
 		},
 		"node_modules/@babel/highlight": {
-			"version": "7.23.4",
-			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
-			"integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
+			"integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
 			"dev": true,
 			"dependencies": {
 				"@babel/helper-validator-identifier": "^7.22.20",
 				"chalk": "^2.4.2",
-				"js-tokens": "^4.0.0"
+				"js-tokens": "^4.0.0",
+				"picocolors": "^1.0.0"
 			},
 			"engines": {
 				"node": ">=6.9.0"
@@ -106,17 +93,17 @@
 			}
 		},
 		"node_modules/@es-joy/jsdoccomment": {
-			"version": "0.37.1",
-			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.37.1.tgz",
-			"integrity": "sha512-5vxWJ1gEkEF0yRd0O+uK6dHJf7adrxwQSX8PuRiPfFSAbNLnY0ZJfXaZucoz14Jj2N11xn2DnlEPwWRpYpvRjg==",
+			"version": "0.42.0",
+			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz",
+			"integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==",
 			"dev": true,
 			"dependencies": {
-				"comment-parser": "1.3.1",
+				"comment-parser": "1.4.1",
 				"esquery": "^1.5.0",
 				"jsdoc-type-pratt-parser": "~4.0.0"
 			},
 			"engines": {
-				"node": "^14 || ^16 || ^17 || ^18 || ^19 || ^20"
+				"node": ">=16"
 			}
 		},
 		"node_modules/@eslint-community/eslint-utils": {
@@ -134,15 +121,6 @@
 				"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
 			}
 		},
-		"node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
-			"version": "3.3.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-			"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			}
-		},
 		"node_modules/@eslint-community/regexpp": {
 			"version": "4.10.0",
 			"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
@@ -188,9 +166,9 @@
 			}
 		},
 		"node_modules/@eslint/js": {
-			"version": "8.56.0",
-			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
-			"integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+			"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
 			"dev": true,
 			"engines": {
 				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -329,9 +307,9 @@
 			"dev": true
 		},
 		"node_modules/@types/semver": {
-			"version": "7.5.6",
-			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz",
-			"integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==",
+			"version": "7.5.8",
+			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+			"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
 			"dev": true
 		},
 		"node_modules/@typescript-eslint/scope-manager": {
@@ -456,18 +434,6 @@
 				"url": "https://opencollective.com/typescript-eslint"
 			}
 		},
-		"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
 		"node_modules/@ungap/structured-clone": {
 			"version": "1.2.0",
 			"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
@@ -672,9 +638,9 @@
 			"dev": true
 		},
 		"node_modules/browserslist": {
-			"version": "4.21.10",
-			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
-			"integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==",
+			"version": "4.23.0",
+			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+			"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
 			"dev": true,
 			"funding": [
 				{
@@ -691,10 +657,10 @@
 				}
 			],
 			"dependencies": {
-				"caniuse-lite": "^1.0.30001517",
-				"electron-to-chromium": "^1.4.477",
-				"node-releases": "^2.0.13",
-				"update-browserslist-db": "^1.0.11"
+				"caniuse-lite": "^1.0.30001587",
+				"electron-to-chromium": "^1.4.668",
+				"node-releases": "^2.0.14",
+				"update-browserslist-db": "^1.0.13"
 			},
 			"bin": {
 				"browserslist": "cli.js"
@@ -704,9 +670,9 @@
 			}
 		},
 		"node_modules/browserslist-config-wikimedia": {
-			"version": "0.5.1",
-			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.5.1.tgz",
-			"integrity": "sha512-jf532fUf/gaxiKdHgGCQUT552P5up3RpG+CzLixOQBJ5FwDmYQSRLYHCFUA9s3KMOHh4P3xVp+NUaGNxvtoT9g==",
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.6.1.tgz",
+			"integrity": "sha512-F3O+12ud7ZwBaiB/RZIMGDgz3nEuXz8RhtdPB4Lkd/WVP5Vy77EqBWRMz4vJ64x8LTTH3BOaHCD2ZuUcgShqyQ==",
 			"dev": true
 		},
 		"node_modules/builtin-modules": {
@@ -749,9 +715,9 @@
 			}
 		},
 		"node_modules/caniuse-lite": {
-			"version": "1.0.30001583",
-			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001583.tgz",
-			"integrity": "sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==",
+			"version": "1.0.30001611",
+			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001611.tgz",
+			"integrity": "sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==",
 			"dev": true,
 			"funding": [
 				{
@@ -898,9 +864,9 @@
 			}
 		},
 		"node_modules/ci-info": {
-			"version": "3.9.0",
-			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
-			"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz",
+			"integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==",
 			"dev": true,
 			"funding": [
 				{
@@ -972,9 +938,9 @@
 			"dev": true
 		},
 		"node_modules/comment-parser": {
-			"version": "1.3.1",
-			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
-			"integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+			"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
 			"dev": true,
 			"engines": {
 				"node": ">= 12.0.0"
@@ -994,6 +960,19 @@
 			"hasInstallScript": true,
 			"optional": true
 		},
+		"node_modules/core-js-compat": {
+			"version": "3.37.0",
+			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz",
+			"integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==",
+			"dev": true,
+			"dependencies": {
+				"browserslist": "^4.23.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/core-js"
+			}
+		},
 		"node_modules/cross-spawn": {
 			"version": "7.0.3",
 			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -1116,9 +1095,9 @@
 			"dev": true
 		},
 		"node_modules/electron-to-chromium": {
-			"version": "1.4.499",
-			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.499.tgz",
-			"integrity": "sha512-0NmjlYBLKVHva4GABWAaHuPJolnDuL0AhV3h1hES6rcLCWEIbRL6/8TghfsVwkx6TEroQVdliX7+aLysUpKvjw==",
+			"version": "1.4.740",
+			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.740.tgz",
+			"integrity": "sha512-Yvg5i+iyv7Xm18BRdVPVm8lc7kgxM3r6iwqCH2zB7QZy1kZRNmd0Zqm0zcD9XoFREE5/5rwIuIAOT+/mzGcnZg==",
 			"dev": true
 		},
 		"node_modules/emoji-regex": {
@@ -1182,9 +1161,9 @@
 			}
 		},
 		"node_modules/escalade": {
-			"version": "3.1.1",
-			"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-			"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+			"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
 			"dev": true,
 			"engines": {
 				"node": ">=6"
@@ -1200,16 +1179,16 @@
 			}
 		},
 		"node_modules/eslint": {
-			"version": "8.56.0",
-			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
-			"integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+			"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
 			"dev": true,
 			"dependencies": {
 				"@eslint-community/eslint-utils": "^4.2.0",
 				"@eslint-community/regexpp": "^4.6.1",
 				"@eslint/eslintrc": "^2.1.4",
-				"@eslint/js": "8.56.0",
-				"@humanwhocodes/config-array": "^0.11.13",
+				"@eslint/js": "8.57.0",
+				"@humanwhocodes/config-array": "^0.11.14",
 				"@humanwhocodes/module-importer": "^1.0.1",
 				"@nodelib/fs.walk": "^1.2.8",
 				"@ungap/structured-clone": "^1.2.0",
@@ -1255,10 +1234,13 @@
 			}
 		},
 		"node_modules/eslint-compat-utils": {
-			"version": "0.1.2",
-			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz",
-			"integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==",
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz",
+			"integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==",
 			"dev": true,
+			"dependencies": {
+				"semver": "^7.5.4"
+			},
 			"engines": {
 				"node": ">=12"
 			},
@@ -1267,85 +1249,28 @@
 			}
 		},
 		"node_modules/eslint-config-wikimedia": {
-			"version": "0.26.0",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.26.0.tgz",
-			"integrity": "sha512-TAXTySls9k3oWs754rIjlcd9PBLvYeMvjqjiuU8u4gweu0UDgBJGslf+zcvVNXEooAtyLZdENjrzDDjG8ssS7Q==",
+			"version": "0.27.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.27.0.tgz",
+			"integrity": "sha512-KkZ54+MUnggz17C/RCEMXQSpiiqZRF7p9fjrz4phaaeKlTrjg0B+QbM5zcDWcjGiAWaJUptHaH17+RZldadkUw==",
 			"dev": true,
 			"dependencies": {
-				"browserslist-config-wikimedia": "^0.5.1",
-				"eslint": "^8.53.0",
+				"browserslist-config-wikimedia": "^0.6.1",
+				"eslint": "^8.57.0",
 				"eslint-plugin-compat": "^4.2.0",
-				"eslint-plugin-es-x": "^7.3.0",
-				"eslint-plugin-jest": "^27.6.0",
-				"eslint-plugin-jsdoc": "^42.0.0",
+				"eslint-plugin-es-x": "^7.6.0",
+				"eslint-plugin-jest": "^27.9.0",
+				"eslint-plugin-jsdoc": "48.2.1",
 				"eslint-plugin-json-es": "^1.5.7",
-				"eslint-plugin-mediawiki": "^0.5.0",
-				"eslint-plugin-mocha": "^10.2.0",
-				"eslint-plugin-n": "^16.0.1",
+				"eslint-plugin-mediawiki": "^0.6.0",
+				"eslint-plugin-mocha": "^10.4.1",
+				"eslint-plugin-n": "^16.6.2",
 				"eslint-plugin-no-jquery": "^2.7.0",
-				"eslint-plugin-qunit": "^7.3.4",
+				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
-				"eslint-plugin-unicorn": "^47.0.0",
-				"eslint-plugin-vue": "^9.18.1",
-				"eslint-plugin-wdio": "^7.19.4",
-				"eslint-plugin-yml": "^1.10.0"
-			}
-		},
-		"node_modules/eslint-config-wikimedia/node_modules/eslint-plugin-vue": {
-			"version": "9.21.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz",
-			"integrity": "sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==",
-			"dev": true,
-			"dependencies": {
-				"@eslint-community/eslint-utils": "^4.4.0",
-				"natural-compare": "^1.4.0",
-				"nth-check": "^2.1.1",
-				"postcss-selector-parser": "^6.0.13",
-				"semver": "^7.5.4",
-				"vue-eslint-parser": "^9.4.2",
-				"xml-name-validator": "^4.0.0"
-			},
-			"engines": {
-				"node": "^14.17.0 || >=16.0.0"
-			},
-			"peerDependencies": {
-				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
-			}
-		},
-		"node_modules/eslint-config-wikimedia/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
-		"node_modules/eslint-config-wikimedia/node_modules/vue-eslint-parser": {
-			"version": "9.4.2",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
-			"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
-			"dev": true,
-			"dependencies": {
-				"debug": "^4.3.4",
-				"eslint-scope": "^7.1.1",
-				"eslint-visitor-keys": "^3.3.0",
-				"espree": "^9.3.1",
-				"esquery": "^1.4.0",
-				"lodash": "^4.17.21",
-				"semver": "^7.3.6"
-			},
-			"engines": {
-				"node": "^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
-			},
-			"peerDependencies": {
-				"eslint": ">=6.0.0"
+				"eslint-plugin-unicorn": "^51.0.1",
+				"eslint-plugin-vue": "^9.23.0",
+				"eslint-plugin-wdio": "^8.24.12",
+				"eslint-plugin-yml": "^1.13.2"
 			}
 		},
 		"node_modules/eslint-plugin-compat": {
@@ -1440,14 +1365,14 @@
 			}
 		},
 		"node_modules/eslint-plugin-es-x": {
-			"version": "7.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz",
-			"integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz",
+			"integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==",
 			"dev": true,
 			"dependencies": {
 				"@eslint-community/eslint-utils": "^4.1.2",
 				"@eslint-community/regexpp": "^4.6.0",
-				"eslint-compat-utils": "^0.1.2"
+				"eslint-compat-utils": "^0.5.0"
 			},
 			"engines": {
 				"node": "^14.18.0 || >=16.0.0"
@@ -1460,9 +1385,9 @@
 			}
 		},
 		"node_modules/eslint-plugin-jest": {
-			"version": "27.6.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.6.3.tgz",
-			"integrity": "sha512-+YsJFVH6R+tOiO3gCJon5oqn4KWc+mDq2leudk8mrp8RFubLOo9CVyi3cib4L7XMpxExmkmBZQTPDYVBzgpgOA==",
+			"version": "27.9.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz",
+			"integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==",
 			"dev": true,
 			"dependencies": {
 				"@typescript-eslint/utils": "^5.10.0"
@@ -1471,7 +1396,7 @@
 				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
 			},
 			"peerDependencies": {
-				"@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0",
+				"@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0",
 				"eslint": "^7.0.0 || ^8.0.0",
 				"jest": "*"
 			},
@@ -1485,25 +1410,26 @@
 			}
 		},
 		"node_modules/eslint-plugin-jsdoc": {
-			"version": "42.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-42.0.0.tgz",
-			"integrity": "sha512-qXYr45G8atPKowZbIOdmABukMzu9IMjAlj6j5Fe0iuUItznWSXUDiBj57ejXcbt8bkPrg83333nuz+cqGKFgcQ==",
+			"version": "48.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz",
+			"integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==",
 			"dev": true,
 			"dependencies": {
-				"@es-joy/jsdoccomment": "~0.37.0",
+				"@es-joy/jsdoccomment": "~0.42.0",
 				"are-docs-informative": "^0.0.2",
-				"comment-parser": "1.3.1",
+				"comment-parser": "1.4.1",
 				"debug": "^4.3.4",
 				"escape-string-regexp": "^4.0.0",
 				"esquery": "^1.5.0",
-				"semver": "^7.3.8",
-				"spdx-expression-parse": "^3.0.1"
+				"is-builtin-module": "^3.2.1",
+				"semver": "^7.6.0",
+				"spdx-expression-parse": "^4.0.0"
 			},
 			"engines": {
-				"node": "^14 || ^16 || ^17 || ^18 || ^19"
+				"node": ">=18"
 			},
 			"peerDependencies": {
-				"eslint": "^7.0.0 || ^8.0.0"
+				"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": {
@@ -1531,22 +1457,13 @@
 				"eslint": ">= 7"
 			}
 		},
-		"node_modules/eslint-plugin-json-es/node_modules/eslint-visitor-keys": {
-			"version": "3.3.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-			"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			}
-		},
 		"node_modules/eslint-plugin-mediawiki": {
-			"version": "0.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.5.0.tgz",
-			"integrity": "sha512-rjkHFyv3VDan/dmu7YpD1Rl9h64NOlz4mqqesRN316R+571+ymmb6lXVOdNMbT8H1iPhmtHc+nijVLVkn7pYDw==",
+			"version": "0.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.6.0.tgz",
+			"integrity": "sha512-a2Zm18N5nPyflBajM2ZWATxucIpYPEmOSjFzUR1OBH3hAL0GY9fx1mpezEwzqAQ862d+kPkolgQOzktnZe8nKA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-plugin-vue": "^8.7.1",
+				"eslint-plugin-vue": "^9.23.0",
 				"upath": "^2.0.1"
 			},
 			"peerDependencies": {
@@ -1554,12 +1471,13 @@
 			}
 		},
 		"node_modules/eslint-plugin-mocha": {
-			"version": "10.2.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.2.0.tgz",
-			"integrity": "sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ==",
+			"version": "10.4.2",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.2.tgz",
+			"integrity": "sha512-cur4dVYnSEWTBwdqIBQFxa/9siAhesu0TX+lbJ4ClE9j0eNMNe6BSx3vkFFNz6tGoveyMyELFXa30f3fvuAVDg==",
 			"dev": true,
 			"dependencies": {
 				"eslint-utils": "^3.0.0",
+				"globals": "^13.24.0",
 				"rambda": "^7.4.0"
 			},
 			"engines": {
@@ -1619,16 +1537,16 @@
 			}
 		},
 		"node_modules/eslint-plugin-qunit": {
-			"version": "7.3.4",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.3.4.tgz",
-			"integrity": "sha512-EbDM0zJerH9zVdUswMJpcFF7wrrpvsGuYfNexUpa5hZkkdFhaFcX+yD+RSK4Nrauw4psMGlcqeWUMhaVo+Manw==",
+			"version": "8.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-8.1.1.tgz",
+			"integrity": "sha512-j3xhiAf2Wvr8Dfwl5T6tlJ+F55vqYE9ZdAHUOTzq1lGerYrXzOS46RvK4SSWug2D8sl3ZYr2lA4/hgVXgLloxw==",
 			"dev": true,
 			"dependencies": {
 				"eslint-utils": "^3.0.0",
 				"requireindex": "^1.2.0"
 			},
 			"engines": {
-				"node": "12.x || 14.x || >=16.0.0"
+				"node": "^16.0.0 || ^18.0.0 || >=20.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-security": {
@@ -1641,26 +1559,26 @@
 			}
 		},
 		"node_modules/eslint-plugin-unicorn": {
-			"version": "47.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-47.0.0.tgz",
-			"integrity": "sha512-ivB3bKk7fDIeWOUmmMm9o3Ax9zbMz1Bsza/R2qm46ufw4T6VBFBaJIR1uN3pCKSmSXm8/9Nri8V+iUut1NhQGA==",
+			"version": "51.0.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz",
+			"integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-validator-identifier": "^7.19.1",
+				"@babel/helper-validator-identifier": "^7.22.20",
 				"@eslint-community/eslint-utils": "^4.4.0",
-				"ci-info": "^3.8.0",
+				"@eslint/eslintrc": "^2.1.4",
+				"ci-info": "^4.0.0",
 				"clean-regexp": "^1.0.0",
+				"core-js-compat": "^3.34.0",
 				"esquery": "^1.5.0",
 				"indent-string": "^4.0.0",
 				"is-builtin-module": "^3.2.1",
 				"jsesc": "^3.0.2",
-				"lodash": "^4.17.21",
 				"pluralize": "^8.0.0",
 				"read-pkg-up": "^7.0.1",
-				"regexp-tree": "^0.1.24",
+				"regexp-tree": "^0.1.27",
 				"regjsparser": "^0.10.0",
-				"safe-regex": "^2.1.1",
-				"semver": "^7.3.8",
+				"semver": "^7.5.4",
 				"strip-indent": "^3.0.0"
 			},
 			"engines": {
@@ -1670,46 +1588,48 @@
 				"url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1"
 			},
 			"peerDependencies": {
-				"eslint": ">=8.38.0"
+				"eslint": ">=8.56.0"
 			}
 		},
 		"node_modules/eslint-plugin-vue": {
-			"version": "8.7.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz",
-			"integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==",
+			"version": "9.25.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz",
+			"integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-utils": "^3.0.0",
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"globals": "^13.24.0",
 				"natural-compare": "^1.4.0",
-				"nth-check": "^2.0.1",
-				"postcss-selector-parser": "^6.0.9",
-				"semver": "^7.3.5",
-				"vue-eslint-parser": "^8.0.1"
+				"nth-check": "^2.1.1",
+				"postcss-selector-parser": "^6.0.15",
+				"semver": "^7.6.0",
+				"vue-eslint-parser": "^9.4.2",
+				"xml-name-validator": "^4.0.0"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"peerDependencies": {
-				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
+				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-wdio": {
-			"version": "7.25.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.25.3.tgz",
-			"integrity": "sha512-2zbYwV14Md9FNlyhaIILVGPB6w4bu2eJdOTywDUs2Qy4ebcQNwrxB0qCaf7Rm4O+T0Ir+tdYHYBBfbDocSLKng==",
+			"version": "8.24.12",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-8.24.12.tgz",
+			"integrity": "sha512-OmzGteXFOQnJDdkTNnTfksaVa18WlFCyeLjZXHvDpkbomLWAg9wc296Pr0wnTCagqNj8qfEHpy+N2XVew5VCMA==",
 			"dev": true,
 			"engines": {
-				"node": ">=12.0.0"
+				"node": "^16.13 || >=18"
 			}
 		},
 		"node_modules/eslint-plugin-yml": {
-			"version": "1.12.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.12.2.tgz",
-			"integrity": "sha512-hvS9p08FhPT7i/ynwl7/Wt7ke7Rf4P2D6fT8lZlL43peZDTsHtH2A0SIFQ7Kt7+mJ6if6P+FX3iJhMkdnxQwpg==",
+			"version": "1.14.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz",
+			"integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==",
 			"dev": true,
 			"dependencies": {
 				"debug": "^4.3.2",
-				"eslint-compat-utils": "^0.4.0",
+				"eslint-compat-utils": "^0.5.0",
 				"lodash": "^4.17.21",
 				"natural-compare": "^1.4.0",
 				"yaml-eslint-parser": "^1.2.1"
@@ -1724,21 +1644,6 @@
 				"eslint": ">=6.0.0"
 			}
 		},
-		"node_modules/eslint-plugin-yml/node_modules/eslint-compat-utils": {
-			"version": "0.4.1",
-			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.4.1.tgz",
-			"integrity": "sha512-5N7ZaJG5pZxUeNNJfUchurLVrunD1xJvyg5kYOIVF8kg1f3ajTikmAu/5fZ9w100omNPOoMjngRszh/Q/uFGMg==",
-			"dev": true,
-			"dependencies": {
-				"semver": "^7.5.4"
-			},
-			"engines": {
-				"node": ">=12"
-			},
-			"peerDependencies": {
-				"eslint": ">=6.0.0"
-			}
-		},
 		"node_modules/eslint-scope": {
 			"version": "7.2.2",
 			"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
@@ -1773,7 +1678,7 @@
 				"eslint": ">=5"
 			}
 		},
-		"node_modules/eslint-visitor-keys": {
+		"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
 			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
@@ -1782,28 +1687,28 @@
 				"node": ">=10"
 			}
 		},
-		"node_modules/eslint/node_modules/escape-string-regexp": {
-			"version": "4.0.0",
-			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-			"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+		"node_modules/eslint-visitor-keys": {
+			"version": "3.4.3",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
 			"dev": true,
 			"engines": {
-				"node": ">=10"
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
 			},
 			"funding": {
-				"url": "https://github.com/sponsors/sindresorhus"
+				"url": "https://opencollective.com/eslint"
 			}
 		},
-		"node_modules/eslint/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+		"node_modules/eslint/node_modules/escape-string-regexp": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+			"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
 			"dev": true,
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": ">=10"
 			},
 			"funding": {
-				"url": "https://opencollective.com/eslint"
+				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
 		"node_modules/eslint/node_modules/find-up": {
@@ -1917,18 +1822,6 @@
 				"url": "https://opencollective.com/eslint"
 			}
 		},
-		"node_modules/espree/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
 		"node_modules/esprima": {
 			"version": "4.0.1",
 			"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
@@ -3043,9 +2936,9 @@
 			}
 		},
 		"node_modules/node-releases": {
-			"version": "2.0.13",
-			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
-			"integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+			"version": "2.0.14",
+			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+			"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
 			"dev": true
 		},
 		"node_modules/normalize-package-data": {
@@ -3313,9 +3206,9 @@
 			"dev": true
 		},
 		"node_modules/postcss-selector-parser": {
-			"version": "6.0.15",
-			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
-			"integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
+			"version": "6.0.16",
+			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
+			"integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
 			"dev": true,
 			"dependencies": {
 				"cssesc": "^3.0.0",
@@ -3487,9 +3380,9 @@
 			}
 		},
 		"node_modules/regexp-tree": {
-			"version": "0.1.24",
-			"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz",
-			"integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==",
+			"version": "0.1.27",
+			"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
+			"integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==",
 			"dev": true,
 			"bin": {
 				"regexp-tree": "bin/regexp-tree"
@@ -3642,9 +3535,9 @@
 			}
 		},
 		"node_modules/semver": {
-			"version": "7.5.4",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-			"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+			"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
 			"dev": true,
 			"dependencies": {
 				"lru-cache": "^6.0.0"
@@ -3702,16 +3595,26 @@
 				"spdx-license-ids": "^3.0.0"
 			}
 		},
+		"node_modules/spdx-correct/node_modules/spdx-expression-parse": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"dev": true,
+			"dependencies": {
+				"spdx-exceptions": "^2.1.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
 		"node_modules/spdx-exceptions": {
-			"version": "2.4.0",
-			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz",
-			"integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==",
+			"version": "2.5.0",
+			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+			"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
 			"dev": true
 		},
 		"node_modules/spdx-expression-parse": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
-			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+			"integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
 			"dev": true,
 			"dependencies": {
 				"spdx-exceptions": "^2.1.0",
@@ -3921,9 +3824,9 @@
 			}
 		},
 		"node_modules/typescript": {
-			"version": "5.3.3",
-			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
-			"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+			"version": "5.4.5",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+			"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
 			"dev": true,
 			"peer": true,
 			"bin": {
@@ -3957,9 +3860,9 @@
 			}
 		},
 		"node_modules/update-browserslist-db": {
-			"version": "1.0.11",
-			"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
-			"integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+			"version": "1.0.13",
+			"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+			"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
 			"dev": true,
 			"funding": [
 				{
@@ -4011,22 +3914,32 @@
 				"spdx-expression-parse": "^3.0.0"
 			}
 		},
+		"node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"dev": true,
+			"dependencies": {
+				"spdx-exceptions": "^2.1.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
 		"node_modules/vue-eslint-parser": {
-			"version": "8.3.0",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
-			"integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==",
+			"version": "9.4.2",
+			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+			"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
 			"dev": true,
 			"dependencies": {
-				"debug": "^4.3.2",
-				"eslint-scope": "^7.0.0",
-				"eslint-visitor-keys": "^3.1.0",
-				"espree": "^9.0.0",
+				"debug": "^4.3.4",
+				"eslint-scope": "^7.1.1",
+				"eslint-visitor-keys": "^3.3.0",
+				"espree": "^9.3.1",
 				"esquery": "^1.4.0",
 				"lodash": "^4.17.21",
-				"semver": "^7.3.5"
+				"semver": "^7.3.6"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/mysticatea"
@@ -4035,18 +3948,6 @@
 				"eslint": ">=6.0.0"
 			}
 		},
-		"node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": {
-			"version": "3.4.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
-			"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
 		"node_modules/which": {
 			"version": "2.0.2",
 			"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -4180,10 +4081,13 @@
 			"dev": true
 		},
 		"node_modules/yaml": {
-			"version": "2.3.4",
-			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
-			"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
+			"version": "2.4.1",
+			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
+			"integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
 			"dev": true,
+			"bin": {
+				"yaml": "bin.mjs"
+			},
 			"engines": {
 				"node": ">= 14"
 			}
@@ -4205,18 +4109,6 @@
 				"url": "https://github.com/sponsors/ota-meshi"
 			}
 		},
-		"node_modules/yaml-eslint-parser/node_modules/eslint-visitor-keys": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-			"dev": true,
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"funding": {
-				"url": "https://opencollective.com/eslint"
-			}
-		},
 		"node_modules/yargs": {
 			"version": "13.3.2",
 			"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
@@ -4280,26 +4172,13 @@
 			"dev": true
 		},
 		"@babel/code-frame": {
-			"version": "7.23.5",
-			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
-			"integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+			"integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
 			"dev": true,
 			"requires": {
-				"@babel/highlight": "^7.23.4",
-				"chalk": "^2.4.2"
-			},
-			"dependencies": {
-				"chalk": {
-					"version": "2.4.2",
-					"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-					"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-					"dev": true,
-					"requires": {
-						"ansi-styles": "^3.2.1",
-						"escape-string-regexp": "^1.0.5",
-						"supports-color": "^5.3.0"
-					}
-				}
+				"@babel/highlight": "^7.24.2",
+				"picocolors": "^1.0.0"
 			}
 		},
 		"@babel/helper-validator-identifier": {
@@ -4309,14 +4188,15 @@
 			"dev": true
 		},
 		"@babel/highlight": {
-			"version": "7.23.4",
-			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
-			"integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
+			"integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
 			"dev": true,
 			"requires": {
 				"@babel/helper-validator-identifier": "^7.22.20",
 				"chalk": "^2.4.2",
-				"js-tokens": "^4.0.0"
+				"js-tokens": "^4.0.0",
+				"picocolors": "^1.0.0"
 			},
 			"dependencies": {
 				"chalk": {
@@ -4339,12 +4219,12 @@
 			"dev": true
 		},
 		"@es-joy/jsdoccomment": {
-			"version": "0.37.1",
-			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.37.1.tgz",
-			"integrity": "sha512-5vxWJ1gEkEF0yRd0O+uK6dHJf7adrxwQSX8PuRiPfFSAbNLnY0ZJfXaZucoz14Jj2N11xn2DnlEPwWRpYpvRjg==",
+			"version": "0.42.0",
+			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz",
+			"integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==",
 			"dev": true,
 			"requires": {
-				"comment-parser": "1.3.1",
+				"comment-parser": "1.4.1",
 				"esquery": "^1.5.0",
 				"jsdoc-type-pratt-parser": "~4.0.0"
 			}
@@ -4356,14 +4236,6 @@
 			"dev": true,
 			"requires": {
 				"eslint-visitor-keys": "^3.3.0"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.3.0",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-					"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-					"dev": true
-				}
 			}
 		},
 		"@eslint-community/regexpp": {
@@ -4401,9 +4273,9 @@
 			}
 		},
 		"@eslint/js": {
-			"version": "8.56.0",
-			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
-			"integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+			"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
 			"dev": true
 		},
 		"@humanwhocodes/config-array": {
@@ -4516,9 +4388,9 @@
 			"dev": true
 		},
 		"@types/semver": {
-			"version": "7.5.6",
-			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz",
-			"integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==",
+			"version": "7.5.8",
+			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+			"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
 			"dev": true
 		},
 		"@typescript-eslint/scope-manager": {
@@ -4594,14 +4466,6 @@
 			"requires": {
 				"@typescript-eslint/types": "5.62.0",
 				"eslint-visitor-keys": "^3.3.0"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				}
 			}
 		},
 		"@ungap/structured-clone": {
@@ -4768,21 +4632,21 @@
 			"dev": true
 		},
 		"browserslist": {
-			"version": "4.21.10",
-			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
-			"integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==",
+			"version": "4.23.0",
+			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+			"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
 			"dev": true,
 			"requires": {
-				"caniuse-lite": "^1.0.30001517",
-				"electron-to-chromium": "^1.4.477",
-				"node-releases": "^2.0.13",
-				"update-browserslist-db": "^1.0.11"
+				"caniuse-lite": "^1.0.30001587",
+				"electron-to-chromium": "^1.4.668",
+				"node-releases": "^2.0.14",
+				"update-browserslist-db": "^1.0.13"
 			}
 		},
 		"browserslist-config-wikimedia": {
-			"version": "0.5.1",
-			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.5.1.tgz",
-			"integrity": "sha512-jf532fUf/gaxiKdHgGCQUT552P5up3RpG+CzLixOQBJ5FwDmYQSRLYHCFUA9s3KMOHh4P3xVp+NUaGNxvtoT9g==",
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.6.1.tgz",
+			"integrity": "sha512-F3O+12ud7ZwBaiB/RZIMGDgz3nEuXz8RhtdPB4Lkd/WVP5Vy77EqBWRMz4vJ64x8LTTH3BOaHCD2ZuUcgShqyQ==",
 			"dev": true
 		},
 		"builtin-modules": {
@@ -4813,9 +4677,9 @@
 			"dev": true
 		},
 		"caniuse-lite": {
-			"version": "1.0.30001583",
-			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001583.tgz",
-			"integrity": "sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==",
+			"version": "1.0.30001611",
+			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001611.tgz",
+			"integrity": "sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==",
 			"dev": true
 		},
 		"catharsis": {
@@ -4915,9 +4779,9 @@
 			}
 		},
 		"ci-info": {
-			"version": "3.9.0",
-			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
-			"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz",
+			"integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==",
 			"dev": true
 		},
 		"clean-regexp": {
@@ -4973,9 +4837,9 @@
 			"dev": true
 		},
 		"comment-parser": {
-			"version": "1.3.1",
-			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
-			"integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+			"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
 			"dev": true
 		},
 		"concat-map": {
@@ -4991,6 +4855,15 @@
 			"dev": true,
 			"optional": true
 		},
+		"core-js-compat": {
+			"version": "3.37.0",
+			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz",
+			"integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==",
+			"dev": true,
+			"requires": {
+				"browserslist": "^4.23.0"
+			}
+		},
 		"cross-spawn": {
 			"version": "7.0.3",
 			"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -5078,9 +4951,9 @@
 			"dev": true
 		},
 		"electron-to-chromium": {
-			"version": "1.4.499",
-			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.499.tgz",
-			"integrity": "sha512-0NmjlYBLKVHva4GABWAaHuPJolnDuL0AhV3h1hES6rcLCWEIbRL6/8TghfsVwkx6TEroQVdliX7+aLysUpKvjw==",
+			"version": "1.4.740",
+			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.740.tgz",
+			"integrity": "sha512-Yvg5i+iyv7Xm18BRdVPVm8lc7kgxM3r6iwqCH2zB7QZy1kZRNmd0Zqm0zcD9XoFREE5/5rwIuIAOT+/mzGcnZg==",
 			"dev": true
 		},
 		"emoji-regex": {
@@ -5135,9 +5008,9 @@
 			}
 		},
 		"escalade": {
-			"version": "3.1.1",
-			"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-			"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+			"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
 			"dev": true
 		},
 		"escape-string-regexp": {
@@ -5147,16 +5020,16 @@
 			"dev": true
 		},
 		"eslint": {
-			"version": "8.56.0",
-			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
-			"integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+			"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
 			"dev": true,
 			"requires": {
 				"@eslint-community/eslint-utils": "^4.2.0",
 				"@eslint-community/regexpp": "^4.6.1",
 				"@eslint/eslintrc": "^2.1.4",
-				"@eslint/js": "8.56.0",
-				"@humanwhocodes/config-array": "^0.11.13",
+				"@eslint/js": "8.57.0",
+				"@humanwhocodes/config-array": "^0.11.14",
 				"@humanwhocodes/module-importer": "^1.0.1",
 				"@nodelib/fs.walk": "^1.2.8",
 				"@ungap/structured-clone": "^1.2.0",
@@ -5198,12 +5071,6 @@
 					"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
 					"dev": true
 				},
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				},
 				"find-up": {
 					"version": "5.0.0",
 					"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -5268,73 +5135,37 @@
 			}
 		},
 		"eslint-compat-utils": {
-			"version": "0.1.2",
-			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz",
-			"integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==",
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz",
+			"integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==",
 			"dev": true,
-			"requires": {}
+			"requires": {
+				"semver": "^7.5.4"
+			}
 		},
 		"eslint-config-wikimedia": {
-			"version": "0.26.0",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.26.0.tgz",
-			"integrity": "sha512-TAXTySls9k3oWs754rIjlcd9PBLvYeMvjqjiuU8u4gweu0UDgBJGslf+zcvVNXEooAtyLZdENjrzDDjG8ssS7Q==",
+			"version": "0.27.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.27.0.tgz",
+			"integrity": "sha512-KkZ54+MUnggz17C/RCEMXQSpiiqZRF7p9fjrz4phaaeKlTrjg0B+QbM5zcDWcjGiAWaJUptHaH17+RZldadkUw==",
 			"dev": true,
 			"requires": {
-				"browserslist-config-wikimedia": "^0.5.1",
-				"eslint": "^8.53.0",
+				"browserslist-config-wikimedia": "^0.6.1",
+				"eslint": "^8.57.0",
 				"eslint-plugin-compat": "^4.2.0",
-				"eslint-plugin-es-x": "^7.3.0",
-				"eslint-plugin-jest": "^27.6.0",
-				"eslint-plugin-jsdoc": "^42.0.0",
+				"eslint-plugin-es-x": "^7.6.0",
+				"eslint-plugin-jest": "^27.9.0",
+				"eslint-plugin-jsdoc": "48.2.1",
 				"eslint-plugin-json-es": "^1.5.7",
-				"eslint-plugin-mediawiki": "^0.5.0",
-				"eslint-plugin-mocha": "^10.2.0",
-				"eslint-plugin-n": "^16.0.1",
+				"eslint-plugin-mediawiki": "^0.6.0",
+				"eslint-plugin-mocha": "^10.4.1",
+				"eslint-plugin-n": "^16.6.2",
 				"eslint-plugin-no-jquery": "^2.7.0",
-				"eslint-plugin-qunit": "^7.3.4",
+				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
-				"eslint-plugin-unicorn": "^47.0.0",
-				"eslint-plugin-vue": "^9.18.1",
-				"eslint-plugin-wdio": "^7.19.4",
-				"eslint-plugin-yml": "^1.10.0"
-			},
-			"dependencies": {
-				"eslint-plugin-vue": {
-					"version": "9.21.1",
-					"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz",
-					"integrity": "sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==",
-					"dev": true,
-					"requires": {
-						"@eslint-community/eslint-utils": "^4.4.0",
-						"natural-compare": "^1.4.0",
-						"nth-check": "^2.1.1",
-						"postcss-selector-parser": "^6.0.13",
-						"semver": "^7.5.4",
-						"vue-eslint-parser": "^9.4.2",
-						"xml-name-validator": "^4.0.0"
-					}
-				},
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				},
-				"vue-eslint-parser": {
-					"version": "9.4.2",
-					"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
-					"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
-					"dev": true,
-					"requires": {
-						"debug": "^4.3.4",
-						"eslint-scope": "^7.1.1",
-						"eslint-visitor-keys": "^3.3.0",
-						"espree": "^9.3.1",
-						"esquery": "^1.4.0",
-						"lodash": "^4.17.21",
-						"semver": "^7.3.6"
-					}
-				}
+				"eslint-plugin-unicorn": "^51.0.1",
+				"eslint-plugin-vue": "^9.23.0",
+				"eslint-plugin-wdio": "^8.24.12",
+				"eslint-plugin-yml": "^1.13.2"
 			}
 		},
 		"eslint-plugin-compat": {
@@ -5398,39 +5229,40 @@
 			}
 		},
 		"eslint-plugin-es-x": {
-			"version": "7.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz",
-			"integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz",
+			"integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==",
 			"dev": true,
 			"requires": {
 				"@eslint-community/eslint-utils": "^4.1.2",
 				"@eslint-community/regexpp": "^4.6.0",
-				"eslint-compat-utils": "^0.1.2"
+				"eslint-compat-utils": "^0.5.0"
 			}
 		},
 		"eslint-plugin-jest": {
-			"version": "27.6.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.6.3.tgz",
-			"integrity": "sha512-+YsJFVH6R+tOiO3gCJon5oqn4KWc+mDq2leudk8mrp8RFubLOo9CVyi3cib4L7XMpxExmkmBZQTPDYVBzgpgOA==",
+			"version": "27.9.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz",
+			"integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==",
 			"dev": true,
 			"requires": {
 				"@typescript-eslint/utils": "^5.10.0"
 			}
 		},
 		"eslint-plugin-jsdoc": {
-			"version": "42.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-42.0.0.tgz",
-			"integrity": "sha512-qXYr45G8atPKowZbIOdmABukMzu9IMjAlj6j5Fe0iuUItznWSXUDiBj57ejXcbt8bkPrg83333nuz+cqGKFgcQ==",
+			"version": "48.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz",
+			"integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==",
 			"dev": true,
 			"requires": {
-				"@es-joy/jsdoccomment": "~0.37.0",
+				"@es-joy/jsdoccomment": "~0.42.0",
 				"are-docs-informative": "^0.0.2",
-				"comment-parser": "1.3.1",
+				"comment-parser": "1.4.1",
 				"debug": "^4.3.4",
 				"escape-string-regexp": "^4.0.0",
 				"esquery": "^1.5.0",
-				"semver": "^7.3.8",
-				"spdx-expression-parse": "^3.0.1"
+				"is-builtin-module": "^3.2.1",
+				"semver": "^7.6.0",
+				"spdx-expression-parse": "^4.0.0"
 			},
 			"dependencies": {
 				"escape-string-regexp": {
@@ -5449,33 +5281,26 @@
 			"requires": {
 				"eslint-visitor-keys": "^3.3.0",
 				"espree": "^9.3.1"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.3.0",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-					"integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-					"dev": true
-				}
 			}
 		},
 		"eslint-plugin-mediawiki": {
-			"version": "0.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.5.0.tgz",
-			"integrity": "sha512-rjkHFyv3VDan/dmu7YpD1Rl9h64NOlz4mqqesRN316R+571+ymmb6lXVOdNMbT8H1iPhmtHc+nijVLVkn7pYDw==",
+			"version": "0.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.6.0.tgz",
+			"integrity": "sha512-a2Zm18N5nPyflBajM2ZWATxucIpYPEmOSjFzUR1OBH3hAL0GY9fx1mpezEwzqAQ862d+kPkolgQOzktnZe8nKA==",
 			"dev": true,
 			"requires": {
-				"eslint-plugin-vue": "^8.7.1",
+				"eslint-plugin-vue": "^9.23.0",
 				"upath": "^2.0.1"
 			}
 		},
 		"eslint-plugin-mocha": {
-			"version": "10.2.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.2.0.tgz",
-			"integrity": "sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ==",
+			"version": "10.4.2",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.2.tgz",
+			"integrity": "sha512-cur4dVYnSEWTBwdqIBQFxa/9siAhesu0TX+lbJ4ClE9j0eNMNe6BSx3vkFFNz6tGoveyMyELFXa30f3fvuAVDg==",
 			"dev": true,
 			"requires": {
 				"eslint-utils": "^3.0.0",
+				"globals": "^13.24.0",
 				"rambda": "^7.4.0"
 			}
 		},
@@ -5517,9 +5342,9 @@
 			"requires": {}
 		},
 		"eslint-plugin-qunit": {
-			"version": "7.3.4",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.3.4.tgz",
-			"integrity": "sha512-EbDM0zJerH9zVdUswMJpcFF7wrrpvsGuYfNexUpa5hZkkdFhaFcX+yD+RSK4Nrauw4psMGlcqeWUMhaVo+Manw==",
+			"version": "8.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-8.1.1.tgz",
+			"integrity": "sha512-j3xhiAf2Wvr8Dfwl5T6tlJ+F55vqYE9ZdAHUOTzq1lGerYrXzOS46RvK4SSWug2D8sl3ZYr2lA4/hgVXgLloxw==",
 			"dev": true,
 			"requires": {
 				"eslint-utils": "^3.0.0",
@@ -5536,71 +5361,62 @@
 			}
 		},
 		"eslint-plugin-unicorn": {
-			"version": "47.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-47.0.0.tgz",
-			"integrity": "sha512-ivB3bKk7fDIeWOUmmMm9o3Ax9zbMz1Bsza/R2qm46ufw4T6VBFBaJIR1uN3pCKSmSXm8/9Nri8V+iUut1NhQGA==",
+			"version": "51.0.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz",
+			"integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==",
 			"dev": true,
 			"requires": {
-				"@babel/helper-validator-identifier": "^7.19.1",
+				"@babel/helper-validator-identifier": "^7.22.20",
 				"@eslint-community/eslint-utils": "^4.4.0",
-				"ci-info": "^3.8.0",
+				"@eslint/eslintrc": "^2.1.4",
+				"ci-info": "^4.0.0",
 				"clean-regexp": "^1.0.0",
+				"core-js-compat": "^3.34.0",
 				"esquery": "^1.5.0",
 				"indent-string": "^4.0.0",
 				"is-builtin-module": "^3.2.1",
 				"jsesc": "^3.0.2",
-				"lodash": "^4.17.21",
 				"pluralize": "^8.0.0",
 				"read-pkg-up": "^7.0.1",
-				"regexp-tree": "^0.1.24",
+				"regexp-tree": "^0.1.27",
 				"regjsparser": "^0.10.0",
-				"safe-regex": "^2.1.1",
-				"semver": "^7.3.8",
+				"semver": "^7.5.4",
 				"strip-indent": "^3.0.0"
 			}
 		},
 		"eslint-plugin-vue": {
-			"version": "8.7.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz",
-			"integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==",
+			"version": "9.25.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz",
+			"integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==",
 			"dev": true,
 			"requires": {
-				"eslint-utils": "^3.0.0",
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"globals": "^13.24.0",
 				"natural-compare": "^1.4.0",
-				"nth-check": "^2.0.1",
-				"postcss-selector-parser": "^6.0.9",
-				"semver": "^7.3.5",
-				"vue-eslint-parser": "^8.0.1"
+				"nth-check": "^2.1.1",
+				"postcss-selector-parser": "^6.0.15",
+				"semver": "^7.6.0",
+				"vue-eslint-parser": "^9.4.2",
+				"xml-name-validator": "^4.0.0"
 			}
 		},
 		"eslint-plugin-wdio": {
-			"version": "7.25.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.25.3.tgz",
-			"integrity": "sha512-2zbYwV14Md9FNlyhaIILVGPB6w4bu2eJdOTywDUs2Qy4ebcQNwrxB0qCaf7Rm4O+T0Ir+tdYHYBBfbDocSLKng==",
+			"version": "8.24.12",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-8.24.12.tgz",
+			"integrity": "sha512-OmzGteXFOQnJDdkTNnTfksaVa18WlFCyeLjZXHvDpkbomLWAg9wc296Pr0wnTCagqNj8qfEHpy+N2XVew5VCMA==",
 			"dev": true
 		},
 		"eslint-plugin-yml": {
-			"version": "1.12.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.12.2.tgz",
-			"integrity": "sha512-hvS9p08FhPT7i/ynwl7/Wt7ke7Rf4P2D6fT8lZlL43peZDTsHtH2A0SIFQ7Kt7+mJ6if6P+FX3iJhMkdnxQwpg==",
+			"version": "1.14.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz",
+			"integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==",
 			"dev": true,
 			"requires": {
 				"debug": "^4.3.2",
-				"eslint-compat-utils": "^0.4.0",
+				"eslint-compat-utils": "^0.5.0",
 				"lodash": "^4.17.21",
 				"natural-compare": "^1.4.0",
 				"yaml-eslint-parser": "^1.2.1"
-			},
-			"dependencies": {
-				"eslint-compat-utils": {
-					"version": "0.4.1",
-					"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.4.1.tgz",
-					"integrity": "sha512-5N7ZaJG5pZxUeNNJfUchurLVrunD1xJvyg5kYOIVF8kg1f3ajTikmAu/5fZ9w100omNPOoMjngRszh/Q/uFGMg==",
-					"dev": true,
-					"requires": {
-						"semver": "^7.5.4"
-					}
-				}
 			}
 		},
 		"eslint-scope": {
@@ -5620,12 +5436,20 @@
 			"dev": true,
 			"requires": {
 				"eslint-visitor-keys": "^2.0.0"
+			},
+			"dependencies": {
+				"eslint-visitor-keys": {
+					"version": "2.1.0",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+					"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+					"dev": true
+				}
 			}
 		},
 		"eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+			"version": "3.4.3",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+			"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
 			"dev": true
 		},
 		"espree": {
@@ -5637,14 +5461,6 @@
 				"acorn": "^8.9.0",
 				"acorn-jsx": "^5.3.2",
 				"eslint-visitor-keys": "^3.4.1"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				}
 			}
 		},
 		"esprima": {
@@ -6521,9 +6337,9 @@
 			}
 		},
 		"node-releases": {
-			"version": "2.0.13",
-			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
-			"integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+			"version": "2.0.14",
+			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+			"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
 			"dev": true
 		},
 		"normalize-package-data": {
@@ -6730,9 +6546,9 @@
 			"dev": true
 		},
 		"postcss-selector-parser": {
-			"version": "6.0.15",
-			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
-			"integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
+			"version": "6.0.16",
+			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
+			"integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
 			"dev": true,
 			"requires": {
 				"cssesc": "^3.0.0",
@@ -6855,9 +6671,9 @@
 			}
 		},
 		"regexp-tree": {
-			"version": "0.1.24",
-			"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz",
-			"integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==",
+			"version": "0.1.27",
+			"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
+			"integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==",
 			"dev": true
 		},
 		"regjsparser": {
@@ -6961,9 +6777,9 @@
 			}
 		},
 		"semver": {
-			"version": "7.5.4",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-			"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+			"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
 			"dev": true,
 			"requires": {
 				"lru-cache": "^6.0.0"
@@ -7004,18 +6820,30 @@
 			"requires": {
 				"spdx-expression-parse": "^3.0.0",
 				"spdx-license-ids": "^3.0.0"
+			},
+			"dependencies": {
+				"spdx-expression-parse": {
+					"version": "3.0.1",
+					"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+					"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+					"dev": true,
+					"requires": {
+						"spdx-exceptions": "^2.1.0",
+						"spdx-license-ids": "^3.0.0"
+					}
+				}
 			}
 		},
 		"spdx-exceptions": {
-			"version": "2.4.0",
-			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz",
-			"integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==",
+			"version": "2.5.0",
+			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+			"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
 			"dev": true
 		},
 		"spdx-expression-parse": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
-			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+			"integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
 			"dev": true,
 			"requires": {
 				"spdx-exceptions": "^2.1.0",
@@ -7179,9 +7007,9 @@
 			"dev": true
 		},
 		"typescript": {
-			"version": "5.3.3",
-			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
-			"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+			"version": "5.4.5",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+			"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
 			"dev": true,
 			"peer": true
 		},
@@ -7204,9 +7032,9 @@
 			"dev": true
 		},
 		"update-browserslist-db": {
-			"version": "1.0.11",
-			"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
-			"integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+			"version": "1.0.13",
+			"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+			"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
 			"dev": true,
 			"requires": {
 				"escalade": "^3.1.1",
@@ -7236,29 +7064,33 @@
 			"requires": {
 				"spdx-correct": "^3.0.0",
 				"spdx-expression-parse": "^3.0.0"
+			},
+			"dependencies": {
+				"spdx-expression-parse": {
+					"version": "3.0.1",
+					"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+					"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+					"dev": true,
+					"requires": {
+						"spdx-exceptions": "^2.1.0",
+						"spdx-license-ids": "^3.0.0"
+					}
+				}
 			}
 		},
 		"vue-eslint-parser": {
-			"version": "8.3.0",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
-			"integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==",
+			"version": "9.4.2",
+			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+			"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
 			"dev": true,
 			"requires": {
-				"debug": "^4.3.2",
-				"eslint-scope": "^7.0.0",
-				"eslint-visitor-keys": "^3.1.0",
-				"espree": "^9.0.0",
+				"debug": "^4.3.4",
+				"eslint-scope": "^7.1.1",
+				"eslint-visitor-keys": "^3.3.0",
+				"espree": "^9.3.1",
 				"esquery": "^1.4.0",
 				"lodash": "^4.17.21",
-				"semver": "^7.3.5"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.4.0",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
-					"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
-					"dev": true
-				}
+				"semver": "^7.3.6"
 			}
 		},
 		"which": {
@@ -7371,9 +7203,9 @@
 			"dev": true
 		},
 		"yaml": {
-			"version": "2.3.4",
-			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz",
-			"integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==",
+			"version": "2.4.1",
+			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
+			"integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
 			"dev": true
 		},
 		"yaml-eslint-parser": {
@@ -7385,14 +7217,6 @@
 				"eslint-visitor-keys": "^3.0.0",
 				"lodash": "^4.17.21",
 				"yaml": "^2.0.0"
-			},
-			"dependencies": {
-				"eslint-visitor-keys": {
-					"version": "3.4.3",
-					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-					"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
-					"dev": true
-				}
 			}
 		},
 		"yargs": {
diff --git a/package.json b/package.json
index 9c17e48..b5f34d6 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
 		"babybird": "^0.0.1",
 		"chai": "^4.2.0",
 		"domino": "^2.1.0",
-		"eslint-config-wikimedia": "0.26.0",
+		"eslint-config-wikimedia": "0.27.0",
 		"jsdoc": "4.0.2",
 		"jsdoc-wmf-theme": "0.0.12",
 		"mocha": "^7.1.2",
diff --git a/tools/build-langconv-fst.js b/tools/build-langconv-fst.js
index a5abb9d..36835c7 100755
--- a/tools/build-langconv-fst.js
+++ b/tools/build-langconv-fst.js
@@ -8,6 +8,7 @@
  * The input is expected to be a "byte machine", that is, unicode code units
  * have already been decomposed into code points corresponding to UTF-8
  * bytes.  Symbols used in the ATT file:
+ *
  *  @0@      Epsilon ("no character").  Used in both input and output edges;
  *           as an input edge this introduced nondeterminism.
  *  <hh>    The input byte with hexadecimal value <hh>
-- 
2.39.2


--- end ---

composer dependencies

Dependencies
Development dependencies

npm dependencies

Development dependencies

Logs

Source code is licensed under the AGPL.