mediawiki/extensions/PageOwnership: main (log #2136480)

sourcepatches

This run took 55 seconds.

From 02ac833be09750befccbb0f0fe66a75618107d0c Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Sat, 4 Oct 2025 03:11:06 +0000
Subject: [PATCH] build: Updating dependencies
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

composer:
* mediawiki/mediawiki-codesniffer: 47.0.0 → 48.0.0
  The following sniffs are failing and were disabled:
  * MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation
  * MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter
  * MediaWiki.Commenting.CommentBeforeClass.SpacingAfter

npm:
* eslint-config-wikimedia: 0.28.2 → 0.31.0
  The following rules are failing and were disabled:
  * no-jquery/no-done-fail

Change-Id: I9220f62e3d042bcc422b6d549128fb3de1378678
---
 .eslintrc.json                                |   3 +-
 .phpcs.xml                                    |   3 +
 composer.json                                 |   2 +-
 package-lock.json                             | 762 +++++++++++++++---
 package.json                                  |   2 +-
 resources/PageOwnership.js                    |   2 +-
 resources/PageOwnershipPermissions.js         |   6 +-
 ...mw.widgets.GroupsUsersMultiselectWidget.js |   2 +-
 .../mw.widgets.MultiToggleButtonWidget.js     |   2 +-
 9 files changed, 681 insertions(+), 103 deletions(-)

diff --git a/.eslintrc.json b/.eslintrc.json
index 5735096..85c7e39 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -8,6 +8,7 @@
 	"rules": {
 		"camelcase": "off",
 		"no-var": "off",
-		"no-jquery/no-global-selector": "warn"
+		"no-jquery/no-global-selector": "warn",
+		"no-jquery/no-done-fail": "warn"
 	}
 }
diff --git a/.phpcs.xml b/.phpcs.xml
index 579cee8..4e089bc 100644
--- a/.phpcs.xml
+++ b/.phpcs.xml
@@ -4,6 +4,9 @@
 		<exclude name="Generic.Files.LineLength.TooLong" />
 		<exclude name="MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName" />
 		<exclude name="Generic.Files.OneObjectStructurePerFile.MultipleFound" />
+		<exclude name="MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation" />
+		<exclude name="MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter" />
+		<exclude name="MediaWiki.Commenting.CommentBeforeClass.SpacingAfter" />
 	</rule>
 	<file>.</file>
 	<arg name="extensions" value="php"/>
diff --git a/composer.json b/composer.json
index 481cac4..996ca0f 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
 {
 	"require-dev": {
-		"mediawiki/mediawiki-codesniffer": "47.0.0",
+		"mediawiki/mediawiki-codesniffer": "48.0.0",
 		"mediawiki/minus-x": "1.1.3",
 		"php-parallel-lint/php-console-highlighter": "1.0.0",
 		"php-parallel-lint/php-parallel-lint": "1.4.0"
diff --git a/package-lock.json b/package-lock.json
index 28f934d..728d3f4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
 		"": {
 			"name": "PageOwnership",
 			"devDependencies": {
-				"eslint-config-wikimedia": "0.28.2",
+				"eslint-config-wikimedia": "0.31.0",
 				"grunt": "1.6.1",
 				"grunt-banana-checker": "0.13.0",
 				"grunt-eslint": "24.3.0",
@@ -236,16 +236,19 @@
 			}
 		},
 		"node_modules/@eslint-community/eslint-utils": {
-			"version": "4.4.0",
-			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
-			"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+			"version": "4.9.0",
+			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+			"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
 			"dev": true,
 			"dependencies": {
-				"eslint-visitor-keys": "^3.3.0"
+				"eslint-visitor-keys": "^3.4.3"
 			},
 			"engines": {
 				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
 			},
+			"funding": {
+				"url": "https://opencollective.com/eslint"
+			},
 			"peerDependencies": {
 				"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
 			}
@@ -367,6 +370,225 @@
 				"node": ">= 8"
 			}
 		},
+		"node_modules/@stylistic/eslint-plugin": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-3.1.0.tgz",
+			"integrity": "sha512-pA6VOrOqk0+S8toJYhQGv2MWpQQR0QpeUo9AhNkC49Y26nxBQ/nH1rta9bUU1rPw2fJ1zZEMV5oCX5AazT7J2g==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/utils": "^8.13.0",
+				"eslint-visitor-keys": "^4.2.0",
+				"espree": "^10.3.0",
+				"estraverse": "^5.3.0",
+				"picomatch": "^4.0.2"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"peerDependencies": {
+				"eslint": ">=8.40.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/project-service": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.45.0.tgz",
+			"integrity": "sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/tsconfig-utils": "^8.45.0",
+				"@typescript-eslint/types": "^8.45.0",
+				"debug": "^4.3.4"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <6.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz",
+			"integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.45.0",
+				"@typescript-eslint/visitor-keys": "8.45.0"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz",
+			"integrity": "sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <6.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/types": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz",
+			"integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz",
+			"integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/project-service": "8.45.0",
+				"@typescript-eslint/tsconfig-utils": "8.45.0",
+				"@typescript-eslint/types": "8.45.0",
+				"@typescript-eslint/visitor-keys": "8.45.0",
+				"debug": "^4.3.4",
+				"fast-glob": "^3.3.2",
+				"is-glob": "^4.0.3",
+				"minimatch": "^9.0.4",
+				"semver": "^7.6.0",
+				"ts-api-utils": "^2.1.0"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <6.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/utils": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz",
+			"integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==",
+			"dev": true,
+			"dependencies": {
+				"@eslint-community/eslint-utils": "^4.7.0",
+				"@typescript-eslint/scope-manager": "8.45.0",
+				"@typescript-eslint/types": "8.45.0",
+				"@typescript-eslint/typescript-estree": "8.45.0"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <6.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz",
+			"integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.45.0",
+				"eslint-visitor-keys": "^4.2.1"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/brace-expansion": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+			"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+			"dev": true,
+			"dependencies": {
+				"balanced-match": "^1.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": {
+			"version": "4.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+			"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"url": "https://opencollective.com/eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/espree": {
+			"version": "10.4.0",
+			"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+			"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+			"dev": true,
+			"dependencies": {
+				"acorn": "^8.15.0",
+				"acorn-jsx": "^5.3.2",
+				"eslint-visitor-keys": "^4.2.1"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"url": "https://opencollective.com/eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/minimatch": {
+			"version": "9.0.5",
+			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+			"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+			"dev": true,
+			"dependencies": {
+				"brace-expansion": "^2.0.1"
+			},
+			"engines": {
+				"node": ">=16 || 14 >=14.17"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/isaacs"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/picomatch": {
+			"version": "4.0.3",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+			"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+			"dev": true,
+			"engines": {
+				"node": ">=12"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
+		},
 		"node_modules/@stylistic/stylelint-config": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-2.0.0.tgz",
@@ -447,14 +669,132 @@
 			"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
 			"dev": true
 		},
+		"node_modules/@typescript-eslint/eslint-plugin": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz",
+			"integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==",
+			"dev": true,
+			"dependencies": {
+				"@eslint-community/regexpp": "^4.10.0",
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/type-utils": "8.35.1",
+				"@typescript-eslint/utils": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
+				"graphemer": "^1.4.0",
+				"ignore": "^7.0.0",
+				"natural-compare": "^1.4.0",
+				"ts-api-utils": "^2.1.0"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"@typescript-eslint/parser": "^8.35.1",
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.9.0"
+			}
+		},
+		"node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+			"version": "7.0.5",
+			"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+			"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+			"dev": true,
+			"engines": {
+				"node": ">= 4"
+			}
+		},
+		"node_modules/@typescript-eslint/parser": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz",
+			"integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/typescript-estree": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
+				"debug": "^4.3.4"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.9.0"
+			}
+		},
+		"node_modules/@typescript-eslint/project-service": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz",
+			"integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/tsconfig-utils": "^8.35.1",
+				"@typescript-eslint/types": "^8.35.1",
+				"debug": "^4.3.4"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <5.9.0"
+			}
+		},
 		"node_modules/@typescript-eslint/scope-manager": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz",
-			"integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz",
+			"integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@typescript-eslint/tsconfig-utils": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz",
+			"integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <5.9.0"
+			}
+		},
+		"node_modules/@typescript-eslint/type-utils": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz",
+			"integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==",
 			"dev": true,
 			"dependencies": {
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/visitor-keys": "8.7.0"
+				"@typescript-eslint/typescript-estree": "8.35.1",
+				"@typescript-eslint/utils": "8.35.1",
+				"debug": "^4.3.4",
+				"ts-api-utils": "^2.1.0"
 			},
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -462,12 +802,16 @@
 			"funding": {
 				"type": "opencollective",
 				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.9.0"
 			}
 		},
 		"node_modules/@typescript-eslint/types": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz",
-			"integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz",
+			"integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==",
 			"dev": true,
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -478,19 +822,21 @@
 			}
 		},
 		"node_modules/@typescript-eslint/typescript-estree": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz",
-			"integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz",
+			"integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==",
 			"dev": true,
 			"dependencies": {
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/visitor-keys": "8.7.0",
+				"@typescript-eslint/project-service": "8.35.1",
+				"@typescript-eslint/tsconfig-utils": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
 				"debug": "^4.3.4",
 				"fast-glob": "^3.3.2",
 				"is-glob": "^4.0.3",
 				"minimatch": "^9.0.4",
 				"semver": "^7.6.0",
-				"ts-api-utils": "^1.3.0"
+				"ts-api-utils": "^2.1.0"
 			},
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -499,10 +845,8 @@
 				"type": "opencollective",
 				"url": "https://opencollective.com/typescript-eslint"
 			},
-			"peerDependenciesMeta": {
-				"typescript": {
-					"optional": true
-				}
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <5.9.0"
 			}
 		},
 		"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
@@ -530,15 +874,15 @@
 			}
 		},
 		"node_modules/@typescript-eslint/utils": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz",
-			"integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz",
+			"integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==",
 			"dev": true,
 			"dependencies": {
-				"@eslint-community/eslint-utils": "^4.4.0",
-				"@typescript-eslint/scope-manager": "8.7.0",
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/typescript-estree": "8.7.0"
+				"@eslint-community/eslint-utils": "^4.7.0",
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/typescript-estree": "8.35.1"
 			},
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -548,17 +892,18 @@
 				"url": "https://opencollective.com/typescript-eslint"
 			},
 			"peerDependencies": {
-				"eslint": "^8.57.0 || ^9.0.0"
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.9.0"
 			}
 		},
 		"node_modules/@typescript-eslint/visitor-keys": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz",
-			"integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz",
+			"integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==",
 			"dev": true,
 			"dependencies": {
-				"@typescript-eslint/types": "8.7.0",
-				"eslint-visitor-keys": "^3.4.3"
+				"@typescript-eslint/types": "8.35.1",
+				"eslint-visitor-keys": "^4.2.1"
 			},
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -568,6 +913,18 @@
 				"url": "https://opencollective.com/typescript-eslint"
 			}
 		},
+		"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+			"version": "4.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+			"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.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",
@@ -581,9 +938,9 @@
 			"dev": true
 		},
 		"node_modules/acorn": {
-			"version": "8.12.1",
-			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
-			"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+			"version": "8.15.0",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+			"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
 			"dev": true,
 			"bin": {
 				"acorn": "bin/acorn"
@@ -1388,11 +1745,14 @@
 			}
 		},
 		"node_modules/eslint-config-wikimedia": {
-			"version": "0.28.2",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz",
-			"integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==",
+			"version": "0.31.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.31.0.tgz",
+			"integrity": "sha512-Z/t/zGPdxs/ehxb0EM6THNWAzueT7GtuqzjUvmBpkxcTKzZPJEXWnnpswdj/hgv8Ce8PIeDp0zwQxR4e3c9CIw==",
 			"dev": true,
 			"dependencies": {
+				"@stylistic/eslint-plugin": "^3.1.0",
+				"@typescript-eslint/eslint-plugin": "8.35.1",
+				"@typescript-eslint/parser": "8.35.1",
 				"browserslist-config-wikimedia": "^0.7.0",
 				"eslint": "^8.57.0",
 				"eslint-plugin-compat": "^4.2.0",
@@ -1403,13 +1763,16 @@
 				"eslint-plugin-mediawiki": "^0.7.0",
 				"eslint-plugin-mocha": "^10.4.3",
 				"eslint-plugin-n": "^17.7.0",
-				"eslint-plugin-no-jquery": "^3.0.1",
+				"eslint-plugin-no-jquery": "^3.1.1",
 				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
 				"eslint-plugin-unicorn": "^53.0.0",
 				"eslint-plugin-vue": "^9.26.0",
 				"eslint-plugin-wdio": "^8.24.12",
 				"eslint-plugin-yml": "^1.14.0"
+			},
+			"engines": {
+				"node": ">=18 <25"
 			}
 		},
 		"node_modules/eslint-plugin-compat": {
@@ -1607,9 +1970,9 @@
 			}
 		},
 		"node_modules/eslint-plugin-no-jquery": {
-			"version": "3.0.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz",
-			"integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==",
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz",
+			"integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==",
 			"dev": true,
 			"peerDependencies": {
 				"eslint": ">=8.0.0"
@@ -4577,15 +4940,15 @@
 			}
 		},
 		"node_modules/ts-api-utils": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
-			"integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+			"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
 			"dev": true,
 			"engines": {
-				"node": ">=16"
+				"node": ">=18.12"
 			},
 			"peerDependencies": {
-				"typescript": ">=4.2.0"
+				"typescript": ">=4.8.4"
 			}
 		},
 		"node_modules/type-check": {
@@ -5039,12 +5402,12 @@
 			}
 		},
 		"@eslint-community/eslint-utils": {
-			"version": "4.4.0",
-			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
-			"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+			"version": "4.9.0",
+			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+			"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
 			"dev": true,
 			"requires": {
-				"eslint-visitor-keys": "^3.3.0"
+				"eslint-visitor-keys": "^3.4.3"
 			}
 		},
 		"@eslint-community/regexpp": {
@@ -5131,6 +5494,136 @@
 				"fastq": "^1.6.0"
 			}
 		},
+		"@stylistic/eslint-plugin": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-3.1.0.tgz",
+			"integrity": "sha512-pA6VOrOqk0+S8toJYhQGv2MWpQQR0QpeUo9AhNkC49Y26nxBQ/nH1rta9bUU1rPw2fJ1zZEMV5oCX5AazT7J2g==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/utils": "^8.13.0",
+				"eslint-visitor-keys": "^4.2.0",
+				"espree": "^10.3.0",
+				"estraverse": "^5.3.0",
+				"picomatch": "^4.0.2"
+			},
+			"dependencies": {
+				"@typescript-eslint/project-service": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.45.0.tgz",
+					"integrity": "sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/tsconfig-utils": "^8.45.0",
+						"@typescript-eslint/types": "^8.45.0",
+						"debug": "^4.3.4"
+					}
+				},
+				"@typescript-eslint/scope-manager": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz",
+					"integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/types": "8.45.0",
+						"@typescript-eslint/visitor-keys": "8.45.0"
+					}
+				},
+				"@typescript-eslint/tsconfig-utils": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz",
+					"integrity": "sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==",
+					"dev": true,
+					"requires": {}
+				},
+				"@typescript-eslint/types": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz",
+					"integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==",
+					"dev": true
+				},
+				"@typescript-eslint/typescript-estree": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz",
+					"integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/project-service": "8.45.0",
+						"@typescript-eslint/tsconfig-utils": "8.45.0",
+						"@typescript-eslint/types": "8.45.0",
+						"@typescript-eslint/visitor-keys": "8.45.0",
+						"debug": "^4.3.4",
+						"fast-glob": "^3.3.2",
+						"is-glob": "^4.0.3",
+						"minimatch": "^9.0.4",
+						"semver": "^7.6.0",
+						"ts-api-utils": "^2.1.0"
+					}
+				},
+				"@typescript-eslint/utils": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz",
+					"integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==",
+					"dev": true,
+					"requires": {
+						"@eslint-community/eslint-utils": "^4.7.0",
+						"@typescript-eslint/scope-manager": "8.45.0",
+						"@typescript-eslint/types": "8.45.0",
+						"@typescript-eslint/typescript-estree": "8.45.0"
+					}
+				},
+				"@typescript-eslint/visitor-keys": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz",
+					"integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/types": "8.45.0",
+						"eslint-visitor-keys": "^4.2.1"
+					}
+				},
+				"brace-expansion": {
+					"version": "2.0.2",
+					"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+					"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+					"dev": true,
+					"requires": {
+						"balanced-match": "^1.0.0"
+					}
+				},
+				"eslint-visitor-keys": {
+					"version": "4.2.1",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+					"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+					"dev": true
+				},
+				"espree": {
+					"version": "10.4.0",
+					"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+					"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+					"dev": true,
+					"requires": {
+						"acorn": "^8.15.0",
+						"acorn-jsx": "^5.3.2",
+						"eslint-visitor-keys": "^4.2.1"
+					}
+				},
+				"minimatch": {
+					"version": "9.0.5",
+					"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+					"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+					"dev": true,
+					"requires": {
+						"brace-expansion": "^2.0.1"
+					}
+				},
+				"picomatch": {
+					"version": "4.0.3",
+					"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+					"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+					"dev": true
+				}
+			}
+		},
 		"@stylistic/stylelint-config": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-2.0.0.tgz",
@@ -5198,36 +5691,106 @@
 			"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
 			"dev": true
 		},
+		"@typescript-eslint/eslint-plugin": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz",
+			"integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==",
+			"dev": true,
+			"requires": {
+				"@eslint-community/regexpp": "^4.10.0",
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/type-utils": "8.35.1",
+				"@typescript-eslint/utils": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
+				"graphemer": "^1.4.0",
+				"ignore": "^7.0.0",
+				"natural-compare": "^1.4.0",
+				"ts-api-utils": "^2.1.0"
+			},
+			"dependencies": {
+				"ignore": {
+					"version": "7.0.5",
+					"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+					"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+					"dev": true
+				}
+			}
+		},
+		"@typescript-eslint/parser": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz",
+			"integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/typescript-estree": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
+				"debug": "^4.3.4"
+			}
+		},
+		"@typescript-eslint/project-service": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz",
+			"integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/tsconfig-utils": "^8.35.1",
+				"@typescript-eslint/types": "^8.35.1",
+				"debug": "^4.3.4"
+			}
+		},
 		"@typescript-eslint/scope-manager": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz",
-			"integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz",
+			"integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==",
 			"dev": true,
 			"requires": {
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/visitor-keys": "8.7.0"
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1"
+			}
+		},
+		"@typescript-eslint/tsconfig-utils": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz",
+			"integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==",
+			"dev": true,
+			"requires": {}
+		},
+		"@typescript-eslint/type-utils": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz",
+			"integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/typescript-estree": "8.35.1",
+				"@typescript-eslint/utils": "8.35.1",
+				"debug": "^4.3.4",
+				"ts-api-utils": "^2.1.0"
 			}
 		},
 		"@typescript-eslint/types": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz",
-			"integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz",
+			"integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==",
 			"dev": true
 		},
 		"@typescript-eslint/typescript-estree": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz",
-			"integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz",
+			"integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==",
 			"dev": true,
 			"requires": {
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/visitor-keys": "8.7.0",
+				"@typescript-eslint/project-service": "8.35.1",
+				"@typescript-eslint/tsconfig-utils": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
 				"debug": "^4.3.4",
 				"fast-glob": "^3.3.2",
 				"is-glob": "^4.0.3",
 				"minimatch": "^9.0.4",
 				"semver": "^7.6.0",
-				"ts-api-utils": "^1.3.0"
+				"ts-api-utils": "^2.1.0"
 			},
 			"dependencies": {
 				"brace-expansion": {
@@ -5251,25 +5814,33 @@
 			}
 		},
 		"@typescript-eslint/utils": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz",
-			"integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz",
+			"integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==",
 			"dev": true,
 			"requires": {
-				"@eslint-community/eslint-utils": "^4.4.0",
-				"@typescript-eslint/scope-manager": "8.7.0",
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/typescript-estree": "8.7.0"
+				"@eslint-community/eslint-utils": "^4.7.0",
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/typescript-estree": "8.35.1"
 			}
 		},
 		"@typescript-eslint/visitor-keys": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz",
-			"integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz",
+			"integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==",
 			"dev": true,
 			"requires": {
-				"@typescript-eslint/types": "8.7.0",
-				"eslint-visitor-keys": "^3.4.3"
+				"@typescript-eslint/types": "8.35.1",
+				"eslint-visitor-keys": "^4.2.1"
+			},
+			"dependencies": {
+				"eslint-visitor-keys": {
+					"version": "4.2.1",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+					"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+					"dev": true
+				}
 			}
 		},
 		"@ungap/structured-clone": {
@@ -5285,9 +5856,9 @@
 			"dev": true
 		},
 		"acorn": {
-			"version": "8.12.1",
-			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
-			"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+			"version": "8.15.0",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+			"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
 			"dev": true
 		},
 		"acorn-jsx": {
@@ -5859,11 +6430,14 @@
 			}
 		},
 		"eslint-config-wikimedia": {
-			"version": "0.28.2",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz",
-			"integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==",
+			"version": "0.31.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.31.0.tgz",
+			"integrity": "sha512-Z/t/zGPdxs/ehxb0EM6THNWAzueT7GtuqzjUvmBpkxcTKzZPJEXWnnpswdj/hgv8Ce8PIeDp0zwQxR4e3c9CIw==",
 			"dev": true,
 			"requires": {
+				"@stylistic/eslint-plugin": "^3.1.0",
+				"@typescript-eslint/eslint-plugin": "8.35.1",
+				"@typescript-eslint/parser": "8.35.1",
 				"browserslist-config-wikimedia": "^0.7.0",
 				"eslint": "^8.57.0",
 				"eslint-plugin-compat": "^4.2.0",
@@ -5874,7 +6448,7 @@
 				"eslint-plugin-mediawiki": "^0.7.0",
 				"eslint-plugin-mocha": "^10.4.3",
 				"eslint-plugin-n": "^17.7.0",
-				"eslint-plugin-no-jquery": "^3.0.1",
+				"eslint-plugin-no-jquery": "^3.1.1",
 				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
 				"eslint-plugin-unicorn": "^53.0.0",
@@ -6009,9 +6583,9 @@
 			}
 		},
 		"eslint-plugin-no-jquery": {
-			"version": "3.0.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz",
-			"integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==",
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz",
+			"integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==",
 			"dev": true,
 			"requires": {}
 		},
@@ -8151,9 +8725,9 @@
 			}
 		},
 		"ts-api-utils": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
-			"integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+			"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
 			"dev": true,
 			"requires": {}
 		},
diff --git a/package.json b/package.json
index f459e6e..338f172 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
 		"test": "grunt test"
 	},
 	"devDependencies": {
-		"eslint-config-wikimedia": "0.28.2",
+		"eslint-config-wikimedia": "0.31.0",
 		"grunt": "1.6.1",
 		"grunt-banana-checker": "0.13.0",
 		"grunt-eslint": "24.3.0",
diff --git a/resources/PageOwnership.js b/resources/PageOwnership.js
index f0ff809..0b1c835 100644
--- a/resources/PageOwnership.js
+++ b/resources/PageOwnership.js
@@ -59,7 +59,7 @@ $( () => {
 	function updateCheckboxes( val ) {
 
 		for ( var i in permissions[ val ] ) {
-			$( '#pageownership_form_input_permissions_' + i + ' input' ).prop( 'checked', ( val === default_role && default_permissions.indexOf( i.replace( '_', ' ' ) ) > -1 ? true : permissions[ val ][ i ].checked ) );
+			$( '#pageownership_form_input_permissions_' + i + ' input' ).prop( 'checked', ( val === default_role && default_permissions.includes( i.replace( '_', ' ' ) ) ? true : permissions[ val ][ i ].checked ) );
 			$( '#pageownership_form_input_permissions_' + i + ' input' ).prop( 'disabled', permissions[ val ][ i ].disabled );
 		}
 
diff --git a/resources/PageOwnershipPermissions.js b/resources/PageOwnershipPermissions.js
index 20d9761..2fa1e6f 100644
--- a/resources/PageOwnershipPermissions.js
+++ b/resources/PageOwnershipPermissions.js
@@ -136,11 +136,11 @@ $( () => {
 
 		var options = [];
 		for ( var i in actions ) {
-			if ( action === 'add' && selected.indexOf( i ) !== -1 ) {
+			if ( action === 'add' && selected.includes( i ) ) {
 				continue;
 			}
 
-			if ( action === 'remove' && selected.indexOf( i ) === -1 ) {
+			if ( action === 'remove' && !selected.includes( i ) ) {
 				continue;
 			}
 
@@ -168,7 +168,7 @@ $( () => {
 							messages[ actions[ i ][ ii ] ] :
 							actions[ i ][ ii ],
 						// mw.msg( 'right-' + actions[i][ii] ),
-						selected: selectedItems.indexOf( actions[ i ][ ii ] ) !== -1
+						selected: selectedItems.includes( actions[ i ][ ii ] )
 					} )
 				);
 			}
diff --git a/resources/mw.widgets.GroupsUsersMultiselectWidget.js b/resources/mw.widgets.GroupsUsersMultiselectWidget.js
index a010298..e39a962 100644
--- a/resources/mw.widgets.GroupsUsersMultiselectWidget.js
+++ b/resources/mw.widgets.GroupsUsersMultiselectWidget.js
@@ -204,7 +204,7 @@ config.inputWidget = new OO.ui.TextInputWidget({
 								// Remove usernames, which are already selected from suggestions
 								suggestions = suggestions
 									.map( ( user ) => {
-										if ( selected.indexOf( user.name ) === -1 ) {
+										if ( !selected.includes( user.name ) ) {
 											return new OO.ui.MenuOptionWidget( {
 												data: user.name,
 												label: user.name,
diff --git a/resources/mw.widgets.MultiToggleButtonWidget.js b/resources/mw.widgets.MultiToggleButtonWidget.js
index 03b5da6..d2c2b89 100644
--- a/resources/mw.widgets.MultiToggleButtonWidget.js
+++ b/resources/mw.widgets.MultiToggleButtonWidget.js
@@ -48,7 +48,7 @@
 				this.items[ i ] = new OO.ui.ToggleButtonWidget( {
 					data: i,
 					label: this.options[ i ],
-					value: config.selected.indexOf( i ) !== -1
+					value: config.selected.includes( i )
 				} );
 
 				this.items[ i ].on( 'change', () => {
-- 
2.47.3

$ date
--- stdout ---
Sat Oct  4 03:10:24 UTC 2025

--- end ---
$ git clone file:///srv/git/mediawiki-extensions-PageOwnership.git repo --depth=1 -b master
--- stderr ---
Cloning into 'repo'...
--- 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 ---
435410206a44627596cb669212c0200edae6fe57 refs/heads/master

--- end ---
$ /usr/bin/npm audit --json
--- stdout ---
{
  "auditReportVersion": 2,
  "vulnerabilities": {},
  "metadata": {
    "vulnerabilities": {
      "info": 0,
      "low": 0,
      "moderate": 0,
      "high": 0,
      "critical": 0,
      "total": 0
    },
    "dependencies": {
      "prod": 1,
      "dev": 404,
      "optional": 0,
      "peer": 1,
      "peerOptional": 0,
      "total": 404
    }
  }
}

--- 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: 21 installs, 0 updates, 0 removals
  - Locking composer/semver (3.4.3)
  - Locking composer/spdx-licenses (1.5.9)
  - Locking dealerdirect/phpcodesniffer-composer-installer (v1.1.2)
  - Locking mediawiki/mediawiki-codesniffer (v47.0.0)
  - Locking mediawiki/minus-x (1.1.3)
  - 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.4.0)
  - Locking phpcsstandards/phpcsextra (1.2.1)
  - Locking phpcsstandards/phpcsutils (1.0.12)
  - Locking psr/container (2.0.2)
  - Locking squizlabs/php_codesniffer (3.12.2)
  - Locking symfony/console (v7.3.4)
  - Locking symfony/deprecation-contracts (v3.6.0)
  - Locking symfony/polyfill-ctype (v1.33.0)
  - Locking symfony/polyfill-intl-grapheme (v1.33.0)
  - Locking symfony/polyfill-intl-normalizer (v1.33.0)
  - Locking symfony/polyfill-mbstring (v1.33.0)
  - Locking symfony/polyfill-php80 (v1.33.0)
  - Locking symfony/service-contracts (v3.6.0)
  - Locking symfony/string (v7.3.4)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 21 installs, 0 updates, 0 removals
    0 [>---------------------------]    0 [->--------------------------]
  - Installing squizlabs/php_codesniffer (3.12.2): Extracting archive
  - Installing dealerdirect/phpcodesniffer-composer-installer (v1.1.2): Extracting archive
  - Installing symfony/polyfill-php80 (v1.33.0): Extracting archive
  - Installing phpcsstandards/phpcsutils (1.0.12): Extracting archive
  - Installing phpcsstandards/phpcsextra (1.2.1): Extracting archive
  - Installing symfony/polyfill-mbstring (v1.33.0): Extracting archive
  - Installing composer/spdx-licenses (1.5.9): Extracting archive
  - Installing composer/semver (3.4.3): Extracting archive
  - Installing mediawiki/mediawiki-codesniffer (v47.0.0): Extracting archive
  - Installing symfony/polyfill-intl-normalizer (v1.33.0): Extracting archive
  - Installing symfony/polyfill-intl-grapheme (v1.33.0): Extracting archive
  - Installing symfony/polyfill-ctype (v1.33.0): Extracting archive
  - Installing symfony/string (v7.3.4): Extracting archive
  - Installing symfony/deprecation-contracts (v3.6.0): Extracting archive
  - Installing psr/container (2.0.2): Extracting archive
  - Installing symfony/service-contracts (v3.6.0): Extracting archive
  - Installing symfony/console (v7.3.4): Extracting archive
  - Installing mediawiki/minus-x (1.1.3): 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.4.0): Extracting archive
  0/19 [>---------------------------]   0%
 19/19 [============================] 100%
Generating autoload files
15 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.28.2 -> 0.31.0
$ /usr/bin/npm install
--- stderr ---
npm WARN deprecated @humanwhocodes/config-array@0.13.0: Use @eslint/config-array instead
npm WARN deprecated @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
--- stdout ---

added 424 packages, and audited 425 packages in 5s

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

found 0 vulnerabilities

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

--- end ---
$ /usr/bin/npm install grunt-eslint@24.3.0 --save-exact
--- stdout ---

up to date, audited 425 packages in 1s

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

found 0 vulnerabilities

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

--- end ---
$ ./node_modules/.bin/eslint resources/PageOwnership.js package.json resources/mw.widgets.GroupsUsersMultiselectWidget.js Gruntfile.js resources/mw.widgets.MultiToggleButtonWidget.js resources/mw.widgets.MenuTagMultiselectWidget.js i18n/en.json resources/VersionCheck.js package-lock.json composer.json extension.json i18n/qqq.json resources/PageOwnershipPermissions.js --fix
--- stdout ---

/src/repo/resources/PageOwnershipPermissions.js
  125:5  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  129:5  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  180:7  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  182:4  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VersionCheck.js
  31:4  error    Prefer .then to .done                                                               no-jquery/no-done-fail
  58:8  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/mw.widgets.GroupsUsersMultiselectWidget.js
  190:6  error  Prefer .then to .done  no-jquery/no-done-fail
  190:6  error  Prefer .then to .fail  no-jquery/no-done-fail

/src/repo/resources/mw.widgets.MultiToggleButtonWidget.js
  18:1  warning  Invalid JSDoc tag name "ingroup"  jsdoc/check-tag-names

✖ 9 problems (3 errors, 6 warnings)


--- end ---
$ ./node_modules/.bin/eslint resources/PageOwnership.js package.json resources/mw.widgets.GroupsUsersMultiselectWidget.js Gruntfile.js resources/mw.widgets.MultiToggleButtonWidget.js resources/mw.widgets.MenuTagMultiselectWidget.js i18n/en.json resources/VersionCheck.js package-lock.json composer.json extension.json i18n/qqq.json resources/PageOwnershipPermissions.js -f json
--- stdout ---
[{"filePath":"/src/repo/Gruntfile.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"max-len","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/composer.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/extension.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/i18n/en.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/i18n/qqq.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/package-lock.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/package.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"indent","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/resources/PageOwnership.js","messages":[],"suppressedMessages":[{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":75,"column":2,"nodeType":"CallExpression","endLine":75,"endColumn":81,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'val' is defined but never used.","line":75,"column":106,"nodeType":"Identifier","messageId":"unusedVar","endLine":75,"endColumn":109,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-alert","severity":2,"message":"Unexpected confirm.","line":78,"column":10,"nodeType":"CallExpression","messageId":"unexpected","endLine":78,"endColumn":73,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-sizzle","severity":2,"message":"Selector extensions are not allowed","line":83,"column":4,"nodeType":"CallExpression","endLine":85,"endColumn":22,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"max-len","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/resources/PageOwnershipPermissions.js","messages":[{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":125,"column":5,"nodeType":"CallExpression","endLine":125,"endColumn":60},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":129,"column":5,"nodeType":"CallExpression","endLine":129,"endColumn":63},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":180,"column":7,"nodeType":"CallExpression","endLine":180,"endColumn":65},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":182,"column":4,"nodeType":"CallExpression","endLine":182,"endColumn":62}],"suppressedMessages":[{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":195,"column":2,"nodeType":"CallExpression","endLine":195,"endColumn":62,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'val' is defined but never used.","line":198,"column":14,"nodeType":"Identifier","messageId":"unusedVar","endLine":198,"endColumn":17,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-alert","severity":2,"message":"Unexpected confirm.","line":201,"column":11,"nodeType":"CallExpression","messageId":"unexpected","endLine":201,"endColumn":74,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-sizzle","severity":2,"message":"Selector extensions are not allowed","line":206,"column":5,"nodeType":"CallExpression","endLine":208,"endColumn":23,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension PageOwnership.\n *\n * PageOwnership is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * PageOwnership is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with PageOwnership.  If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2021-2023, https://wikisphere.org\n */\n\n$( () => {\n\t//  @see https://www.mediawiki.org/wiki/Manual:User_rights\n\tvar actions = {\n\t\treading: [ 'read' ],\n\t\tediting: [\n\t\t\t'applychangetags',\n\t\t\t'autocreateaccount',\n\t\t\t'createaccount',\n\t\t\t'createpage',\n\t\t\t'createtalk',\n\t\t\t'delete-redirect',\n\t\t\t'edit',\n\t\t\t'editsemiprotected',\n\t\t\t'editprotected',\n\t\t\t'minoredit',\n\t\t\t'move',\n\t\t\t'move-categorypages',\n\t\t\t'move-rootuserpages',\n\t\t\t'move-subpages',\n\t\t\t'movefile',\n\t\t\t'reupload',\n\t\t\t'reupload-own',\n\t\t\t'reupload-shared',\n\t\t\t'sendemail',\n\t\t\t'upload',\n\t\t\t'upload_by_url'\n\t\t],\n\t\tmanagement: [\n\t\t\t'bigdelete',\n\t\t\t'block',\n\t\t\t'blockemail',\n\t\t\t'browsearchive',\n\t\t\t'changetags',\n\t\t\t'delete',\n\t\t\t'deletedhistory',\n\t\t\t'deletedtext',\n\t\t\t'deletelogentry',\n\t\t\t'deleterevision',\n\t\t\t'editcontentmodel',\n\t\t\t'editinterface',\n\t\t\t'editmyoptions',\n\t\t\t'editmyprivateinfo',\n\t\t\t'editmyusercss',\n\t\t\t'editmyuserjs',\n\t\t\t'editmyuserjsredirect',\n\t\t\t'editmyuserjson',\n\t\t\t'editmywatchlist',\n\t\t\t'editsitecss',\n\t\t\t'editsitejs',\n\t\t\t'editsitejson',\n\t\t\t'editusercss',\n\t\t\t'edituserjs',\n\t\t\t'edituserjson',\n\t\t\t'hideuser',\n\t\t\t'markbotedits',\n\t\t\t'mergehistory',\n\t\t\t'pagelang',\n\t\t\t'patrol',\n\t\t\t'patrolmarks',\n\t\t\t'protect',\n\t\t\t'rollback',\n\t\t\t'suppressionlog',\n\t\t\t'suppressrevision',\n\t\t\t'unblockself',\n\t\t\t'undelete',\n\t\t\t'userrights',\n\t\t\t'userrights-interwiki',\n\t\t\t'viewmyprivateinfo',\n\t\t\t'viewmywatchlist',\n\t\t\t'viewsuppressed'\n\t\t],\n\t\tadministration: [\n\t\t\t'autopatrol',\n\t\t\t'deletechangetags',\n\t\t\t'import',\n\t\t\t'importupload',\n\t\t\t'managechangetags',\n\t\t\t'siteadmin',\n\t\t\t'unwatchedpages'\n\t\t],\n\t\ttechnical: [\n\t\t\t'apihighlimits',\n\t\t\t'autoconfirmed',\n\t\t\t'bot',\n\t\t\t'ipblock-exempt',\n\t\t\t'nominornewtalk',\n\t\t\t'noratelimit',\n\t\t\t'override-export-depth',\n\t\t\t'purge',\n\t\t\t'suppressredirect',\n\t\t\t'writeapi'\n\t\t]\n\t};\n\n\tvar messages = JSON.parse(\n\t\tmw.config.get( 'pageownership-permissions-groupPermissions-messages' )\n\t);\n\n\tfunction populateMenus( action, selected ) {\n\t\tvar menuTagInputWidget;\n\n\t\tif ( action === 'add' ) {\n\t\t\tmenuTagInputWidget = OO.ui.infuse(\n\t\t\t\t$( '#pageownership-permissions-field-add-permissions' )\n\t\t\t);\n\t\t} else if ( action === 'remove' ) {\n\t\t\tmenuTagInputWidget = OO.ui.infuse(\n\t\t\t\t$( '#pageownership-permissions-field-remove-permissions' )\n\t\t\t);\n\t\t}\n\n\t\tvar selectedItems = menuTagInputWidget.getValue();\n\n\t\tmenuTagInputWidget.menu.clearItems();\n\n\t\tvar options = [];\n\t\tfor ( var i in actions ) {\n\t\t\tif ( action === 'add' && selected.includes( i ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( action === 'remove' && !selected.includes( i ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\toptions.push(\n\t\t\t\tnew OO.ui.MenuOptionWidget( {\n\t\t\t\t\tdisabled: true,\n\t\t\t\t\tclasses: [ 'pageownership-permissions-options-optgroup' ],\n\t\t\t\t\tdata: i,\n\t\t\t\t\t// The following messages are used here:\n\t\t\t\t\t// * pageownership-permissions-actions-label-reading\n\t\t\t\t\t// * pageownership-permissions-actions-label-editing\n\t\t\t\t\t// * pageownership-permissions-actions-label-management\n\t\t\t\t\t// * pageownership-permissions-actions-label-administration\n\t\t\t\t\t// * pageownership-permissions-actions-label-technical\n\t\t\t\t\tlabel: mw.msg( 'pageownership-permissions-actions-label-' + i )\n\t\t\t\t} )\n\t\t\t);\n\n\t\t\tfor ( var ii in actions[ i ] ) {\n\t\t\t\toptions.push(\n\t\t\t\t\tnew OO.ui.MenuOptionWidget( {\n\t\t\t\t\t\tclasses: [ 'pageownership-permissions-options-option' ],\n\t\t\t\t\t\tdata: actions[ i ][ ii ],\n\t\t\t\t\t\tlabel: actions[ i ][ ii ] in messages ?\n\t\t\t\t\t\t\tmessages[ actions[ i ][ ii ] ] :\n\t\t\t\t\t\t\tactions[ i ][ ii ],\n\t\t\t\t\t\t// mw.msg( 'right-' + actions[i][ii] ),\n\t\t\t\t\t\tselected: selectedItems.includes( actions[ i ][ ii ] )\n\t\t\t\t\t} )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tmenuTagInputWidget.menu.addItems( options );\n\t}\n\n\tif ( $( '#pageownership-permissions-field-permissions-bytype' ).get( 0 ) ) {\n\t\tvar multiToggleButtonWidget = OO.ui.infuse(\n\t\t\t$( '#pageownership-permissions-field-permissions-bytype' )\n\t\t);\n\n\t\tmultiToggleButtonWidget.on( 'change', ( value ) => {\n\t\t\tpopulateMenus( 'add', value );\n\t\t\tpopulateMenus( 'remove', value );\n\t\t} );\n\n\t\tpopulateMenus( 'add', multiToggleButtonWidget.getValue() );\n\t\tpopulateMenus( 'remove', multiToggleButtonWidget.getValue() );\n\t}\n\n\t// eslint-disable-next-line no-jquery/no-global-selector\n\t$( '#pageownership-form-permissions button[type=\"submit\"]' ).on(\n\t\t'click',\n\t\t// eslint-disable-next-line no-unused-vars\n\t\tfunction ( val ) {\n\t\t\tif ( $( this ).val() === 'delete' ) {\n\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\tif ( !confirm( mw.msg( 'pageownership-jsmodule-deleteitemconfirm' ) ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line no-jquery/no-sizzle\n\t\t\t\t$( this )\n\t\t\t\t\t.closest( 'form' )\n\t\t\t\t\t.find( ':input' )\n\t\t\t\t\t.each( ( i, el ) => {\n\t\t\t\t\t\t$( el ).removeAttr( 'required' );\n\t\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t);\n} );\n","usedDeprecatedRules":[{"ruleId":"max-len","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/resources/VersionCheck.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":31,"column":4,"nodeType":"CallExpression","endLine":87,"endColumn":8},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":58,"column":8,"nodeType":"CallExpression","endLine":58,"endColumn":74}],"suppressedMessages":[{"ruleId":"no-jquery/no-parse-html-literal","severity":2,"message":"Prefer DOM building to parsing HTML literals","line":62,"column":10,"nodeType":"CallExpression","endLine":62,"endColumn":33,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-class-state","severity":2,"message":"Where possible, maintain application state in JS to avoid slower DOM queries","line":66,"column":10,"nodeType":"CallExpression","endLine":68,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension PageOwnership.\n *\n * PageOwnership is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * PageOwnership is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with PageOwnership.  If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2021-2023, https://wikisphere.org\n */\n\n$( () => {\n\n\t// display every 3 days\n\tif (\n\t\t!mw.config.get( 'pageownership-disableVersionCheck' ) &&\n\t\tmw.config.get( 'pageownership-canmanagepermissions' ) &&\n\t\t!mw.cookie.get( 'pageownership-check-latest-version' )\n\t) {\n\t\tmw.loader.using( 'mediawiki.api', () => {\n\t\t\tnew mw.Api()\n\t\t\t\t.postWithToken( 'csrf', {\n\t\t\t\t\taction: 'pageownership-check-latest-version'\n\t\t\t\t} )\n\t\t\t\t.done( ( res ) => {\n\t\t\t\t\tif ( 'pageownership-check-latest-version' in res ) {\n\t\t\t\t\t\tif ( res[ 'pageownership-check-latest-version' ].result === 2 ) {\n\t\t\t\t\t\t\tvar messageWidget = new OO.ui.MessageWidget( {\n\t\t\t\t\t\t\t\ttype: 'warning',\n\t\t\t\t\t\t\t\tlabel: new OO.ui.HtmlSnippet(\n\t\t\t\t\t\t\t\t\tmw.msg(\n\t\t\t\t\t\t\t\t\t\t'pageownership-jsmodule-outdated-version'\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t// *** this does not work before ooui v0.43.0\n\t\t\t\t\t\t\t\tshowClose: true\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\tvar closeFunction = function () {\n\t\t\t\t\t\t\t\tvar three_days = 3 * 86400;\n\t\t\t\t\t\t\t\tmw.cookie.set( 'pageownership-check-latest-version', true, {\n\t\t\t\t\t\t\t\t\tpath: '/',\n\t\t\t\t\t\t\t\t\texpires: three_days\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t$( messageWidget.$element ).parent().remove();\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tmessageWidget.on( 'close', closeFunction );\n\n\t\t\t\t\t\t\t$( '#pageownership-panel-layout,#pageownership-form-permissions' )\n\t\t\t\t\t\t\t\t.first()\n\t\t\t\t\t\t\t\t.prepend(\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-jquery/no-parse-html-literal\n\t\t\t\t\t\t\t\t\t$( '<div><br/></div>' ).prepend( messageWidget.$element )\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t// eslint-disable-next-line no-jquery/no-class-state\n\t\t\t\t\t\t\t\t!messageWidget.$element.hasClass(\n\t\t\t\t\t\t\t\t\t'oo-ui-messageWidget-showClose'\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tmessageWidget.$element.addClass(\n\t\t\t\t\t\t\t\t\t'oo-ui-messageWidget-showClose'\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tvar closeButton = new OO.ui.ButtonWidget( {\n\t\t\t\t\t\t\t\t\tclasses: [ 'oo-ui-messageWidget-close' ],\n\t\t\t\t\t\t\t\t\tframed: false,\n\t\t\t\t\t\t\t\t\ticon: 'close',\n\t\t\t\t\t\t\t\t\tlabel: OO.ui.msg(\n\t\t\t\t\t\t\t\t\t\t'ooui-popup-widget-close-button-aria-label'\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\tinvisibleLabel: true\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\tcloseButton.on( 'click', closeFunction );\n\t\t\t\t\t\t\t\tmessageWidget.$element.append( closeButton.$element );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t} );\n\t}\n} );\n","usedDeprecatedRules":[{"ruleId":"max-len","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/resources/mw.widgets.GroupsUsersMultiselectWidget.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":190,"column":6,"nodeType":"CallExpression","endLine":247,"endColumn":8},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":190,"column":6,"nodeType":"CallExpression","endLine":248,"endColumn":44}],"suppressedMessages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 101. Maximum allowed is 100.","line":31,"column":1,"nodeType":"Program","messageId":"max","endLine":31,"endColumn":99,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 110. Maximum allowed is 100.","line":64,"column":1,"nodeType":"Program","messageId":"max","endLine":64,"endColumn":99,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 104. Maximum allowed is 100.","line":96,"column":1,"nodeType":"Program","messageId":"max","endLine":96,"endColumn":93,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 108. Maximum allowed is 100.","line":98,"column":1,"nodeType":"Program","messageId":"max","endLine":98,"endColumn":97,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 101. Maximum allowed is 100.","line":220,"column":1,"nodeType":"Program","messageId":"max","endLine":220,"endColumn":75,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/*!\n * MediaWiki Widgets - GroupsUsersMultiselectWidget class.\n *\n * @copyright 2017 MediaWiki Widgets Team and others; see AUTHORS.txt\n * @license The MIT License (MIT); see LICENSE.txt\n */\n\n/* eslint-disable max-len */\n( function () {\n\t/**\n\t * GroupsUsersMultiselectWidget can be used to input list of users in a single\n\t * line.\n\t *\n\t * If used inside HTML form the results will be sent as the list of\n\t * newline-separated usernames.\n\t *\n\t * This can be configured to accept IP addresses and/or ranges as well as\n\t * usernames.\n\t *\n\t * @class\n\t * @extends OO.ui.MenuTagMultiselectWidget\n\t *\n\t * @constructor\n\t * @param {Object} [config] Configuration options\n\t * @cfg {mw.Api} [api] Instance of mw.Api (or subclass thereof) to use for queries\n\t * @cfg {number} [limit=10] Number of results to show in autocomplete menu\n\t * @cfg {string} [name] Name of input to submit results (when used in HTML forms)\n\t * @cfg {boolean} [ipAllowed=false] Show IP addresses in autocomplete menu\n\t *  If false, single IP addresses are not allowed, even if IP ranges are allowed.\n\t * @cfg {boolean} [ipRangeAllowed=false] Show IP ranges in autocomplete menu\n\t * @cfg {Object} [ipRangeLimits] Maximum allowed IP ranges (defaults match HTMLUserTextField.php)\n\t * @cfg {number} [ipRangeLimits.IPv4 = 16] Maximum allowed IPv4 range\n\t * @cfg {number} [ipRangeLimits.IPv6 = 32] Maximum allowed IPv6 range\n\t */\n\n\tmw.widgets.GroupsUsersMultiselectWidget =\n\t\tfunction MwWidgetsGroupsGroupsUsersMultiselectWidget( config ) {\n\n\t\t\t// ***edited\n\t\t\tmw.widgets.GroupsUsersMultiselectWidget.prototype.originalOptions =\n\t\t\t\tconfig.options;\n\n\t\t\t// Config initialization\n\t\t\tconfig = Object.assign(\n\t\t\t\t{\n\t\t\t\t\tlimit: 10,\n\t\t\t\t\tipAllowed: false,\n\t\t\t\t\tipRangeAllowed: false,\n\t\t\t\t\tipRangeLimits: {\n\t\t\t\t\t\tIPv4: 16,\n\t\t\t\t\t\tIPv6: 32\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tconfig\n\t\t\t);\n\n\t\t\t// ***edited\n\t\t\t// see resources/lib/ooui/oojs-ui-widgets.js -> OoUiTagMultiselectWidget\n\t\t\tconfig.input = {\n\n\t\t\t\t// ***not working ?\n\t\t\t\t// required: true,\n\t\t\t\tautocomplete: false\n\t\t\t\t// indicatorElement: $('.oo-ui-tagMultiselectWidget-handle .oo-ui-indicatorElement-indicator')\n\n\t\t\t};\n\n\t\t\t/*\nconfig.inputWidget = new OO.ui.TextInputWidget({\n\t\t\t\trequired: true,\n\t\t\t\tautocomplete: false,\n\t\t\t\tplaceholder: config.placeholder,\n\t\t\t\tclasses: [ 'oo-ui-tagMultiselectWidget-input' ]\n\t\t\t} );\n*/\n\n\t\t\t// Parent constructor\n\t\t\tmw.widgets.GroupsUsersMultiselectWidget.parent.call(\n\t\t\t\tthis,\n\t\t\t\tObject.assign( {}, config, {} )\n\t\t\t);\n\n\t\t\t// Mixin constructors\n\t\t\tOO.ui.mixin.PendingElement.call(\n\t\t\t\tthis,\n\t\t\t\tObject.assign( {}, config, { $pending: this.$handle } )\n\t\t\t);\n\n\t\t\t// Properties\n\t\t\tthis.limit = config.limit;\n\t\t\tthis.ipAllowed = config.ipAllowed;\n\t\t\tthis.ipRangeAllowed = config.ipRangeAllowed;\n\t\t\tthis.ipRangeLimits = config.ipRangeLimits;\n\n\t\t\tif ( 'name' in config ) {\n\t\t\t\t// Use this instead of <input type=\"hidden\">, because hidden inputs do not have separate\n\t\t\t\t// 'value' and 'defaultValue' properties. The script on Special:Preferences\n\t\t\t\t// (mw.special.preferences.confirmClose) checks this property to see if a field was changed.\n\t\t\t\tthis.$hiddenInput = $( '<textarea>' )\n\t\t\t\t\t.addClass( 'oo-ui-element-hidden' )\n\t\t\t\t\t.attr( 'name', config.name )\n\t\t\t\t\t.appendTo( this.$element );\n\t\t\t\t// Update with preset values\n\t\t\t\tthis.updateHiddenInput();\n\t\t\t\t// Set the default value (it might be different from just being empty)\n\t\t\t\tthis.$hiddenInput.prop(\n\t\t\t\t\t'defaultValue',\n\t\t\t\t\tthis.getSelectedUsernames().join( '\\n' )\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Events\n\t\t\t// When list of selected usernames changes, update hidden input\n\t\t\tthis.connect( this, {\n\t\t\t\tchange: 'onMultiselectChange'\n\t\t\t} );\n\n\t\t\t// API init\n\t\t\tthis.api = config.api || new mw.Api();\n\t\t};\n\n\t/* Setup */\n\n\tOO.inheritClass(\n\t\tmw.widgets.GroupsUsersMultiselectWidget,\n\t\tOO.ui.MenuTagMultiselectWidget\n\t);\n\tOO.mixinClass(\n\t\tmw.widgets.GroupsUsersMultiselectWidget,\n\t\tOO.ui.mixin.PendingElement\n\t);\n\n\t/* Methods */\n\n\t/**\n\t * Get currently selected usernames\n\t *\n\t * @return {string[]} usernames\n\t */\n\tmw.widgets.GroupsUsersMultiselectWidget.prototype.getSelectedUsernames =\n\t\tfunction () {\n\t\t\treturn this.getValue();\n\t\t};\n\n\t/**\n\t * Update autocomplete menu with items\n\t *\n\t * @private\n\t */\n\tmw.widgets.GroupsUsersMultiselectWidget.prototype.updateMenuItems =\n\t\tfunction () {\n\t\t\tvar isValidIp,\n\t\t\t\tisValidRange,\n\t\t\t\tinputValue = this.input.getValue();\n\n\t\t\tif ( inputValue === this.inputValue ) {\n\t\t\t\t// Do not restart api query if nothing has changed in the input\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\tthis.inputValue = inputValue;\n\t\t\t}\n\n\t\t\tthis.api.abort(); // Abort all unfinished api requests\n\n\t\t\tif ( inputValue.length > 0 ) {\n\t\t\t\tthis.pushPending();\n\n\t\t\t\tif ( this.ipAllowed || this.ipRangeAllowed ) {\n\t\t\t\t\tisValidIp = mw.util.isIPAddress( inputValue, false );\n\t\t\t\t\tisValidRange =\n\t\t\t\t\t\t!isValidIp &&\n\t\t\t\t\t\tmw.util.isIPAddress( inputValue, true ) &&\n\t\t\t\t\t\tthis.validateIpRange( inputValue );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t( this.ipAllowed && isValidIp ) ||\n\t\t\t\t\t( this.ipRangeAllowed && isValidRange )\n\t\t\t\t) {\n\t\t\t\t\tthis.menu.clearItems();\n\t\t\t\t\tthis.menu.addItems( [\n\t\t\t\t\t\tnew OO.ui.MenuOptionWidget( {\n\t\t\t\t\t\t\tdata: inputValue,\n\t\t\t\t\t\t\tlabel: inputValue\n\t\t\t\t\t\t} )\n\t\t\t\t\t] );\n\t\t\t\t\tthis.menu.toggle( true );\n\t\t\t\t\tthis.popPending();\n\t\t\t\t} else {\n\t\t\t\t\tthis.api\n\t\t\t\t\t\t.get( {\n\t\t\t\t\t\t\taction: 'query',\n\t\t\t\t\t\t\tlist: 'allusers',\n\t\t\t\t\t\t\t// Prefix of list=allusers is case sensitive. Normalise first\n\t\t\t\t\t\t\t// character to uppercase so that \"fo\" may yield \"Foo\".\n\t\t\t\t\t\t\tauprefix: inputValue[ 0 ].toUpperCase() + inputValue.slice( 1 ),\n\t\t\t\t\t\t\taulimit: this.limit\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.done(\n\t\t\t\t\t\t\t( response ) => {\n\t\t\t\t\t\t\t\tvar suggestions = response.query.allusers,\n\t\t\t\t\t\t\t\t\tselected = this.getSelectedUsernames();\n\n\t\t\t\t\t\t\t\t// Remove usernames, which are already selected from suggestions\n\t\t\t\t\t\t\t\tsuggestions = suggestions\n\t\t\t\t\t\t\t\t\t.map( ( user ) => {\n\t\t\t\t\t\t\t\t\t\tif ( !selected.includes( user.name ) ) {\n\t\t\t\t\t\t\t\t\t\t\treturn new OO.ui.MenuOptionWidget( {\n\t\t\t\t\t\t\t\t\t\t\t\tdata: user.name,\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: user.name,\n\t\t\t\t\t\t\t\t\t\t\t\tid: user.name\n\t\t\t\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t\t.filter( ( item ) => item !== undefined );\n\n\t\t\t\t\t\t\t\t// ***edited\n\t\t\t\t\t\t\t\tsuggestions = suggestions.concat(\n\t\t\t\t\t\t\t\t\tmw.widgets.GroupsUsersMultiselectWidget.prototype.originalOptions\n\t\t\t\t\t\t\t\t\t\t// .filter( function ( val ) {\n\t\t\t\t\t\t\t\t\t\t// return val.data.indexOf( inputValue ) === 0;\n\t\t\t\t\t\t\t\t\t\t// } )\n\t\t\t\t\t\t\t\t\t\t.map( ( x ) => new OO.ui.MenuOptionWidget( {\n\t\t\t\t\t\t\t\t\t\t\tdata: x.data,\n\t\t\t\t\t\t\t\t\t\t\tlabel: x.label\n\t\t\t\t\t\t\t\t\t\t} ) )\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t// Remove all items from menu add fill it with new\n\t\t\t\t\t\t\t\tthis.menu.clearItems();\n\t\t\t\t\t\t\t\tthis.menu.addItems( suggestions );\n\n\t\t\t\t\t\t\t\tif ( suggestions.length ) {\n\t\t\t\t\t\t\t\t\t// Enable Narrator focus on menu item, see T250762.\n\t\t\t\t\t\t\t\t\tthis.menu.$focusOwner.attr(\n\t\t\t\t\t\t\t\t\t\t'aria-activedescendant',\n\t\t\t\t\t\t\t\t\t\tsuggestions[ 0 ].$element.attr( 'id' )\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Make the menu visible; it might not be if it was previously empty\n\t\t\t\t\t\t\t\tthis.menu.toggle( true );\n\n\t\t\t\t\t\t\t\tthis.popPending();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.fail( this.popPending.bind( this ) );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.menu.clearItems();\n\n\t\t\t\t// ***edited\n\t\t\t\tthis.menu.addItems(\n\t\t\t\t\tmw.widgets.GroupsUsersMultiselectWidget.prototype.originalOptions.map(\n\t\t\t\t\t\t( x ) => new OO.ui.MenuOptionWidget( {\n\t\t\t\t\t\t\tdata: x.data,\n\t\t\t\t\t\t\tlabel: x.label\n\t\t\t\t\t\t} )\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t/**\n\t * @private\n\t * @param {string} ipRange Valid IPv4 or IPv6 range\n\t * @return {boolean} The IP range is within the size limit\n\t */\n\tmw.widgets.GroupsUsersMultiselectWidget.prototype.validateIpRange = function (\n\t\tipRange\n\t) {\n\t\tipRange = ipRange.split( '/' );\n\n\t\treturn (\n\t\t\t( mw.util.isIPv4Address( ipRange[ 0 ] ) &&\n\t\t\t\t+ipRange[ 1 ] >= this.ipRangeLimits.IPv4 ) ||\n\t\t\t( mw.util.isIPv6Address( ipRange[ 0 ] ) &&\n\t\t\t\t+ipRange[ 1 ] >= this.ipRangeLimits.IPv6 )\n\t\t);\n\t};\n\n\tmw.widgets.GroupsUsersMultiselectWidget.prototype.onInputChange =\n\t\tfunction () {\n\t\t\tmw.widgets.GroupsUsersMultiselectWidget.parent.prototype.onInputChange.apply(\n\t\t\t\tthis,\n\t\t\t\targuments\n\t\t\t);\n\n\t\t\tthis.updateMenuItems();\n\t\t};\n\n\t/**\n\t * If used inside HTML form, then update hiddenInput with list of\n\t * newline-separated usernames.\n\t *\n\t * @private\n\t */\n\tmw.widgets.GroupsUsersMultiselectWidget.prototype.updateHiddenInput =\n\t\tfunction () {\n\t\t\tif ( '$hiddenInput' in this ) {\n\t\t\t\tthis.$hiddenInput.val( this.getSelectedUsernames().join( '\\n' ) );\n\t\t\t\t// Trigger a 'change' event as if a user edited the text\n\t\t\t\t// (it is not triggered when changing the value from JS code).\n\t\t\t\tthis.$hiddenInput.trigger( 'change' );\n\t\t\t}\n\t\t};\n\n\t/**\n\t * React to the 'change' event.\n\t *\n\t * Updates the hidden input and clears the text from the text box.\n\t */\n\tmw.widgets.GroupsUsersMultiselectWidget.prototype.onMultiselectChange =\n\t\tfunction () {\n\t\t\tthis.updateHiddenInput();\n\t\t\tthis.input.setValue( '' );\n\t\t};\n}() );\n","usedDeprecatedRules":[{"ruleId":"max-len","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/resources/mw.widgets.MenuTagMultiselectWidget.js","messages":[],"suppressedMessages":[{"ruleId":"no-jquery/no-map-util","severity":2,"message":"Prefer Array#map to $.map","line":30,"column":20,"nodeType":"CallExpression","endLine":30,"endColumn":94,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"max-len","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/resources/mw.widgets.MultiToggleButtonWidget.js","messages":[{"ruleId":"jsdoc/check-tag-names","severity":1,"message":"Invalid JSDoc tag name \"ingroup\".","line":18,"column":1,"nodeType":"Block","endLine":18,"endColumn":1}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension PageOwnership.\n *\n * PageOwnership is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 2 of the License, or\n * (at your option) any later version.\n *\n * PageOwnership is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with PageOwnership.  If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @ingroup extensions\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright ©2021-2023, https://wikisphere.org\n */\n\n( function () {\n\tmw.widgets.MultiToggleButtonWidget =\n\t\tfunction MwWidgetsMultiToggleButtonWidget( config ) {\n\n\t\t\t// ***important, add position: relative to display\n\t\t\t// property native validation\n\t\t\tconfig.classes.push( 'pageownership-button-multiselect-widget' );\n\n\t\t\t// Parent constructor\n\t\t\tmw.widgets.MultiToggleButtonWidget.parent.call(\n\t\t\t\tthis,\n\t\t\t\tObject.assign( {}, config, {} )\n\t\t\t);\n\n\t\t\t// Events\n\t\t\t// When list of selected tags changes, update hidden input\n\t\t\tthis.connect( this, {\n\t\t\t\tchange: 'onMultiselectChange'\n\t\t\t} );\n\n\t\t\tthis.options = config.options;\n\n\t\t\tvar self = this;\n\t\t\tthis.items = {};\n\t\t\tfor ( var i in this.options ) {\n\t\t\t\tthis.items[ i ] = new OO.ui.ToggleButtonWidget( {\n\t\t\t\t\tdata: i,\n\t\t\t\t\tlabel: this.options[ i ],\n\t\t\t\t\tvalue: config.selected.includes( i )\n\t\t\t\t} );\n\n\t\t\t\tthis.items[ i ].on( 'change', () => {\n\t\t\t\t\tself.emit( 'change', self.getValue() );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\tfor ( var ii in this.items ) {\n\t\t\t\tthis.$element.append( this.items[ ii ].$element );\n\t\t\t}\n\n\t\t\tif ( 'name' in config ) {\n\t\t\t\tthis.$hiddenInput = $( '<textarea>' )\n\t\t\t\t\t.addClass( 'oo-ui-element-hidden' )\n\t\t\t\t\t.attr( 'name', config.name )\n\t\t\t\t\t.appendTo( this.$element );\n\n\t\t\t\t// Update with preset values\n\t\t\t\tthis.updateHiddenInput();\n\n\t\t\t\t// Set the default value (it might be different from just being empty)\n\t\t\t\tthis.$hiddenInput.prop( 'defaultValue', this.getValue().join( '\\n' ) );\n\t\t\t}\n\n\t\t};\n\n\tOO.inheritClass( mw.widgets.MultiToggleButtonWidget, OO.ui.Widget );\n\n\tmw.widgets.MultiToggleButtonWidget.prototype.getValue = function () {\n\t\tvar ret = [];\n\t\tfor ( var i in this.items ) {\n\t\t\tif ( this.items[ i ].getValue() ) {\n\t\t\t\tret.push( i );\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * If used inside HTML form, then update hiddenInput with list of\n\t * newline-separated tags.\n\t *\n\t * @private\n\t */\n\tmw.widgets.MultiToggleButtonWidget.prototype.updateHiddenInput = function () {\n\t\tif ( '$hiddenInput' in this ) {\n\t\t\tthis.$hiddenInput.val( this.getValue().join( '\\n' ) );\n\t\t}\n\t};\n\n\t/**\n\t * React to the 'change' event.\n\t *\n\t * Updates the hidden input and clears the text from the text box.\n\t */\n\tmw.widgets.MultiToggleButtonWidget.prototype.onMultiselectChange =\n\t\tfunction () {\n\t\t\tthis.updateHiddenInput();\n\t\t};\n}() );\n","usedDeprecatedRules":[{"ruleId":"max-len","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":"implicit-arrow-linebreak","replacedBy":[]},{"ruleId":"array-bracket-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"computed-property-spacing","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"indent","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multi-spaces","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]}]

--- end ---
Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json
Disabling eslint rule 'no-jquery/no-done-fail' (broken in .eslintrc.json) on .eslintrc.json
$ /usr/bin/npm ci
--- stderr ---
npm WARN deprecated @humanwhocodes/config-array@0.13.0: Use @eslint/config-array instead
npm WARN deprecated @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
--- stdout ---

added 424 packages, and audited 425 packages in 5s

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

found 0 vulnerabilities

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

> test
> grunt test

Running "eslint:all" (eslint) task

/src/repo/resources/PageOwnershipPermissions.js
  125:5  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  129:5  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  180:7  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  182:4  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VersionCheck.js
  31:4  warning  Prefer .then to .done                                                               no-jquery/no-done-fail
  58:8  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/mw.widgets.GroupsUsersMultiselectWidget.js
  190:6  warning  Prefer .then to .done  no-jquery/no-done-fail
  190:6  warning  Prefer .then to .fail  no-jquery/no-done-fail

/src/repo/resources/mw.widgets.MultiToggleButtonWidget.js
  18:1  warning  Invalid JSDoc tag name "ingroup"  jsdoc/check-tag-names

✖ 9 problems (0 errors, 9 warnings)


Running "stylelint:all" (stylelint) task
>> Linted 1 files without errors

Running "banana:PageOwnership" (banana) task
>> 1 message directory checked.

Done.

--- end ---
Upgrading c:mediawiki/mediawiki-codesniffer from 47.0.0 -> 48.0.0
$ /usr/bin/composer update
--- stderr ---
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 5 updates, 1 removal
  - Removing symfony/polyfill-php80 (v1.33.0)
  - Upgrading composer/semver (3.4.3 => 3.4.4)
  - Upgrading mediawiki/mediawiki-codesniffer (v47.0.0 => v48.0.0)
  - Upgrading phpcsstandards/phpcsextra (1.2.1 => 1.4.0)
  - Upgrading phpcsstandards/phpcsutils (1.0.12 => 1.1.1)
  - Upgrading squizlabs/php_codesniffer (3.12.2 => 3.13.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 0 installs, 5 updates, 1 removal
    0 [>---------------------------]    0 [->--------------------------]
  - Removing symfony/polyfill-php80 (v1.33.0)
  - Upgrading squizlabs/php_codesniffer (3.12.2 => 3.13.2): Extracting archive
  - Upgrading phpcsstandards/phpcsutils (1.0.12 => 1.1.1): Extracting archive
  - Upgrading phpcsstandards/phpcsextra (1.2.1 => 1.4.0): Extracting archive
  - Upgrading composer/semver (3.4.3 => 3.4.4): Extracting archive
  - Upgrading mediawiki/mediawiki-codesniffer (v47.0.0 => v48.0.0): Extracting archive
 0/5 [>---------------------------]   0%
 4/5 [======================>-----]  80%
 5/5 [============================] 100%
Generating autoload files
14 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
--- stdout ---
PHP CodeSniffer Config installed_paths set to ../../mediawiki/mediawiki-codesniffer,../../phpcsstandards/phpcsextra,../../phpcsstandards/phpcsutils

--- end ---
Previously failing phpcs rules: {'Generic.Files.LineLength.TooLong', 'Generic.Files.OneObjectStructurePerFile.MultipleFound', 'MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName'}
$ vendor/bin/phpcs --report=json
--- stdout ---
{"totals":{"errors":15,"warnings":20,"fixable":0},"files":{"\/src\/repo\/PageOwnershipMagic.i18n.magic.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/aliases\/DerivativeRequest.php":{"errors":1,"warnings":0,"messages":[{"message":"Only one object structure is allowed in a file","source":"Generic.Files.OneObjectStructurePerFile.MultipleFound","severity":5,"fixable":false,"type":"ERROR","line":32,"column":5}]},"\/src\/repo\/includes\/specials\/Widgets\/MenuTagMultiselectWidget.php":{"errors":2,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":21,"column":4},{"message":"There must be at least a blank line between a file-level comment and a class. Make sure you are not mixing file-level comments (like license headers) and class documentation","source":"MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":25,"column":2}]},"\/src\/repo\/includes\/aliases\/Linker.php":{"errors":1,"warnings":0,"messages":[{"message":"Only one object structure is allowed in a file","source":"Generic.Files.OneObjectStructurePerFile.MultipleFound","severity":5,"fixable":false,"type":"ERROR","line":32,"column":5}]},"\/src\/repo\/includes\/specials\/SpecialPageOwnershipForm.php":{"errors":1,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":19,"column":4}]},"\/src\/repo\/includes\/aliases\/Title.php":{"errors":1,"warnings":0,"messages":[{"message":"Only one object structure is allowed in a file","source":"Generic.Files.OneObjectStructurePerFile.MultipleFound","severity":5,"fixable":false,"type":"ERROR","line":32,"column":5}]},"\/src\/repo\/PageOwnership.alias.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/Widgets\/MultiToggleButtonWidget.php":{"errors":2,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":21,"column":4},{"message":"There must be at least a blank line between a file-level comment and a class. Make sure you are not mixing file-level comments (like license headers) and class documentation","source":"MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":25,"column":2}]},"\/src\/repo\/includes\/api\/PageOwnershipApiGetPermissions.php":{"errors":1,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":19,"column":4}]},"\/src\/repo\/includes\/specials\/Widgets\/HTMLMultiToggleButtonField.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/PageOwnershipApiSetPermissions.php":{"errors":1,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":19,"column":4}]},"\/src\/repo\/includes\/specials\/Widgets\/GroupsUsersMultiselectWidget.php":{"errors":1,"warnings":0,"messages":[{"message":"If this is a class comment, it must have no blank lines after; if it is a stray comment, it must not use \"\/**\" style comments; if it is a file-level comment, file a task in #MediaWiki-Codesniffer","source":"MediaWiki.Commenting.CommentBeforeClass.SpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":3,"column":1}]},"\/src\/repo\/includes\/specials\/Widgets\/HTMLMenuTagMultiselectField.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/Widgets\/PageOwnershipTagMultiselectWidget.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/PageOwnershipApiCheckLatestVersion.php":{"errors":1,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":19,"column":4}]},"\/src\/repo\/includes\/specials\/PageOwnershipPermissionsPager.php":{"errors":1,"warnings":4,"messages":[{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":114,"column":125},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":266,"column":121},{"message":"Method name \"pageIDsToList_\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":280,"column":20},{"message":"Line exceeds 120 characters; contains 123 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":293,"column":123},{"message":"Line exceeds 120 characters; contains 155 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":334,"column":155}]},"\/src\/repo\/includes\/PageOwnershipHooks.php":{"errors":0,"warnings":5,"messages":[{"message":"Line exceeds 120 characters; contains 135 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":67,"column":135},{"message":"Line exceeds 120 characters; contains 147 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":84,"column":147},{"message":"Line exceeds 120 characters; contains 226 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":191,"column":226},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":337,"column":128},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":529,"column":17}]},"\/src\/repo\/includes\/specials\/Widgets\/HTMLGroupsUsersMultiselectField.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/SpecialPageOwnershipPermissions.php":{"errors":0,"warnings":10,"messages":[{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":202,"column":126},{"message":"Line exceeds 120 characters; contains 187 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":240,"column":187},{"message":"Line exceeds 120 characters; contains 142 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":244,"column":142},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":249,"column":133},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":253,"column":125},{"message":"Line exceeds 120 characters; contains 150 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":343,"column":150},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":382,"column":121},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":543,"column":133},{"message":"Line exceeds 120 characters; contains 136 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":557,"column":136},{"message":"Line exceeds 120 characters; contains 155 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":716,"column":155}]},"\/src\/repo\/includes\/PageOwnership.php":{"errors":2,"warnings":1,"messages":[{"message":"Method name \"pageownership_userpages\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":620,"column":19},{"message":"Method name \"page_ancestors\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":1079,"column":19},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1150,"column":13}]}}}

--- end ---
PHPCS run failed
$ vendor/bin/phpcs --report=json
--- stdout ---
{"totals":{"errors":15,"warnings":20,"fixable":0},"files":{"\/src\/repo\/PageOwnership.alias.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/aliases\/Linker.php":{"errors":1,"warnings":0,"messages":[{"message":"Only one object structure is allowed in a file","source":"Generic.Files.OneObjectStructurePerFile.MultipleFound","severity":5,"fixable":false,"type":"ERROR","line":32,"column":5}]},"\/src\/repo\/includes\/aliases\/DerivativeRequest.php":{"errors":1,"warnings":0,"messages":[{"message":"Only one object structure is allowed in a file","source":"Generic.Files.OneObjectStructurePerFile.MultipleFound","severity":5,"fixable":false,"type":"ERROR","line":32,"column":5}]},"\/src\/repo\/includes\/specials\/Widgets\/MultiToggleButtonWidget.php":{"errors":2,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":21,"column":4},{"message":"There must be at least a blank line between a file-level comment and a class. Make sure you are not mixing file-level comments (like license headers) and class documentation","source":"MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":25,"column":2}]},"\/src\/repo\/PageOwnershipMagic.i18n.magic.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/Widgets\/MenuTagMultiselectWidget.php":{"errors":2,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":21,"column":4},{"message":"There must be at least a blank line between a file-level comment and a class. Make sure you are not mixing file-level comments (like license headers) and class documentation","source":"MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":25,"column":2}]},"\/src\/repo\/includes\/aliases\/Title.php":{"errors":1,"warnings":0,"messages":[{"message":"Only one object structure is allowed in a file","source":"Generic.Files.OneObjectStructurePerFile.MultipleFound","severity":5,"fixable":false,"type":"ERROR","line":32,"column":5}]},"\/src\/repo\/includes\/api\/PageOwnershipApiGetPermissions.php":{"errors":1,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":19,"column":4}]},"\/src\/repo\/includes\/specials\/SpecialPageOwnershipForm.php":{"errors":1,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":19,"column":4}]},"\/src\/repo\/includes\/api\/PageOwnershipApiCheckLatestVersion.php":{"errors":1,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":19,"column":4}]},"\/src\/repo\/includes\/specials\/Widgets\/GroupsUsersMultiselectWidget.php":{"errors":1,"warnings":0,"messages":[{"message":"If this is a class comment, it must have no blank lines after; if it is a stray comment, it must not use \"\/**\" style comments; if it is a file-level comment, file a task in #MediaWiki-Codesniffer","source":"MediaWiki.Commenting.CommentBeforeClass.SpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":3,"column":1}]},"\/src\/repo\/includes\/api\/PageOwnershipApiSetPermissions.php":{"errors":1,"warnings":0,"messages":[{"message":"@file is not a valid class annotation","source":"MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation","severity":5,"fixable":false,"type":"ERROR","line":19,"column":4}]},"\/src\/repo\/includes\/specials\/Widgets\/PageOwnershipTagMultiselectWidget.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/Widgets\/HTMLMultiToggleButtonField.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/Widgets\/HTMLMenuTagMultiselectField.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/Widgets\/HTMLGroupsUsersMultiselectField.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/PageOwnershipPermissionsPager.php":{"errors":1,"warnings":4,"messages":[{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":114,"column":125},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":266,"column":121},{"message":"Method name \"pageIDsToList_\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":280,"column":20},{"message":"Line exceeds 120 characters; contains 123 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":293,"column":123},{"message":"Line exceeds 120 characters; contains 155 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":334,"column":155}]},"\/src\/repo\/includes\/PageOwnershipHooks.php":{"errors":0,"warnings":5,"messages":[{"message":"Line exceeds 120 characters; contains 135 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":67,"column":135},{"message":"Line exceeds 120 characters; contains 147 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":84,"column":147},{"message":"Line exceeds 120 characters; contains 226 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":191,"column":226},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":337,"column":128},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":529,"column":17}]},"\/src\/repo\/includes\/specials\/SpecialPageOwnershipPermissions.php":{"errors":0,"warnings":10,"messages":[{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":202,"column":126},{"message":"Line exceeds 120 characters; contains 187 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":240,"column":187},{"message":"Line exceeds 120 characters; contains 142 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":244,"column":142},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":249,"column":133},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":253,"column":125},{"message":"Line exceeds 120 characters; contains 150 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":343,"column":150},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":382,"column":121},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":543,"column":133},{"message":"Line exceeds 120 characters; contains 136 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":557,"column":136},{"message":"Line exceeds 120 characters; contains 155 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":716,"column":155}]},"\/src\/repo\/includes\/PageOwnership.php":{"errors":2,"warnings":1,"messages":[{"message":"Method name \"pageownership_userpages\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":620,"column":19},{"message":"Method name \"page_ancestors\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":1079,"column":19},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1150,"column":13}]}}}

--- end ---
 * sniff MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter is now failing
 * sniff MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation is now failing
 * sniff MediaWiki.Commenting.CommentBeforeClass.SpacingAfter is now failing
$ git checkout .phpcs.xml
--- stderr ---
Updated 1 path from the index
--- stdout ---

--- end ---
$ /usr/bin/composer install
--- stderr ---
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Nothing to install, update or remove
Generating autoload files
14 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
--- stdout ---

--- end ---
$ /usr/bin/composer test
--- stderr ---
> parallel-lint . --exclude vendor --exclude node_modules
> phpcs -sp --cache
> minus-x check .
--- stdout ---
PHP 8.4.11 | 10 parallel jobs
....................                                         20/20 (100%)


Checked 20 files in 0.1 seconds
No syntax error found
.................... 20 / 20 (100%)


Time: 456ms; Memory: 8MB

MinusX
======
Processing /src/repo...
.............................................
All good!

--- end ---
$ /usr/bin/npm audit --json
--- stdout ---
{
  "auditReportVersion": 2,
  "vulnerabilities": {},
  "metadata": {
    "vulnerabilities": {
      "info": 0,
      "low": 0,
      "moderate": 0,
      "high": 0,
      "critical": 0,
      "total": 0
    },
    "dependencies": {
      "prod": 1,
      "dev": 424,
      "optional": 0,
      "peer": 1,
      "peerOptional": 0,
      "total": 424
    }
  }
}

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

--- end ---
build: Updating dependencies

composer:
* mediawiki/mediawiki-codesniffer: 47.0.0 → 48.0.0
  The following sniffs are failing and were disabled:
  * MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation
  * MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter
  * MediaWiki.Commenting.CommentBeforeClass.SpacingAfter


npm:
* eslint-config-wikimedia: 0.28.2 → 0.31.0
  The following rules are failing and were disabled:
  * no-jquery/no-done-fail


$ git add .
--- stdout ---

--- end ---
$ git commit -F /tmp/tmpyar8k80q
--- stdout ---
[master 02ac833] build: Updating dependencies
 9 files changed, 681 insertions(+), 103 deletions(-)

--- end ---
$ git format-patch HEAD~1 --stdout
--- stdout ---
From 02ac833be09750befccbb0f0fe66a75618107d0c Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Sat, 4 Oct 2025 03:11:06 +0000
Subject: [PATCH] build: Updating dependencies
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

composer:
* mediawiki/mediawiki-codesniffer: 47.0.0 → 48.0.0
  The following sniffs are failing and were disabled:
  * MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation
  * MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter
  * MediaWiki.Commenting.CommentBeforeClass.SpacingAfter

npm:
* eslint-config-wikimedia: 0.28.2 → 0.31.0
  The following rules are failing and were disabled:
  * no-jquery/no-done-fail

Change-Id: I9220f62e3d042bcc422b6d549128fb3de1378678
---
 .eslintrc.json                                |   3 +-
 .phpcs.xml                                    |   3 +
 composer.json                                 |   2 +-
 package-lock.json                             | 762 +++++++++++++++---
 package.json                                  |   2 +-
 resources/PageOwnership.js                    |   2 +-
 resources/PageOwnershipPermissions.js         |   6 +-
 ...mw.widgets.GroupsUsersMultiselectWidget.js |   2 +-
 .../mw.widgets.MultiToggleButtonWidget.js     |   2 +-
 9 files changed, 681 insertions(+), 103 deletions(-)

diff --git a/.eslintrc.json b/.eslintrc.json
index 5735096..85c7e39 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -8,6 +8,7 @@
 	"rules": {
 		"camelcase": "off",
 		"no-var": "off",
-		"no-jquery/no-global-selector": "warn"
+		"no-jquery/no-global-selector": "warn",
+		"no-jquery/no-done-fail": "warn"
 	}
 }
diff --git a/.phpcs.xml b/.phpcs.xml
index 579cee8..4e089bc 100644
--- a/.phpcs.xml
+++ b/.phpcs.xml
@@ -4,6 +4,9 @@
 		<exclude name="Generic.Files.LineLength.TooLong" />
 		<exclude name="MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName" />
 		<exclude name="Generic.Files.OneObjectStructurePerFile.MultipleFound" />
+		<exclude name="MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation" />
+		<exclude name="MediaWiki.Commenting.CommentBeforeClass.FileSpacingAfter" />
+		<exclude name="MediaWiki.Commenting.CommentBeforeClass.SpacingAfter" />
 	</rule>
 	<file>.</file>
 	<arg name="extensions" value="php"/>
diff --git a/composer.json b/composer.json
index 481cac4..996ca0f 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
 {
 	"require-dev": {
-		"mediawiki/mediawiki-codesniffer": "47.0.0",
+		"mediawiki/mediawiki-codesniffer": "48.0.0",
 		"mediawiki/minus-x": "1.1.3",
 		"php-parallel-lint/php-console-highlighter": "1.0.0",
 		"php-parallel-lint/php-parallel-lint": "1.4.0"
diff --git a/package-lock.json b/package-lock.json
index 28f934d..728d3f4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
 		"": {
 			"name": "PageOwnership",
 			"devDependencies": {
-				"eslint-config-wikimedia": "0.28.2",
+				"eslint-config-wikimedia": "0.31.0",
 				"grunt": "1.6.1",
 				"grunt-banana-checker": "0.13.0",
 				"grunt-eslint": "24.3.0",
@@ -236,16 +236,19 @@
 			}
 		},
 		"node_modules/@eslint-community/eslint-utils": {
-			"version": "4.4.0",
-			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
-			"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+			"version": "4.9.0",
+			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+			"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
 			"dev": true,
 			"dependencies": {
-				"eslint-visitor-keys": "^3.3.0"
+				"eslint-visitor-keys": "^3.4.3"
 			},
 			"engines": {
 				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
 			},
+			"funding": {
+				"url": "https://opencollective.com/eslint"
+			},
 			"peerDependencies": {
 				"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
 			}
@@ -367,6 +370,225 @@
 				"node": ">= 8"
 			}
 		},
+		"node_modules/@stylistic/eslint-plugin": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-3.1.0.tgz",
+			"integrity": "sha512-pA6VOrOqk0+S8toJYhQGv2MWpQQR0QpeUo9AhNkC49Y26nxBQ/nH1rta9bUU1rPw2fJ1zZEMV5oCX5AazT7J2g==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/utils": "^8.13.0",
+				"eslint-visitor-keys": "^4.2.0",
+				"espree": "^10.3.0",
+				"estraverse": "^5.3.0",
+				"picomatch": "^4.0.2"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"peerDependencies": {
+				"eslint": ">=8.40.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/project-service": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.45.0.tgz",
+			"integrity": "sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/tsconfig-utils": "^8.45.0",
+				"@typescript-eslint/types": "^8.45.0",
+				"debug": "^4.3.4"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <6.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz",
+			"integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.45.0",
+				"@typescript-eslint/visitor-keys": "8.45.0"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz",
+			"integrity": "sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <6.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/types": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz",
+			"integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz",
+			"integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/project-service": "8.45.0",
+				"@typescript-eslint/tsconfig-utils": "8.45.0",
+				"@typescript-eslint/types": "8.45.0",
+				"@typescript-eslint/visitor-keys": "8.45.0",
+				"debug": "^4.3.4",
+				"fast-glob": "^3.3.2",
+				"is-glob": "^4.0.3",
+				"minimatch": "^9.0.4",
+				"semver": "^7.6.0",
+				"ts-api-utils": "^2.1.0"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <6.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/utils": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz",
+			"integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==",
+			"dev": true,
+			"dependencies": {
+				"@eslint-community/eslint-utils": "^4.7.0",
+				"@typescript-eslint/scope-manager": "8.45.0",
+				"@typescript-eslint/types": "8.45.0",
+				"@typescript-eslint/typescript-estree": "8.45.0"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <6.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
+			"version": "8.45.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz",
+			"integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.45.0",
+				"eslint-visitor-keys": "^4.2.1"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/brace-expansion": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+			"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+			"dev": true,
+			"dependencies": {
+				"balanced-match": "^1.0.0"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": {
+			"version": "4.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+			"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"url": "https://opencollective.com/eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/espree": {
+			"version": "10.4.0",
+			"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+			"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+			"dev": true,
+			"dependencies": {
+				"acorn": "^8.15.0",
+				"acorn-jsx": "^5.3.2",
+				"eslint-visitor-keys": "^4.2.1"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"url": "https://opencollective.com/eslint"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/minimatch": {
+			"version": "9.0.5",
+			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+			"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+			"dev": true,
+			"dependencies": {
+				"brace-expansion": "^2.0.1"
+			},
+			"engines": {
+				"node": ">=16 || 14 >=14.17"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/isaacs"
+			}
+		},
+		"node_modules/@stylistic/eslint-plugin/node_modules/picomatch": {
+			"version": "4.0.3",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+			"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+			"dev": true,
+			"engines": {
+				"node": ">=12"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
+		},
 		"node_modules/@stylistic/stylelint-config": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-2.0.0.tgz",
@@ -447,14 +669,132 @@
 			"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
 			"dev": true
 		},
+		"node_modules/@typescript-eslint/eslint-plugin": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz",
+			"integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==",
+			"dev": true,
+			"dependencies": {
+				"@eslint-community/regexpp": "^4.10.0",
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/type-utils": "8.35.1",
+				"@typescript-eslint/utils": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
+				"graphemer": "^1.4.0",
+				"ignore": "^7.0.0",
+				"natural-compare": "^1.4.0",
+				"ts-api-utils": "^2.1.0"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"@typescript-eslint/parser": "^8.35.1",
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.9.0"
+			}
+		},
+		"node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+			"version": "7.0.5",
+			"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+			"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+			"dev": true,
+			"engines": {
+				"node": ">= 4"
+			}
+		},
+		"node_modules/@typescript-eslint/parser": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz",
+			"integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/typescript-estree": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
+				"debug": "^4.3.4"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.9.0"
+			}
+		},
+		"node_modules/@typescript-eslint/project-service": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz",
+			"integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/tsconfig-utils": "^8.35.1",
+				"@typescript-eslint/types": "^8.35.1",
+				"debug": "^4.3.4"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <5.9.0"
+			}
+		},
 		"node_modules/@typescript-eslint/scope-manager": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz",
-			"integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz",
+			"integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@typescript-eslint/tsconfig-utils": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz",
+			"integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <5.9.0"
+			}
+		},
+		"node_modules/@typescript-eslint/type-utils": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz",
+			"integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==",
 			"dev": true,
 			"dependencies": {
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/visitor-keys": "8.7.0"
+				"@typescript-eslint/typescript-estree": "8.35.1",
+				"@typescript-eslint/utils": "8.35.1",
+				"debug": "^4.3.4",
+				"ts-api-utils": "^2.1.0"
 			},
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -462,12 +802,16 @@
 			"funding": {
 				"type": "opencollective",
 				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.9.0"
 			}
 		},
 		"node_modules/@typescript-eslint/types": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz",
-			"integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz",
+			"integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==",
 			"dev": true,
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -478,19 +822,21 @@
 			}
 		},
 		"node_modules/@typescript-eslint/typescript-estree": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz",
-			"integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz",
+			"integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==",
 			"dev": true,
 			"dependencies": {
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/visitor-keys": "8.7.0",
+				"@typescript-eslint/project-service": "8.35.1",
+				"@typescript-eslint/tsconfig-utils": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
 				"debug": "^4.3.4",
 				"fast-glob": "^3.3.2",
 				"is-glob": "^4.0.3",
 				"minimatch": "^9.0.4",
 				"semver": "^7.6.0",
-				"ts-api-utils": "^1.3.0"
+				"ts-api-utils": "^2.1.0"
 			},
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -499,10 +845,8 @@
 				"type": "opencollective",
 				"url": "https://opencollective.com/typescript-eslint"
 			},
-			"peerDependenciesMeta": {
-				"typescript": {
-					"optional": true
-				}
+			"peerDependencies": {
+				"typescript": ">=4.8.4 <5.9.0"
 			}
 		},
 		"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
@@ -530,15 +874,15 @@
 			}
 		},
 		"node_modules/@typescript-eslint/utils": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz",
-			"integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz",
+			"integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==",
 			"dev": true,
 			"dependencies": {
-				"@eslint-community/eslint-utils": "^4.4.0",
-				"@typescript-eslint/scope-manager": "8.7.0",
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/typescript-estree": "8.7.0"
+				"@eslint-community/eslint-utils": "^4.7.0",
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/typescript-estree": "8.35.1"
 			},
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -548,17 +892,18 @@
 				"url": "https://opencollective.com/typescript-eslint"
 			},
 			"peerDependencies": {
-				"eslint": "^8.57.0 || ^9.0.0"
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.9.0"
 			}
 		},
 		"node_modules/@typescript-eslint/visitor-keys": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz",
-			"integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz",
+			"integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==",
 			"dev": true,
 			"dependencies": {
-				"@typescript-eslint/types": "8.7.0",
-				"eslint-visitor-keys": "^3.4.3"
+				"@typescript-eslint/types": "8.35.1",
+				"eslint-visitor-keys": "^4.2.1"
 			},
 			"engines": {
 				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -568,6 +913,18 @@
 				"url": "https://opencollective.com/typescript-eslint"
 			}
 		},
+		"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+			"version": "4.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+			"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+			"dev": true,
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.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",
@@ -581,9 +938,9 @@
 			"dev": true
 		},
 		"node_modules/acorn": {
-			"version": "8.12.1",
-			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
-			"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+			"version": "8.15.0",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+			"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
 			"dev": true,
 			"bin": {
 				"acorn": "bin/acorn"
@@ -1388,11 +1745,14 @@
 			}
 		},
 		"node_modules/eslint-config-wikimedia": {
-			"version": "0.28.2",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz",
-			"integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==",
+			"version": "0.31.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.31.0.tgz",
+			"integrity": "sha512-Z/t/zGPdxs/ehxb0EM6THNWAzueT7GtuqzjUvmBpkxcTKzZPJEXWnnpswdj/hgv8Ce8PIeDp0zwQxR4e3c9CIw==",
 			"dev": true,
 			"dependencies": {
+				"@stylistic/eslint-plugin": "^3.1.0",
+				"@typescript-eslint/eslint-plugin": "8.35.1",
+				"@typescript-eslint/parser": "8.35.1",
 				"browserslist-config-wikimedia": "^0.7.0",
 				"eslint": "^8.57.0",
 				"eslint-plugin-compat": "^4.2.0",
@@ -1403,13 +1763,16 @@
 				"eslint-plugin-mediawiki": "^0.7.0",
 				"eslint-plugin-mocha": "^10.4.3",
 				"eslint-plugin-n": "^17.7.0",
-				"eslint-plugin-no-jquery": "^3.0.1",
+				"eslint-plugin-no-jquery": "^3.1.1",
 				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
 				"eslint-plugin-unicorn": "^53.0.0",
 				"eslint-plugin-vue": "^9.26.0",
 				"eslint-plugin-wdio": "^8.24.12",
 				"eslint-plugin-yml": "^1.14.0"
+			},
+			"engines": {
+				"node": ">=18 <25"
 			}
 		},
 		"node_modules/eslint-plugin-compat": {
@@ -1607,9 +1970,9 @@
 			}
 		},
 		"node_modules/eslint-plugin-no-jquery": {
-			"version": "3.0.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz",
-			"integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==",
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz",
+			"integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==",
 			"dev": true,
 			"peerDependencies": {
 				"eslint": ">=8.0.0"
@@ -4577,15 +4940,15 @@
 			}
 		},
 		"node_modules/ts-api-utils": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
-			"integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+			"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
 			"dev": true,
 			"engines": {
-				"node": ">=16"
+				"node": ">=18.12"
 			},
 			"peerDependencies": {
-				"typescript": ">=4.2.0"
+				"typescript": ">=4.8.4"
 			}
 		},
 		"node_modules/type-check": {
@@ -5039,12 +5402,12 @@
 			}
 		},
 		"@eslint-community/eslint-utils": {
-			"version": "4.4.0",
-			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
-			"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+			"version": "4.9.0",
+			"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+			"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
 			"dev": true,
 			"requires": {
-				"eslint-visitor-keys": "^3.3.0"
+				"eslint-visitor-keys": "^3.4.3"
 			}
 		},
 		"@eslint-community/regexpp": {
@@ -5131,6 +5494,136 @@
 				"fastq": "^1.6.0"
 			}
 		},
+		"@stylistic/eslint-plugin": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-3.1.0.tgz",
+			"integrity": "sha512-pA6VOrOqk0+S8toJYhQGv2MWpQQR0QpeUo9AhNkC49Y26nxBQ/nH1rta9bUU1rPw2fJ1zZEMV5oCX5AazT7J2g==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/utils": "^8.13.0",
+				"eslint-visitor-keys": "^4.2.0",
+				"espree": "^10.3.0",
+				"estraverse": "^5.3.0",
+				"picomatch": "^4.0.2"
+			},
+			"dependencies": {
+				"@typescript-eslint/project-service": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.45.0.tgz",
+					"integrity": "sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/tsconfig-utils": "^8.45.0",
+						"@typescript-eslint/types": "^8.45.0",
+						"debug": "^4.3.4"
+					}
+				},
+				"@typescript-eslint/scope-manager": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.45.0.tgz",
+					"integrity": "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/types": "8.45.0",
+						"@typescript-eslint/visitor-keys": "8.45.0"
+					}
+				},
+				"@typescript-eslint/tsconfig-utils": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.45.0.tgz",
+					"integrity": "sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==",
+					"dev": true,
+					"requires": {}
+				},
+				"@typescript-eslint/types": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.45.0.tgz",
+					"integrity": "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==",
+					"dev": true
+				},
+				"@typescript-eslint/typescript-estree": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.45.0.tgz",
+					"integrity": "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/project-service": "8.45.0",
+						"@typescript-eslint/tsconfig-utils": "8.45.0",
+						"@typescript-eslint/types": "8.45.0",
+						"@typescript-eslint/visitor-keys": "8.45.0",
+						"debug": "^4.3.4",
+						"fast-glob": "^3.3.2",
+						"is-glob": "^4.0.3",
+						"minimatch": "^9.0.4",
+						"semver": "^7.6.0",
+						"ts-api-utils": "^2.1.0"
+					}
+				},
+				"@typescript-eslint/utils": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.45.0.tgz",
+					"integrity": "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==",
+					"dev": true,
+					"requires": {
+						"@eslint-community/eslint-utils": "^4.7.0",
+						"@typescript-eslint/scope-manager": "8.45.0",
+						"@typescript-eslint/types": "8.45.0",
+						"@typescript-eslint/typescript-estree": "8.45.0"
+					}
+				},
+				"@typescript-eslint/visitor-keys": {
+					"version": "8.45.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.45.0.tgz",
+					"integrity": "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/types": "8.45.0",
+						"eslint-visitor-keys": "^4.2.1"
+					}
+				},
+				"brace-expansion": {
+					"version": "2.0.2",
+					"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+					"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+					"dev": true,
+					"requires": {
+						"balanced-match": "^1.0.0"
+					}
+				},
+				"eslint-visitor-keys": {
+					"version": "4.2.1",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+					"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+					"dev": true
+				},
+				"espree": {
+					"version": "10.4.0",
+					"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+					"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+					"dev": true,
+					"requires": {
+						"acorn": "^8.15.0",
+						"acorn-jsx": "^5.3.2",
+						"eslint-visitor-keys": "^4.2.1"
+					}
+				},
+				"minimatch": {
+					"version": "9.0.5",
+					"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+					"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+					"dev": true,
+					"requires": {
+						"brace-expansion": "^2.0.1"
+					}
+				},
+				"picomatch": {
+					"version": "4.0.3",
+					"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+					"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+					"dev": true
+				}
+			}
+		},
 		"@stylistic/stylelint-config": {
 			"version": "2.0.0",
 			"resolved": "https://registry.npmjs.org/@stylistic/stylelint-config/-/stylelint-config-2.0.0.tgz",
@@ -5198,36 +5691,106 @@
 			"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
 			"dev": true
 		},
+		"@typescript-eslint/eslint-plugin": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.1.tgz",
+			"integrity": "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==",
+			"dev": true,
+			"requires": {
+				"@eslint-community/regexpp": "^4.10.0",
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/type-utils": "8.35.1",
+				"@typescript-eslint/utils": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
+				"graphemer": "^1.4.0",
+				"ignore": "^7.0.0",
+				"natural-compare": "^1.4.0",
+				"ts-api-utils": "^2.1.0"
+			},
+			"dependencies": {
+				"ignore": {
+					"version": "7.0.5",
+					"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+					"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+					"dev": true
+				}
+			}
+		},
+		"@typescript-eslint/parser": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.1.tgz",
+			"integrity": "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/typescript-estree": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
+				"debug": "^4.3.4"
+			}
+		},
+		"@typescript-eslint/project-service": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.1.tgz",
+			"integrity": "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/tsconfig-utils": "^8.35.1",
+				"@typescript-eslint/types": "^8.35.1",
+				"debug": "^4.3.4"
+			}
+		},
 		"@typescript-eslint/scope-manager": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz",
-			"integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.1.tgz",
+			"integrity": "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==",
 			"dev": true,
 			"requires": {
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/visitor-keys": "8.7.0"
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1"
+			}
+		},
+		"@typescript-eslint/tsconfig-utils": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz",
+			"integrity": "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==",
+			"dev": true,
+			"requires": {}
+		},
+		"@typescript-eslint/type-utils": {
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz",
+			"integrity": "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==",
+			"dev": true,
+			"requires": {
+				"@typescript-eslint/typescript-estree": "8.35.1",
+				"@typescript-eslint/utils": "8.35.1",
+				"debug": "^4.3.4",
+				"ts-api-utils": "^2.1.0"
 			}
 		},
 		"@typescript-eslint/types": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz",
-			"integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.1.tgz",
+			"integrity": "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==",
 			"dev": true
 		},
 		"@typescript-eslint/typescript-estree": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz",
-			"integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.1.tgz",
+			"integrity": "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==",
 			"dev": true,
 			"requires": {
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/visitor-keys": "8.7.0",
+				"@typescript-eslint/project-service": "8.35.1",
+				"@typescript-eslint/tsconfig-utils": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/visitor-keys": "8.35.1",
 				"debug": "^4.3.4",
 				"fast-glob": "^3.3.2",
 				"is-glob": "^4.0.3",
 				"minimatch": "^9.0.4",
 				"semver": "^7.6.0",
-				"ts-api-utils": "^1.3.0"
+				"ts-api-utils": "^2.1.0"
 			},
 			"dependencies": {
 				"brace-expansion": {
@@ -5251,25 +5814,33 @@
 			}
 		},
 		"@typescript-eslint/utils": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz",
-			"integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.1.tgz",
+			"integrity": "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==",
 			"dev": true,
 			"requires": {
-				"@eslint-community/eslint-utils": "^4.4.0",
-				"@typescript-eslint/scope-manager": "8.7.0",
-				"@typescript-eslint/types": "8.7.0",
-				"@typescript-eslint/typescript-estree": "8.7.0"
+				"@eslint-community/eslint-utils": "^4.7.0",
+				"@typescript-eslint/scope-manager": "8.35.1",
+				"@typescript-eslint/types": "8.35.1",
+				"@typescript-eslint/typescript-estree": "8.35.1"
 			}
 		},
 		"@typescript-eslint/visitor-keys": {
-			"version": "8.7.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz",
-			"integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==",
+			"version": "8.35.1",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.1.tgz",
+			"integrity": "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==",
 			"dev": true,
 			"requires": {
-				"@typescript-eslint/types": "8.7.0",
-				"eslint-visitor-keys": "^3.4.3"
+				"@typescript-eslint/types": "8.35.1",
+				"eslint-visitor-keys": "^4.2.1"
+			},
+			"dependencies": {
+				"eslint-visitor-keys": {
+					"version": "4.2.1",
+					"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+					"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+					"dev": true
+				}
 			}
 		},
 		"@ungap/structured-clone": {
@@ -5285,9 +5856,9 @@
 			"dev": true
 		},
 		"acorn": {
-			"version": "8.12.1",
-			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
-			"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+			"version": "8.15.0",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+			"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
 			"dev": true
 		},
 		"acorn-jsx": {
@@ -5859,11 +6430,14 @@
 			}
 		},
 		"eslint-config-wikimedia": {
-			"version": "0.28.2",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.28.2.tgz",
-			"integrity": "sha512-5+rdnT7wH1gpKAO6tHYThg78eMhZMruJzvqku3Y5iaEY/A7kSKLFpA/vOj/snys9fKjDHC9BXmArQh+agkOoJQ==",
+			"version": "0.31.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.31.0.tgz",
+			"integrity": "sha512-Z/t/zGPdxs/ehxb0EM6THNWAzueT7GtuqzjUvmBpkxcTKzZPJEXWnnpswdj/hgv8Ce8PIeDp0zwQxR4e3c9CIw==",
 			"dev": true,
 			"requires": {
+				"@stylistic/eslint-plugin": "^3.1.0",
+				"@typescript-eslint/eslint-plugin": "8.35.1",
+				"@typescript-eslint/parser": "8.35.1",
 				"browserslist-config-wikimedia": "^0.7.0",
 				"eslint": "^8.57.0",
 				"eslint-plugin-compat": "^4.2.0",
@@ -5874,7 +6448,7 @@
 				"eslint-plugin-mediawiki": "^0.7.0",
 				"eslint-plugin-mocha": "^10.4.3",
 				"eslint-plugin-n": "^17.7.0",
-				"eslint-plugin-no-jquery": "^3.0.1",
+				"eslint-plugin-no-jquery": "^3.1.1",
 				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
 				"eslint-plugin-unicorn": "^53.0.0",
@@ -6009,9 +6583,9 @@
 			}
 		},
 		"eslint-plugin-no-jquery": {
-			"version": "3.0.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.2.tgz",
-			"integrity": "sha512-n/+6p6PFhWDNPVLJj1463hw4OTIRBbROGcbhmtOHTgw7yihSKzkwZiQ00EJTneyeR3jRiw5lpWSMCCBhtb8t2g==",
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz",
+			"integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==",
 			"dev": true,
 			"requires": {}
 		},
@@ -8151,9 +8725,9 @@
 			}
 		},
 		"ts-api-utils": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
-			"integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+			"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
 			"dev": true,
 			"requires": {}
 		},
diff --git a/package.json b/package.json
index f459e6e..338f172 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,7 @@
 		"test": "grunt test"
 	},
 	"devDependencies": {
-		"eslint-config-wikimedia": "0.28.2",
+		"eslint-config-wikimedia": "0.31.0",
 		"grunt": "1.6.1",
 		"grunt-banana-checker": "0.13.0",
 		"grunt-eslint": "24.3.0",
diff --git a/resources/PageOwnership.js b/resources/PageOwnership.js
index f0ff809..0b1c835 100644
--- a/resources/PageOwnership.js
+++ b/resources/PageOwnership.js
@@ -59,7 +59,7 @@ $( () => {
 	function updateCheckboxes( val ) {
 
 		for ( var i in permissions[ val ] ) {
-			$( '#pageownership_form_input_permissions_' + i + ' input' ).prop( 'checked', ( val === default_role && default_permissions.indexOf( i.replace( '_', ' ' ) ) > -1 ? true : permissions[ val ][ i ].checked ) );
+			$( '#pageownership_form_input_permissions_' + i + ' input' ).prop( 'checked', ( val === default_role && default_permissions.includes( i.replace( '_', ' ' ) ) ? true : permissions[ val ][ i ].checked ) );
 			$( '#pageownership_form_input_permissions_' + i + ' input' ).prop( 'disabled', permissions[ val ][ i ].disabled );
 		}
 
diff --git a/resources/PageOwnershipPermissions.js b/resources/PageOwnershipPermissions.js
index 20d9761..2fa1e6f 100644
--- a/resources/PageOwnershipPermissions.js
+++ b/resources/PageOwnershipPermissions.js
@@ -136,11 +136,11 @@ $( () => {
 
 		var options = [];
 		for ( var i in actions ) {
-			if ( action === 'add' && selected.indexOf( i ) !== -1 ) {
+			if ( action === 'add' && selected.includes( i ) ) {
 				continue;
 			}
 
-			if ( action === 'remove' && selected.indexOf( i ) === -1 ) {
+			if ( action === 'remove' && !selected.includes( i ) ) {
 				continue;
 			}
 
@@ -168,7 +168,7 @@ $( () => {
 							messages[ actions[ i ][ ii ] ] :
 							actions[ i ][ ii ],
 						// mw.msg( 'right-' + actions[i][ii] ),
-						selected: selectedItems.indexOf( actions[ i ][ ii ] ) !== -1
+						selected: selectedItems.includes( actions[ i ][ ii ] )
 					} )
 				);
 			}
diff --git a/resources/mw.widgets.GroupsUsersMultiselectWidget.js b/resources/mw.widgets.GroupsUsersMultiselectWidget.js
index a010298..e39a962 100644
--- a/resources/mw.widgets.GroupsUsersMultiselectWidget.js
+++ b/resources/mw.widgets.GroupsUsersMultiselectWidget.js
@@ -204,7 +204,7 @@ config.inputWidget = new OO.ui.TextInputWidget({
 								// Remove usernames, which are already selected from suggestions
 								suggestions = suggestions
 									.map( ( user ) => {
-										if ( selected.indexOf( user.name ) === -1 ) {
+										if ( !selected.includes( user.name ) ) {
 											return new OO.ui.MenuOptionWidget( {
 												data: user.name,
 												label: user.name,
diff --git a/resources/mw.widgets.MultiToggleButtonWidget.js b/resources/mw.widgets.MultiToggleButtonWidget.js
index 03b5da6..d2c2b89 100644
--- a/resources/mw.widgets.MultiToggleButtonWidget.js
+++ b/resources/mw.widgets.MultiToggleButtonWidget.js
@@ -48,7 +48,7 @@
 				this.items[ i ] = new OO.ui.ToggleButtonWidget( {
 					data: i,
 					label: this.options[ i ],
-					value: config.selected.indexOf( i ) !== -1
+					value: config.selected.includes( i )
 				} );
 
 				this.items[ i ].on( 'change', () => {
-- 
2.47.3


--- end ---
Source code is licensed under the AGPL.