mediawiki/extensions/VisualData: main (log #2142361)

sourcepatches

This run took 76 seconds.

From 1612e27fdbd990147c2675f93ce82f06b2591781 Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Tue, 7 Oct 2025 05:07:57 +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.SpacingAfter
  * MediaWiki.Commenting.CommentBeforeClass.StrayStyle

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

Change-Id: Ibf7edd2fa94f012c0f8085b9de34f4723c25ea61
---
 .eslintrc.json                                |   4 +-
 .phpcs.xml                                    |   3 +
 composer.json                                 |   2 +-
 package-lock.json                             | 762 +++++++++++++++---
 package.json                                  |   2 +-
 resources/VisualDataCalendar.js               |   2 +-
 resources/VisualDataDatatables.js             |   7 +-
 resources/VisualDataFormField.js              |  11 +-
 resources/VisualDataForms.js                  |  16 +-
 resources/VisualDataFunctions.js              |  10 +-
 resources/VisualDataInputConfig.js            |   4 +-
 resources/VisualDataProcessModel.js           |   9 +-
 resources/VisualDataWindowManager.js          |   1 -
 .../Widgets/VisualDataDateTimeInputWidget.js  |   4 +-
 resources/Widgets/VisualDataMaptiler.js       |   4 +-
 .../VisualDataMenuTagSearchMultiselect.js     |   2 +-
 resources/Widgets/VisualDataTinyMCE.js        |   4 +-
 resources/Widgets/VisualDataVisualEditor.js   |   4 +-
 resources/Widgets/VisualDataintlTelInput.js   |   6 +-
 resources/slick/main.js                       |   2 +-
 20 files changed, 715 insertions(+), 144 deletions(-)

diff --git a/.eslintrc.json b/.eslintrc.json
index e1f0c03..f672fa4 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -25,7 +25,9 @@
 		"arrow-body-style": "off",
 		"implicit-arrow-linebreak": "off",
 		"no-jquery/no-extend": "off",
-		"prefer-arrow-callback": "off"
+		"prefer-arrow-callback": "off",
+		"no-jquery/no-done-fail": "warn",
+		"no-throw-literal": "warn"
 	},
 	"parserOptions": {
 		"ecmaVersion": 8
diff --git a/.phpcs.xml b/.phpcs.xml
index f4b54ff..34b0920 100644
--- a/.phpcs.xml
+++ b/.phpcs.xml
@@ -7,6 +7,9 @@
 		<exclude name="MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals" />
 		<exclude name="Squiz.Scope.MethodScope.Missing" />
 		<exclude name="Generic.Files.OneObjectStructurePerFile.MultipleFound" />
+		<exclude name="MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation" />
+		<exclude name="MediaWiki.Commenting.CommentBeforeClass.SpacingAfter" />
+		<exclude name="MediaWiki.Commenting.CommentBeforeClass.StrayStyle" />
 	</rule>
 	<file>.</file>
 	<arg name="extensions" value="php"/>
diff --git a/composer.json b/composer.json
index 754cb28..3575ee5 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 989dc12..0fda9f9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
 		"": {
 			"name": "VisualData",
 			"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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.0.tgz",
+			"integrity": "sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/tsconfig-utils": "^8.46.0",
+				"@typescript-eslint/types": "^8.46.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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.0.tgz",
+			"integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.46.0",
+				"@typescript-eslint/visitor-keys": "8.46.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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.0.tgz",
+			"integrity": "sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==",
+			"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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz",
+			"integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==",
+			"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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.0.tgz",
+			"integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/project-service": "8.46.0",
+				"@typescript-eslint/tsconfig-utils": "8.46.0",
+				"@typescript-eslint/types": "8.46.0",
+				"@typescript-eslint/visitor-keys": "8.46.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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.0.tgz",
+			"integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==",
+			"dev": true,
+			"dependencies": {
+				"@eslint-community/eslint-utils": "^4.7.0",
+				"@typescript-eslint/scope-manager": "8.46.0",
+				"@typescript-eslint/types": "8.46.0",
+				"@typescript-eslint/typescript-estree": "8.46.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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.0.tgz",
+			"integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.46.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz",
-			"integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==",
+			"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.8.0",
-				"@typescript-eslint/visitor-keys": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz",
-			"integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==",
+			"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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz",
-			"integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==",
+			"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.8.0",
-				"@typescript-eslint/visitor-keys": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz",
-			"integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==",
+			"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.8.0",
-				"@typescript-eslint/types": "8.8.0",
-				"@typescript-eslint/typescript-estree": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz",
-			"integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==",
+			"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.8.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"
@@ -4578,15 +4941,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": {
@@ -5040,12 +5403,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": {
@@ -5132,6 +5495,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.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.0.tgz",
+					"integrity": "sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/tsconfig-utils": "^8.46.0",
+						"@typescript-eslint/types": "^8.46.0",
+						"debug": "^4.3.4"
+					}
+				},
+				"@typescript-eslint/scope-manager": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.0.tgz",
+					"integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/types": "8.46.0",
+						"@typescript-eslint/visitor-keys": "8.46.0"
+					}
+				},
+				"@typescript-eslint/tsconfig-utils": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.0.tgz",
+					"integrity": "sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==",
+					"dev": true,
+					"requires": {}
+				},
+				"@typescript-eslint/types": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz",
+					"integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==",
+					"dev": true
+				},
+				"@typescript-eslint/typescript-estree": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.0.tgz",
+					"integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/project-service": "8.46.0",
+						"@typescript-eslint/tsconfig-utils": "8.46.0",
+						"@typescript-eslint/types": "8.46.0",
+						"@typescript-eslint/visitor-keys": "8.46.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.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.0.tgz",
+					"integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==",
+					"dev": true,
+					"requires": {
+						"@eslint-community/eslint-utils": "^4.7.0",
+						"@typescript-eslint/scope-manager": "8.46.0",
+						"@typescript-eslint/types": "8.46.0",
+						"@typescript-eslint/typescript-estree": "8.46.0"
+					}
+				},
+				"@typescript-eslint/visitor-keys": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.0.tgz",
+					"integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/types": "8.46.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",
@@ -5199,36 +5692,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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz",
-			"integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==",
+			"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.8.0",
-				"@typescript-eslint/visitor-keys": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz",
-			"integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==",
+			"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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz",
-			"integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==",
+			"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.8.0",
-				"@typescript-eslint/visitor-keys": "8.8.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": {
@@ -5252,25 +5815,33 @@
 			}
 		},
 		"@typescript-eslint/utils": {
-			"version": "8.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz",
-			"integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==",
+			"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.8.0",
-				"@typescript-eslint/types": "8.8.0",
-				"@typescript-eslint/typescript-estree": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz",
-			"integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==",
+			"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.8.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": {
@@ -5286,9 +5857,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": {
@@ -5860,11 +6431,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",
@@ -5875,7 +6449,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",
@@ -6010,9 +6584,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": {}
 		},
@@ -8152,9 +8726,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 53cf26d..4d15ad8 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/VisualDataCalendar.js b/resources/VisualDataCalendar.js
index 37d171f..5179cba 100644
--- a/resources/VisualDataCalendar.js
+++ b/resources/VisualDataCalendar.js
@@ -97,7 +97,7 @@ $( function () {
 				// eslint-disable-next-line no-underscore-dangle
 				var found_ = false;
 				for ( var i in params.headerToolbar ) {
-					if ( params.headerToolbar[ i ].indexOf( view_ ) !== -1 ) {
+					if ( params.headerToolbar[ i ].includes( view_ ) ) {
 						found_ = true;
 						break;
 					}
diff --git a/resources/VisualDataDatatables.js b/resources/VisualDataDatatables.js
index 47323b0..c658cd5 100644
--- a/resources/VisualDataDatatables.js
+++ b/resources/VisualDataDatatables.js
@@ -488,8 +488,7 @@ const VisualDataDatatables = function ( el, elIndex ) {
 					label: searchPanesOptions[ i ][ ii ].label,
 					value: function ( rowData, rowIdx ) {
 						return (
-							objectValues( data[ rowIdx ] )[ i ].indexOf(
-								searchPanesOptions[ i ][ ii ].value ) !== -1
+							objectValues( data[ rowIdx ] )[ i ].includes( searchPanesOptions[ i ][ ii ].value )
 						);
 					}
 				} );
@@ -1082,11 +1081,11 @@ $( function () {
 	} );
 
 	var modules = [];
-	if ( buttons.indexOf( 'pdf' ) !== -1 ) {
+	if ( buttons.includes( 'pdf' ) ) {
 		modules.push( 'ext.VisualData.Datatables.export.pdf' );
 	}
 
-	if ( buttons.indexOf( 'excel' ) !== -1 ) {
+	if ( buttons.includes( 'excel' ) ) {
 		modules.push( 'ext.VisualData.Datatables.export.excel' );
 	}
 
diff --git a/resources/VisualDataFormField.js b/resources/VisualDataFormField.js
index 48f7035..9c3a235 100644
--- a/resources/VisualDataFormField.js
+++ b/resources/VisualDataFormField.js
@@ -41,7 +41,7 @@ const VisualDataFormField = function ( phpConfig, windowManager, schemas ) {
 	var HandleQueryOptionsInt;
 
 	function inArray( val, arr ) {
-		return arr.indexOf( val ) !== -1;
+		return arr.includes( val );
 	}
 
 	function getCurrentItem() {
@@ -83,8 +83,8 @@ const VisualDataFormField = function ( phpConfig, windowManager, schemas ) {
 		// except multiselect
 		return ret.filter(
 			( x ) =>
-				( VisualDataFunctions.lookupInputs.indexOf( x ) === -1 &&
-					VisualDataFunctions.optionsInputs.indexOf( x ) === -1 ) ||
+				( !VisualDataFunctions.lookupInputs.includes( x ) &&
+					!VisualDataFunctions.optionsInputs.includes( x ) ) ||
 				VisualDataFunctions.isMultiselect( x )
 		);
 	}
@@ -99,8 +99,8 @@ const VisualDataFormField = function ( phpConfig, windowManager, schemas ) {
 
 			} else {
 				var visibleSharedOptions =
-					Object.keys( HandleOptionsInputsInt.modelMap ).indexOf( i ) !== -1 &&
-					Object.keys( HandleQueryOptionsInt.modelMap ).indexOf( i ) !== -1 &&
+					Object.keys( HandleOptionsInputsInt.modelMap ).includes( i ) &&
+					Object.keys( HandleQueryOptionsInt.modelMap ).includes( i ) &&
 					( optionsHasVisibleItems || queryHasVisibleItems );
 
 				if ( !visibleSharedOptions ) {
@@ -1112,7 +1112,6 @@ const VisualDataFormField = function ( phpConfig, windowManager, schemas ) {
 			var thisAvailableInputsValue = availableInputsInput.getValue();
 			var thisDefaultValueInput = getDefaultValueInput();
 
-			// eslint-disable-next-line no-use-before-define
 			Model.default = defaultValueInput;
 
 			if (
diff --git a/resources/VisualDataForms.js b/resources/VisualDataForms.js
index 2cab4d8..0744c5b 100644
--- a/resources/VisualDataForms.js
+++ b/resources/VisualDataForms.js
@@ -22,8 +22,6 @@
 /* eslint-disable no-tabs */
 /* eslint-disable no-unused-vars */
 /* eslint-disable no-underscore-dangle */
-/* eslint-disable es-x/no-async-functions */
-/* eslint-disable compat/compat */
 
 const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowManager, initForms ) {
 	var Model = {};
@@ -59,7 +57,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 	var FormID;
 
 	function inArray( val, arr ) {
-		return arr.indexOf( val ) !== -1;
+		return arr.includes( val );
 	}
 
 	function escapeJsonPointer( str ) {
@@ -386,10 +384,10 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 						res = ( value.indexOf( refValue ) !== 0 );
 						break;
 					case 'contains':
-						res = ( value.indexOf( refValue ) !== -1 );
+						res = ( value.includes( refValue ) );
 						break;
 					case '!contains':
-						res = ( value.indexOf( refValue ) === -1 );
+						res = ( !value.includes( refValue ) );
 						break;
 					case 'ends':
 						var regExp = new RegExp( escapeRegExp( refValue ) + '$' );
@@ -529,7 +527,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 											);
 										}
 										model.input.addOptions( items );
-										model.input.setValue( values.filter( ( x ) => Object.keys( data_ ).indexOf( x ) !== -1 ) );
+										model.input.setValue( values.filter( ( x ) => Object.keys( data_ ).includes( x ) ) );
 										break;
 								}
 							} );
@@ -638,7 +636,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 
 			var subquery = [];
 			for ( var value of arr ) {
-				if ( value.indexOf( '::' ) === -1 ) {
+				if ( !value.includes( '::' ) ) {
 					var trimmed = value.trim();
 					var match_ = trimmed.match( /<([^<>]+)>/ );
 
@@ -1044,7 +1042,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 			if ( value ) {
 				var valueLowerCase = value.toLowerCase();
 				values = values.filter(
-					( x ) => x.toLowerCase().indexOf( valueLowerCase ) !== -1
+					( x ) => x.toLowerCase().includes( valueLowerCase )
 				);
 			}
 
@@ -1787,7 +1785,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 
 				Form.schemas = Form.schemas.filter( ( x ) => x in Schemas );
 
-				if ( !SelectedSchema || Form.schemas.indexOf( SelectedSchema ) === -1 ) {
+				if ( !SelectedSchema || !Form.schemas.includes( SelectedSchema ) ) {
 					// @credits https://gerrit.wikimedia.org/r/c/mediawiki/extensions/VisualData/+/1034934
 					if ( 'selected-schema' in Form.options &&
 						Form.options[ 'selected-schema' ] !== '' &&
diff --git a/resources/VisualDataFunctions.js b/resources/VisualDataFunctions.js
index d796c36..10f96bc 100644
--- a/resources/VisualDataFunctions.js
+++ b/resources/VisualDataFunctions.js
@@ -109,7 +109,7 @@ VisualDataFunctions = ( function () {
 
 			case 'boolean':
 				if ( typeof value === 'string' ) {
-					value = [ 'true', 't', '1', 'on', 'yes', 'y' ].indexOf( value ) !== -1;
+					value = [ 'true', 't', '1', 'on', 'yes', 'y' ].includes( value );
 				} else {
 					value = !!value;
 				}
@@ -283,7 +283,7 @@ VisualDataFunctions = ( function () {
 		console.log( '' );
 
 		// @TODO redirect to the extension page for docs on specific inputs
-		if ( inputName.indexOf( 'OO.' ) === -1 && inputName.indexOf( 'mw.' ) === -1 ) {
+		if ( !inputName.includes( 'OO.' ) && !inputName.includes( 'mw.' ) ) {
 			return null;
 		}
 		// or `https://doc.wikimedia.org/oojs-ui/master/js/${inputName}.html`
@@ -292,7 +292,7 @@ VisualDataFunctions = ( function () {
 
 	function isMultiselect( inputName ) {
 		// return inArray(inputName, ManageProperties.multiselectInputs))
-		return inputName.indexOf( 'Multiselect' ) !== -1;
+		return inputName.includes( 'Multiselect' );
 	}
 
 	function inputInstanceFromName( inputName, config ) {
@@ -504,7 +504,7 @@ VisualDataFunctions = ( function () {
 	}
 
 	function inArray( val, arr ) {
-		return arr.indexOf( val ) !== -1;
+		return arr.includes( val );
 	}
 
 	function getKeyByValue( obj, value ) {
@@ -897,7 +897,7 @@ VisualDataFunctions = ( function () {
 	function arrayIntersect( arr1, arr2 ) {
 		var ret = [];
 		for ( var x of arr1 ) {
-			if ( arr2.indexOf( x ) !== -1 ) {
+			if ( arr2.includes( x ) ) {
 				ret.push( x );
 			}
 		}
diff --git a/resources/VisualDataInputConfig.js b/resources/VisualDataInputConfig.js
index 5f5616d..3e3cace 100644
--- a/resources/VisualDataInputConfig.js
+++ b/resources/VisualDataInputConfig.js
@@ -39,7 +39,7 @@ const VisualDataInputConfig = function ( phpConfig, windowManager ) {
 	var HelpUrl;
 
 	function inArray( val, arr ) {
-		return arr.indexOf( val ) !== -1;
+		return arr.includes( val );
 	}
 
 	// @TODO add default for each of them
@@ -945,7 +945,7 @@ const VisualDataInputConfig = function ( phpConfig, windowManager ) {
 			if ( value ) {
 				var valueLowerCase = value.toLowerCase();
 				values = values.filter(
-					( x ) => x.toLowerCase().indexOf( valueLowerCase ) !== -1
+					( x ) => x.toLowerCase().includes( valueLowerCase )
 				);
 			}
 
diff --git a/resources/VisualDataProcessModel.js b/resources/VisualDataProcessModel.js
index a68d216..3fd09de 100644
--- a/resources/VisualDataProcessModel.js
+++ b/resources/VisualDataProcessModel.js
@@ -19,7 +19,6 @@
  * @copyright Copyright © 2023, https://wikisphere.org
  */
 
-/* eslint-disable no-tabs */
 /* eslint-disable no-unused-vars */
 /* eslint-disable no-underscore-dangle */
 
@@ -176,10 +175,10 @@ const VisualDataProcessModel = function (
 			for ( var error of validateAjv.errors ) {
 				switch ( error.keyword ) {
 					case 'uniqueItems':
-						if ( Removed.indexOf( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.j }` ) === -1 ) {
+						if ( !Removed.includes( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.j }` ) ) {
 							AjvErrors.push( $.extend( VisualDataFunctions.deepCopy( error ), { instancePath: `${ error.instancePath }/${ error.params.i }` } ) );
 						}
-						if ( Removed.indexOf( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.i }` ) === -1 ) {
+						if ( !Removed.includes( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.i }` ) ) {
 							AjvErrors.push( $.extend( VisualDataFunctions.deepCopy( error ), { instancePath: `${ error.instancePath }/${ error.params.j }` } ) );
 						}
 						break;
@@ -328,7 +327,7 @@ const VisualDataProcessModel = function (
 
 				try {
 					for ( var schemaName in ModelSchemas ) {
-						if ( Form.schemas.indexOf( schemaName ) === -1 ) {
+						if ( !Form.schemas.includes( schemaName ) ) {
 							continue;
 						}
 						ret[ schemaName ] = await getValuesRec(
@@ -359,7 +358,7 @@ const VisualDataProcessModel = function (
 
 			case 'submit':
 				for ( var schemaName in ModelSchemas ) {
-					if ( Form.schemas.indexOf( schemaName ) === -1 ) {
+					if ( !Form.schemas.includes( schemaName ) ) {
 						continue;
 					}
 					ret[ schemaName ] = await getValuesRec(
diff --git a/resources/VisualDataWindowManager.js b/resources/VisualDataWindowManager.js
index 9f4b647..aca33ee 100644
--- a/resources/VisualDataWindowManager.js
+++ b/resources/VisualDataWindowManager.js
@@ -20,7 +20,6 @@
  */
 
 // @see https://doc.wikimedia.org/oojs-ui/master/js/
-// eslint-disable-next-line no-unused-vars
 
 // eslint-disable-next-line no-implicit-globals
 VisualDataWindowManager = function () {
diff --git a/resources/Widgets/VisualDataDateTimeInputWidget.js b/resources/Widgets/VisualDataDateTimeInputWidget.js
index 27e8324..1cd7476 100644
--- a/resources/Widgets/VisualDataDateTimeInputWidget.js
+++ b/resources/Widgets/VisualDataDateTimeInputWidget.js
@@ -19,8 +19,6 @@
  * @copyright Copyright ©2025, https://wikisphere.org
  */
 
-/* eslint-disable no-tabs */
-
 ( function () {
 	// eslint-disable-next-line no-implicit-globals
 	VisualDataDateTimeInputWidget = function ( config ) {
@@ -67,7 +65,7 @@
 
 		// const m = /^(\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?Z$/.exec( value );
 		// ***edited, matches both +01:00 (ISO 8601 vP) and +0100 (ISO 8601 vO)
-		// eslint-disable-next-line security/detect-unsafe-regex
+
 		const m = /^(\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?(Z|[+-]\d{2}:?\d{2}|[+-]\d{4})?$/.exec( value );
 
 		if ( m ) {
diff --git a/resources/Widgets/VisualDataMaptiler.js b/resources/Widgets/VisualDataMaptiler.js
index 18a4206..29294f3 100644
--- a/resources/Widgets/VisualDataMaptiler.js
+++ b/resources/Widgets/VisualDataMaptiler.js
@@ -40,7 +40,7 @@
 		// only load scripts
 		if ( !$element.parent().is( ':visible' ) ) {
 			VisualDataFunctions.loadScripts( this.scripts );
-			return Promise.reject( 'Maptiler element not visible' );
+			throw 'Maptiler element not visible';
 		}
 
 		// *** prevents ajv error "Maximum call stack size exceeded"
@@ -51,7 +51,7 @@
 		var mapId = 'visualdata-maptiler-map-' + data.path;
 
 		if ( $( '#' + jQuery.escapeSelector( mapId ) ).length ) {
-			return Promise.resolve();
+			return;
 		}
 
 		return new Promise( ( resolve, reject ) => {
diff --git a/resources/Widgets/VisualDataMenuTagSearchMultiselect.js b/resources/Widgets/VisualDataMenuTagSearchMultiselect.js
index faa6552..d920a83 100644
--- a/resources/Widgets/VisualDataMenuTagSearchMultiselect.js
+++ b/resources/Widgets/VisualDataMenuTagSearchMultiselect.js
@@ -111,7 +111,7 @@
 
 					// Remove if items' data already exists
 					for ( var i in items ) {
-						if ( existingItems.indexOf( i ) !== -1 ) {
+						if ( existingItems.includes( i ) ) {
 							delete items[ i ];
 						}
 					}
diff --git a/resources/Widgets/VisualDataTinyMCE.js b/resources/Widgets/VisualDataTinyMCE.js
index fbf907a..4e71a44 100644
--- a/resources/Widgets/VisualDataTinyMCE.js
+++ b/resources/Widgets/VisualDataTinyMCE.js
@@ -59,13 +59,13 @@
 	VisualDataTinyMCE.prototype.initialize = async function () {
 		var self = this;
 		if ( self.initialized ) {
-			return Promise.resolve();
+			return;
 		}
 
 		// only load scripts
 		if ( !self.$element.parent().is( ':visible' ) ) {
 			VisualDataFunctions.loadScripts( this.scripts );
-			return Promise.reject( 'TinyMCE element not visible' );
+			throw 'TinyMCE element not visible';
 		}
 
 		return new Promise( ( resolve, reject ) => {
diff --git a/resources/Widgets/VisualDataVisualEditor.js b/resources/Widgets/VisualDataVisualEditor.js
index 6c25230..0776dfe 100644
--- a/resources/Widgets/VisualDataVisualEditor.js
+++ b/resources/Widgets/VisualDataVisualEditor.js
@@ -61,13 +61,13 @@
 		var self = this;
 
 		if ( this.isInitialized() || this.initializing ) {
-			return Promise.resolve( true );
+			return true;
 		}
 
 		this.initializing = true;
 
 		if ( !self.$element.parent().is( ':visible' ) ) {
-			return Promise.reject( 'VEForAll element not visible' );
+			throw 'VEForAll element not visible';
 		}
 
 		return new Promise( ( resolve, reject ) => {
diff --git a/resources/Widgets/VisualDataintlTelInput.js b/resources/Widgets/VisualDataintlTelInput.js
index 2c8a9e5..b077258 100644
--- a/resources/Widgets/VisualDataintlTelInput.js
+++ b/resources/Widgets/VisualDataintlTelInput.js
@@ -164,7 +164,7 @@
 		];
 
 		if (
-			!Object.keys( config ).filter( ( x ) => configCountries.indexOf( x ) !== -1 )
+			!Object.keys( config ).filter( ( x ) => configCountries.includes( x ) )
 				.length
 		) {
 			return;
@@ -181,7 +181,7 @@
 			if ( i in config ) {
 				if ( i === 'initialCountry' ) {
 					config[ i ] = config[ i ].toLowerCase();
-					if ( iso2.indexOf( config[ i ] ) === -1 ) {
+					if ( !iso2.includes( config[ i ] ) ) {
 						// eslint-disable-next-line no-console
 						console.error( config[ i ] + ' is not a valid country code' );
 						delete config[ i ];
@@ -190,7 +190,7 @@
 				}
 				var values = [];
 				for ( var ii of config[ i ] ) {
-					if ( iso2.indexOf( ii ) === -1 ) {
+					if ( !iso2.includes( ii ) ) {
 						// eslint-disable-next-line no-console
 						console.error( ii + ' is not a valid country code' );
 						values.splice( ii, 1 );
diff --git a/resources/slick/main.js b/resources/slick/main.js
index 731c622..699c8d8 100644
--- a/resources/slick/main.js
+++ b/resources/slick/main.js
@@ -54,7 +54,7 @@
 			if ( $( this ).attr( 'data-url' ) ) {
 				// $(this).attr('title', $(this).attr('data-title') )
 				$( this ).css( 'cursor', 'pointer' );
-				$( this ).click( function () {
+				$( this ).on( 'click', function () {
 					window.location = $( this ).attr( 'data-url' );
 				} );
 			}
-- 
2.47.3

$ date
--- stdout ---
Tue Oct  7 05:06:57 UTC 2025

--- end ---
$ git clone file:///srv/git/mediawiki-extensions-VisualData.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 ---
1b6b0d3299473dc588d45e554a91bc8c56ff1b8c 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: 22 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 swaggest/json-diff (v3.12.1)
  - 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: 22 installs, 0 updates, 0 removals
  - Downloading swaggest/json-diff (v3.12.1)
 0/1 [>---------------------------]   0%
 1/1 [============================] 100%
  - 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
  - Installing swaggest/json-diff (v3.12.1): Extracting archive
  0/20 [>---------------------------]   0%
 20/20 [============================] 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 6s

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/VisualDataFormField.js package-lock.json Gruntfile.js resources/Widgets/VisualDataDropdownWidget.js resources/Widgets/VisualDataintlTelInput.js resources/VisualDataForms.js resources/VisualDataSchemas.js resources/VisualDataContentBlock.js resources/VisualDataUpload.js resources/VersionCheck.js resources/Widgets/VisualDataDateTimeInputWidget.js resources/VisualDataDatatables.js resources/VisualDataInputConfig.js i18n/en.json resources/VisualDataFunctions.js resources/VisualDataCalendar.js resources/Widgets/VisualDataLookupElement.js i18n/de.json resources/VisualDataMaps.js package.json resources/Widgets/VisualDataMaptiler.js resources/Widgets/VisualDataMenuTagSearchMultiselect.js resources/Widgets/VisualDataTinyMCE.js composer.json extension.json i18n/qqq.json resources/slick/main.js resources/Widgets/VisualDataButtonMultiselectWidget.js resources/VisualDataWindowManager.js resources/VisualDataPrintouts.js resources/VisualDataProcessModel.js resources/VisualDataGeolocation.js resources/Widgets/VisualDataVisualEditor.js resources/VisualData.js resources/Widgets/VisualDataRatingWidget.js --fix
--- stdout ---

/src/repo/resources/VersionCheck.js
  31:3   error    Prefer .then to .done                                                               no-jquery/no-done-fail
  57:22  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  62:18  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  65:9   warning  Where possible, maintain application state in JS to avoid slower DOM queries        no-jquery/no-class-state

/src/repo/resources/VisualData.js
  56:4  error  Prefer .then to .done  no-jquery/no-done-fail
  56:4  error  Prefer .then to .fail  no-jquery/no-done-fail
  92:4  error  Prefer .then to .done  no-jquery/no-done-fail
  92:4  error  Prefer .then to .fail  no-jquery/no-done-fail

/src/repo/resources/VisualDataCalendar.js
  134:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataDatatables.js
    27:6  warning  jQuery collection names must match the variablePattern                              no-jquery/variable-pattern
    43:1  warning  This line has a length of 144. Maximum allowed is 100                               max-len
    59:1  warning  This line has a length of 111. Maximum allowed is 100                               max-len
   140:1  warning  This line has a length of 101. Maximum allowed is 100                               max-len
   173:3  error    Prefer .then to .done                                                               no-jquery/no-done-fail
   173:3  error    Prefer .then to .fail                                                               no-jquery/no-done-fail
   242:1  warning  This line has a length of 112. Maximum allowed is 100                               max-len
   279:3  error    Prefer .then to .done                                                               no-jquery/no-done-fail
   279:3  error    Prefer .then to .fail                                                               no-jquery/no-done-fail
   358:5  warning  Prefer Array#indexOf to $.inArray                                                   no-jquery/no-in-array
   491:1  warning  This line has a length of 111. Maximum allowed is 100                               max-len
   640:8  warning  Prefer Array#indexOf to $.inArray                                                   no-jquery/no-in-array
   681:1  warning  This line has a length of 119. Maximum allowed is 100                               max-len
   686:8  warning  Expected a 'break' statement before 'case'                                          no-fallthrough
   690:8  warning  Expected a 'break' statement before 'case'                                          no-fallthrough
   692:8  warning  Expected a 'break' statement before 'case'                                          no-fallthrough
   757:1  warning  This line has a length of 143. Maximum allowed is 100                               max-len
  1076:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  1093:3  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataFormField.js
   284:1  warning  This line has a length of 108. Maximum allowed is 100                               max-len
   300:1  warning  This line has a length of 135. Maximum allowed is 100                               max-len
  1042:4  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataForms.js
    26:1   warning  This line has a length of 101. Maximum allowed is 100                               max-len
    79:6   warning  Selector extensions are not allowed                                                 no-jquery/no-sizzle
   213:5   warning  Selector extensions are not allowed                                                 no-jquery/no-sizzle
   513:1   warning  This line has a length of 117. Maximum allowed is 100                               max-len
   530:1   warning  This line has a length of 125. Maximum allowed is 100                               max-len
   577:5   error    Prefer .then to .done                                                               no-jquery/no-done-fail
   577:5   error    Prefer .then to .fail                                                               no-jquery/no-done-fail
   878:5   error    Prefer .then to .done                                                               no-jquery/no-done-fail
   878:5   error    Prefer .then to .fail                                                               no-jquery/no-done-fail
   969:5   error    Prefer .then to .fail                                                               no-jquery/no-done-fail
  1007:8   warning  jQuery collection names must match the variablePattern                              no-jquery/variable-pattern
  1007:17  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  1456:4   warning  jQuery collection names must match the variablePattern                              no-jquery/variable-pattern
  1458:26  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  2185:5   warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  2333:1   warning  This line has a length of 117. Maximum allowed is 100                               max-len
  2370:1   warning  This line has a length of 127. Maximum allowed is 100                               max-len
  2582:1   warning  This line has a length of 109. Maximum allowed is 100                               max-len
  2916:1   warning  This line has a length of 102. Maximum allowed is 100                               max-len
  2934:7   warning  jQuery collection names must match the variablePattern                              no-jquery/variable-pattern
  3102:9   error    Prefer .then to .done                                                               no-jquery/no-done-fail
  3102:9   error    Prefer .then to .fail                                                               no-jquery/no-done-fail
  3107:1   warning  This line has a length of 102. Maximum allowed is 100                               max-len
  3231:10  warning  Selector extensions are not allowed                                                 no-jquery/no-sizzle
  3381:1   warning  This line has a length of 108. Maximum allowed is 100                               max-len
  3386:1   warning  This line has a length of 105. Maximum allowed is 100                               max-len
  3601:15  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  3625:1   warning  This line has a length of 119. Maximum allowed is 100                               max-len
  3672:3   warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  3716:3   warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataInputConfig.js
  840:1  warning  This line has a length of 110. Maximum allowed is 100  max-len

/src/repo/resources/VisualDataMaps.js
   35:1  warning  This line has a length of 108. Maximum allowed is 100                               max-len
  119:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataPrintouts.js
  43:1  warning  This line has a length of 107. Maximum allowed is 100                               max-len
  56:1  warning  This line has a length of 144. Maximum allowed is 100                               max-len
  71:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  75:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataProcessModel.js
  222:1   warning  This line has a length of 116. Maximum allowed is 100  max-len
  226:11  warning  Selector extensions are not allowed                    no-jquery/no-sizzle

/src/repo/resources/VisualDataSchemas.js
   325:1   warning  This line has a length of 103. Maximum allowed is 100                               max-len
   640:8   error    Prefer .then to .done                                                               no-jquery/no-done-fail
   640:8   error    Prefer .then to .fail                                                               no-jquery/no-done-fail
  1608:15  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  1785:4   warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  1788:15  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  1804:4   warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataUpload.js
  128:3  error  Prefer .then to .fail  no-jquery/no-done-fail
  280:3  error  Prefer .then to .done  no-jquery/no-done-fail
  280:3  error  Prefer .then to .fail  no-jquery/no-done-fail
  369:3  error  Prefer .then to .done  no-jquery/no-done-fail
  369:3  error  Prefer .then to .fail  no-jquery/no-done-fail

/src/repo/resources/Widgets/VisualDataButtonMultiselectWidget.js
  48:12  warning  Prefer Array#indexOf to $.inArray  no-jquery/no-in-array

/src/repo/resources/Widgets/VisualDataDateTimeInputWidget.js
  66:1  warning  This line has a length of 105. Maximum allowed is 100  max-len

/src/repo/resources/Widgets/VisualDataDropdownWidget.js
  38:7  warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  53:7  warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern

/src/repo/resources/Widgets/VisualDataMaptiler.js
  41:9  warning  Selector extensions are not allowed                    no-jquery/no-sizzle
  43:4  error    Expected an error object to be thrown                  no-throw-literal
  66:1  warning  This line has a length of 102. Maximum allowed is 100  max-len
  68:1  warning  This line has a length of 123. Maximum allowed is 100  max-len

/src/repo/resources/Widgets/VisualDataMenuTagSearchMultiselect.js
  29:1  warning  Invalid JSDoc tag name "mixins"                        jsdoc/check-tag-names
  49:1  warning  This line has a length of 110. Maximum allowed is 100  max-len
  50:1  warning  This line has a length of 107. Maximum allowed is 100  max-len

/src/repo/resources/Widgets/VisualDataRatingWidget.js
  38:19  warning  Prefer DOM building to parsing HTML literals            no-jquery/no-parse-html-literal
  45:8   warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  67:6   warning  Selector extensions are not allowed                     no-jquery/no-sizzle

/src/repo/resources/Widgets/VisualDataTinyMCE.js
  39:3   warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  39:19  warning  Prefer DOM building to parsing HTML literals            no-jquery/no-parse-html-literal
  66:9   warning  Selector extensions are not allowed                     no-jquery/no-sizzle
  68:4   error    Expected an error object to be thrown                   no-throw-literal

/src/repo/resources/Widgets/VisualDataVisualEditor.js
  40:3   warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  40:19  warning  Prefer DOM building to parsing HTML literals            no-jquery/no-parse-html-literal
  47:3   warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  69:9   warning  Selector extensions are not allowed                     no-jquery/no-sizzle
  70:4   error    Expected an error object to be thrown                   no-throw-literal

/src/repo/resources/Widgets/VisualDataintlTelInput.js
  38:7  warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern

/src/repo/resources/slick/main.js
  24:3  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  25:4  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  45:3  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  64:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

✖ 110 problems (26 errors, 84 warnings)


--- end ---
$ ./node_modules/.bin/eslint resources/VisualDataFormField.js package-lock.json Gruntfile.js resources/Widgets/VisualDataDropdownWidget.js resources/Widgets/VisualDataintlTelInput.js resources/VisualDataForms.js resources/VisualDataSchemas.js resources/VisualDataContentBlock.js resources/VisualDataUpload.js resources/VersionCheck.js resources/Widgets/VisualDataDateTimeInputWidget.js resources/VisualDataDatatables.js resources/VisualDataInputConfig.js i18n/en.json resources/VisualDataFunctions.js resources/VisualDataCalendar.js resources/Widgets/VisualDataLookupElement.js i18n/de.json resources/VisualDataMaps.js package.json resources/Widgets/VisualDataMaptiler.js resources/Widgets/VisualDataMenuTagSearchMultiselect.js resources/Widgets/VisualDataTinyMCE.js composer.json extension.json i18n/qqq.json resources/slick/main.js resources/Widgets/VisualDataButtonMultiselectWidget.js resources/VisualDataWindowManager.js resources/VisualDataPrintouts.js resources/VisualDataProcessModel.js resources/VisualDataGeolocation.js resources/Widgets/VisualDataVisualEditor.js resources/VisualData.js resources/Widgets/VisualDataRatingWidget.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":"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":"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":"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/de.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":"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":"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":"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":"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":"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/VersionCheck.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":31,"column":3,"nodeType":"CallExpression","endLine":80,"endColumn":7},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":57,"column":22,"nodeType":"CallExpression","endLine":57,"endColumn":45},{"ruleId":"no-jquery/no-parse-html-literal","severity":1,"message":"Prefer DOM building to parsing HTML literals","line":62,"column":18,"nodeType":"CallExpression","endLine":62,"endColumn":41},{"ruleId":"no-jquery/no-class-state","severity":1,"message":"Where possible, maintain application state in JS to avoid slower DOM queries","line":65,"column":9,"nodeType":"CallExpression","endLine":65,"endColumn":75}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. 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$( function () {\n\tif (\n\t\t!mw.config.get( 'visualdata-show-notice-outdated-version' ) ||\n\t\tmw.cookie.get( 'visualdata-check-latest-version' )\n\t) {\n\t\treturn;\n\t}\n\n\t// display every 3 days\n\tmw.loader.using( 'mediawiki.api', function () {\n\t\tnew mw.Api()\n\t\t\t.postWithToken( 'csrf', {\n\t\t\t\taction: 'visualdata-check-latest-version'\n\t\t\t} )\n\t\t\t.done( function ( res ) {\n\t\t\t\tif ( 'visualdata-check-latest-version' in res ) {\n\t\t\t\t\tif ( res[ 'visualdata-check-latest-version' ].result === 2 ) {\n\t\t\t\t\t\tvar messageWidget = new OO.ui.MessageWidget( {\n\t\t\t\t\t\t\ttype: 'warning',\n\t\t\t\t\t\t\tlabel: new OO.ui.HtmlSnippet(\n\t\t\t\t\t\t\t\tmw.msg(\n\t\t\t\t\t\t\t\t\t'visualdata-jsmodule-outdated-version'\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// *** this does not work before ooui v0.43.0\n\t\t\t\t\t\t\tshowClose: true\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tvar closeFunction = function () {\n\t\t\t\t\t\t\tvar three_days = 3 * 86400;\n\t\t\t\t\t\t\tmw.cookie.set( 'visualdata-check-latest-version', true, {\n\t\t\t\t\t\t\t\tpath: '/',\n\t\t\t\t\t\t\t\texpires: three_days\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t$( messageWidget.$element ).parent().remove();\n\t\t\t\t\t\t};\n\t\t\t\t\t\tmessageWidget.on( 'close', closeFunction );\n\t\t\t\t\t\tvar selector = $( '#schemas-wrapper' ).length ?\n\t\t\t\t\t\t\t'#schemas-wrapper' :\n\t\t\t\t\t\t\t'.VisualDataFormWrapper';\n\t\t\t\t\t\t$( selector )\n\t\t\t\t\t\t\t.first()\n\t\t\t\t\t\t\t.prepend( $( '<div><br/></div>' ).prepend( messageWidget.$element ) );\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!messageWidget.$element.hasClass( 'oo-ui-messageWidget-showClose' )\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tmessageWidget.$element.addClass( 'oo-ui-messageWidget-showClose' );\n\t\t\t\t\t\t\tvar closeButton = new OO.ui.ButtonWidget( {\n\t\t\t\t\t\t\t\tclasses: [ 'oo-ui-messageWidget-close' ],\n\t\t\t\t\t\t\t\tframed: false,\n\t\t\t\t\t\t\t\ticon: 'close',\n\t\t\t\t\t\t\t\tlabel: OO.ui.msg( 'ooui-popup-widget-close-button-aria-label' ),\n\t\t\t\t\t\t\t\tinvisibleLabel: true\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\tcloseButton.on( 'click', closeFunction );\n\t\t\t\t\t\t\tmessageWidget.$element.append( closeButton.$element );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\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":"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/VisualData.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":56,"column":4,"nodeType":"CallExpression","endLine":72,"endColumn":8},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":56,"column":4,"nodeType":"CallExpression","endLine":77,"endColumn":8},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":92,"column":4,"nodeType":"CallExpression","endLine":115,"endColumn":8},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":92,"column":4,"nodeType":"CallExpression","endLine":120,"endColumn":8}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":25,"column":1,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":178,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":75,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":75,"endColumn":19,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[2331,2382],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":81,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":81,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":118,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":118,"endColumn":19,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[3574,3621],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":4,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2021-2024, https://wikisphere.org\n */\n\n/* eslint-disable no-tabs */\n\n// eslint-disable-next-line no-implicit-globals\nVisualData = ( function () {\n\tvar VisualDataForms = {};\n\tvar Schemas = {};\n\tvar Config;\n\n\tfunction matchLoadedData( config, dataToLoad ) {\n\t\treturn dataToLoad.filter( ( x ) => !VisualDataFunctions.inArray( x, config.loadedData ) );\n\t}\n\n\tfunction adjustSchemas( schemas ) {\n\t\t// adjust schema, to ensure it can be handled\n\t\t// @FIXME put in VisualDataSchemas, redesign assignement\n\t\t// to Schemas in VisualDataForms -> loadDataBeforeSelect\n\t\tfor ( var i in schemas ) {\n\t\t\tif ( !( 'wiki' in schemas[ i ] ) ) {\n\t\t\t\tschemas[ i ].wiki = {};\n\t\t\t}\n\t\t\tif ( !( 'name' in schemas[ i ].wiki ) ) {\n\t\t\t\tschemas[ i ].wiki.name = i;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction loadData( config, dataToLoad ) {\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tvar payload = {\n\t\t\t\taction: 'visualdata-load-data',\n\t\t\t\tdataset: dataToLoad.join( '|' ),\n\t\t\t\t'source-page': mw.config.get( 'wgPageName' ),\n\t\t\t\tformat: 'json'\n\t\t\t};\n\t\t\tnew mw.Api()\n\t\t\t\t.postWithToken( 'csrf', payload )\n\t\t\t\t.done( function ( res ) {\n\t\t\t\t\tif ( payload.action in res ) {\n\t\t\t\t\t\tvar data = res[ payload.action ];\n\t\t\t\t\t\tfor ( var i in data ) {\n\t\t\t\t\t\t\tdata[ i ] = JSON.parse( data[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( 'schemas' in data ) {\n\t\t\t\t\t\t\tadjustSchemas( data.schemas );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconfig.loadedData = config.loadedData.concat( dataToLoad );\n\t\t\t\t\t\tresolve( data );\n\t\t\t\t\t} else {\n\t\t\t\t\t\treject();\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.fail( function ( res ) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.error( 'visualdata-load-data error', res );\n\t\t\t\t\treject( res );\n\t\t\t\t} );\n\t\t} );\n\t\t// *** catch is performed in the calling function\n\t\t// .catch( ( err ) => {\n\t\t// \tVisualDataFunctions.OOUIAlert( `error: ${ err }`, { size: 'medium' } );\n\t\t// } );\n\t}\n\n\tfunction loadSchemas( schemas ) {\n\t\tvar payload = {\n\t\t\taction: 'visualdata-get-schemas',\n\t\t\tschemas: schemas.join( '|' )\n\t\t};\n\t\tvar previousSchemas = VisualDataFunctions.deepCopy( Schemas );\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tnew mw.Api()\n\t\t\t\t.postWithToken( 'csrf', payload )\n\t\t\t\t.done( function ( res ) {\n\t\t\t\t\tif ( payload.action in res ) {\n\t\t\t\t\t\tvar thisSchemas = JSON.parse( res[ payload.action ].schemas );\n\t\t\t\t\t\tadjustSchemas( thisSchemas );\n\n\t\t\t\t\t\tfor ( var i in thisSchemas ) {\n\t\t\t\t\t\t\t// @FIXME check why it returns all empty schemas\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tVisualDataFunctions.isObject( thisSchemas[ i ] ) &&\n\t\t\t\t\t\t\t\tObject.keys( thisSchemas[ i ] )\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tSchemas[ i ] = thisSchemas[ i ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresolve( thisSchemas );\n\n\t\t\t\t\t\tfor ( var i in VisualDataForms ) {\n\t\t\t\t\t\t\tVisualDataForms[ i ].updateSchemas( previousSchemas, Schemas );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.fail( function ( res ) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.error( 'visualdata-get-schemas', res );\n\t\t\t\t\treject( res );\n\t\t\t\t} );\n\t\t} ).catch( ( err ) => {\n\t\t\tVisualDataFunctions.OOUIAlert( `error: ${ err }`, { size: 'medium' } );\n\t\t} );\n\t}\n\n\tfunction setVars( config, schemas ) {\n\t\tConfig = config;\n\t\tSchemas = schemas;\n\t}\n\n\tfunction setForms( instances ) {\n\t\tVisualDataForms = instances;\n\t}\n\n\tfunction updateSchemas( data, action ) {\n\t\tvar previousSchemas = VisualDataFunctions.deepCopy( Schemas );\n\n\t\tswitch ( action ) {\n\t\t\tcase 'update':\n\t\t\t\tSchemas = jQuery.extend( Schemas, data.schemas );\n\t\t\t\tbreak;\n\n\t\t\tcase 'delete':\n\t\t\t\tif ( data[ 'deleted-schema' ] in Schemas ) {\n\t\t\t\t\tdelete Schemas[ data[ 'deleted-schema' ] ];\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'create':\n\t\t\t\tSchemas = jQuery.extend( Schemas, data.schemas );\n\t\t\t\tSchemas = VisualDataFunctions.sortObjectByKeys( Schemas );\n\t\t\t\tbreak;\n\n\t\t\tcase 'rename':\n\t\t\t\tdelete Schemas[ data[ 'previous-label' ] ];\n\t\t\t\tSchemas = jQuery.extend( Schemas, data.schemas );\n\t\t\t\tSchemas = VisualDataFunctions.sortObjectByKeys( Schemas );\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( Config.context !== 'ManageSchemas' ) {\n\t\t\tfor ( var i in VisualDataForms ) {\n\t\t\t\tVisualDataForms[ i ].updateSchemas( previousSchemas, Schemas, data );\n\t\t\t}\n\t\t}\n\n\t\treturn Schemas;\n\t}\n\n\treturn {\n\t\tloadData,\n\t\tloadSchemas,\n\t\tsetVars,\n\t\tupdateSchemas,\n\t\tmatchLoadedData,\n\t\tsetForms\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":"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/VisualDataCalendar.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":134,"column":2,"nodeType":"CallExpression","endLine":134,"endColumn":29}],"suppressedMessages":[{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'dateObj_'.","line":79,"column":9,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":79,"endColumn":43,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'view_'.","line":96,"column":14,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":96,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'found_'.","line":98,"column":9,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":98,"endColumn":23,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'ec' is assigned a value but never used.","line":119,"column":9,"nodeType":"Identifier","messageId":"unusedVar","endLine":119,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'info' is defined but never used.","line":124,"column":26,"nodeType":"Identifier","messageId":"unusedVar","endLine":124,"endColumn":30,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'info' is defined but never used.","line":127,"column":23,"nodeType":"Identifier","messageId":"unusedVar","endLine":127,"endColumn":27,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright ©2025, https://wikisphere.org\n */\n\n/* eslint-disable no-unused-vars */\n\n$( function () {\n\tfunction init( $el ) {\n\t\tvar element = $el.get( 0 );\n\t\tvar data = $el.data();\n\t\tvar json = data.json;\n\t\tvar params = data.params;\n\n\t\tif ( !params.date ) {\n\t\t\tparams.date = new Date().toISOString();\n\n\t\t} else {\n\t\t\tvar dateObj = new Date( params.date * 1000 );\n\t\t\tparams.date = dateObj.toISOString();\n\t\t}\n\n\t\t// ***temporary solution, ensure the values of the following keys\n\t\t// are consistent to the selected view\n\t\t// @see https://github.com/vkurko/calendar/tree/master\n\t\tvar overrides = [\n\t\t\t'buttonText',\n\t\t\t'dayHeaderAriaLabelFormat',\n\t\t\t'dayHeaderFormat',\n\t\t\t'displayEventEnd',\n\t\t\t'duration',\n\t\t\t'slotDuration',\n\t\t\t'theme',\n\t\t\t'titleFormat'\n\t\t];\n\n\t\tfor ( var key of overrides ) {\n\t\t\tdelete params[ key ];\n\t\t}\n\n\t\t// handle resources\n\t\tvar resources = [];\n\t\tfor ( var value of json ) {\n\t\t\tvar event = value[ 1 ];\n\t\t\tif ( 'resources' in event ) {\n\t\t\t\tevent.resourceIds = [];\n\t\t\t\tif ( Array.isArray( event.resources ) ) {\n\t\t\t\t\tfor ( var resource of event.resources ) {\n\t\t\t\t\t\tif ( !VisualDataFunctions.inArray( resource, resources ) ) {\n\t\t\t\t\t\t\tresources.push( resource );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tevent.resourceIds.push( resources.indexOf( resource ) );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( !VisualDataFunctions.inArray( event.resources, resources ) ) {\n\t\t\t\t\t\tresources.push( event.resources );\n\t\t\t\t\t}\n\t\t\t\t\tevent.resourceIds.push( resources.indexOf( event.resources ) );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( !event.end ) {\n\t\t\t\t// eslint-disable-next-line no-underscore-dangle\n\t\t\t\tvar dateObj_ = new Date( event.start );\n\t\t\t\tvar durationMinutes = ( event.duration ? event.duration : params[ 'default-event-duration' ] ) * 1;\n\t\t\t\tdateObj_.setMinutes( dateObj_.getMinutes() + durationMinutes );\n\t\t\t\tevent.end = dateObj_;\n\t\t\t}\n\n\t\t\t// convert to local\n\t\t\tfor ( var prop of [ 'start', 'end' ] ) {\n\t\t\t\tevent[ prop ] = dayjs.utc( event[ prop ] ).local().toDate();\n\t\t\t}\n\t\t}\n\n\t\tif ( resources.length ) {\n\t\t\tvar additionalButtons = [];\n\t\t\tvar relatedViews = [ 'resourceTimeGridWeek', 'resourceTimelineWeek' ];\n\n\t\t\t// eslint-disable-next-line no-underscore-dangle\n\t\t\tfor ( var view_ of relatedViews ) {\n\t\t\t\t// eslint-disable-next-line no-underscore-dangle\n\t\t\t\tvar found_ = false;\n\t\t\t\tfor ( var i in params.headerToolbar ) {\n\t\t\t\t\tif ( params.headerToolbar[ i ].includes( view_ ) ) {\n\t\t\t\t\t\tfound_ = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( !found_ ) {\n\t\t\t\t\tadditionalButtons.push( view_ );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( additionalButtons.length ) {\n\t\t\t\tparams.headerToolbar.end += ' ' + additionalButtons.join( ',' );\n\t\t\t}\n\t\t}\n\n\t\t// remove placeholder\n\t\t$el.text( '' );\n\n\t\tconst ec = EventCalendar.create( element, $.extend( params, {\n\t\t\tevents: json.map( ( x ) => x[ 1 ] ),\n\t\t\tresources: resources.map( ( x, j ) => {\n\t\t\t\treturn { id: j, title: x };\n\t\t\t} ),\n\t\t\tdateClick: function ( info ) {\n\t\t\t\t// console.log( info );\n\t\t\t},\n\t\t\tselect: function ( info ) {\n\t\t\t\t// console.log( info );\n\t\t\t}\n\t\t} ) );\n\n\t}\n\n\t$( '.visualdata-calendar' ).each( function () {\n\t\tinit( $( this ) );\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":"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/VisualDataContentBlock.js","messages":[],"suppressedMessages":[{"ruleId":"no-unused-vars","severity":2,"message":"'VisualDataContentBlock' is assigned a value but never used.","line":23,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":23,"endColumn":29,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'Config' is assigned a value but never used.","line":25,"column":6,"nodeType":"Identifier","messageId":"unusedVar","endLine":25,"endColumn":12,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'data' is assigned a value but never used.","line":67,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":67,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'property' is defined but never used.","line":110,"column":45,"nodeType":"Identifier","messageId":"unusedVar","endLine":110,"endColumn":53,"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":"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/VisualDataDatatables.js","messages":[{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":27,"column":6,"nodeType":"VariableDeclarator","endLine":27,"endColumn":21},{"ruleId":"max-len","severity":1,"message":"This line has a length of 144. Maximum allowed is 100.","line":43,"column":1,"nodeType":"Program","messageId":"max","endLine":43,"endColumn":139},{"ruleId":"max-len","severity":1,"message":"This line has a length of 111. Maximum allowed is 100.","line":59,"column":1,"nodeType":"Program","messageId":"max","endLine":59,"endColumn":100},{"ruleId":"max-len","severity":1,"message":"This line has a length of 101. Maximum allowed is 100.","line":140,"column":1,"nodeType":"Program","messageId":"max","endLine":140,"endColumn":90},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":173,"column":3,"nodeType":"CallExpression","endLine":202,"endColumn":7},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":173,"column":3,"nodeType":"CallExpression","endLine":206,"endColumn":7},{"ruleId":"max-len","severity":1,"message":"This line has a length of 112. Maximum allowed is 100.","line":242,"column":1,"nodeType":"Program","messageId":"max","endLine":242,"endColumn":101},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":279,"column":3,"nodeType":"CallExpression","endLine":293,"endColumn":7},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":279,"column":3,"nodeType":"CallExpression","endLine":297,"endColumn":7},{"ruleId":"no-jquery/no-in-array","severity":1,"message":"Prefer Array#indexOf to $.inArray","line":358,"column":5,"nodeType":"CallExpression","endLine":358,"endColumn":49},{"ruleId":"max-len","severity":1,"message":"This line has a length of 111. Maximum allowed is 100.","line":491,"column":1,"nodeType":"Program","messageId":"max","endLine":491,"endColumn":91},{"ruleId":"no-jquery/no-in-array","severity":1,"message":"Prefer Array#indexOf to $.inArray","line":640,"column":8,"nodeType":"CallExpression","endLine":640,"endColumn":53},{"ruleId":"max-len","severity":1,"message":"This line has a length of 119. Maximum allowed is 100.","line":681,"column":1,"nodeType":"Program","messageId":"max","endLine":681,"endColumn":102},{"ruleId":"no-fallthrough","severity":1,"message":"Expected a 'break' statement before 'case'.","line":686,"column":8,"nodeType":"SwitchCase","messageId":"case","endLine":686,"endColumn":20},{"ruleId":"no-fallthrough","severity":1,"message":"Expected a 'break' statement before 'case'.","line":690,"column":8,"nodeType":"SwitchCase","messageId":"case","endLine":690,"endColumn":21},{"ruleId":"no-fallthrough","severity":1,"message":"Expected a 'break' statement before 'case'.","line":692,"column":8,"nodeType":"SwitchCase","messageId":"case","endLine":692,"endColumn":21},{"ruleId":"max-len","severity":1,"message":"This line has a length of 143. Maximum allowed is 100.","line":757,"column":1,"nodeType":"Program","messageId":"max","endLine":757,"endColumn":117},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":1076,"column":2,"nodeType":"CallExpression","endLine":1076,"endColumn":30},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":1093,"column":3,"nodeType":"CallExpression","endLine":1093,"endColumn":31}],"suppressedMessages":[{"ruleId":"no-unused-vars","severity":2,"message":"'obj' is defined but never used.","line":36,"column":33,"nodeType":"Identifier","messageId":"unusedVar","endLine":36,"endColumn":36,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in '_iDisplayStart'.","line":104,"column":18,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":104,"endColumn":51,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in '_iDisplayStart'.","line":144,"column":6,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":144,"endColumn":29,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":165,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":165,"endColumn":15,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[4582,4618],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":181,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":181,"endColumn":17,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[4957,4987],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":183,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":183,"endColumn":17,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[5037,5063],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":205,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":205,"endColumn":18,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[5588,5640],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":271,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":271,"endColumn":15,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[7498,7534],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":287,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":287,"endColumn":17,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[7875,7907],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":289,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":289,"endColumn":17,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[7957,7983],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":296,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":296,"endColumn":18,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[8100,8158],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":590,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":590,"endColumn":15,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[15859,15897],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'header' is defined but never used.","line":663,"column":64,"nodeType":"Identifier","messageId":"unusedVar","endLine":663,"endColumn":70,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'e' is defined but never used.","line":820,"column":24,"nodeType":"Identifier","messageId":"unusedVar","endLine":820,"endColumn":25,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'dt' is defined but never used.","line":820,"column":27,"nodeType":"Identifier","messageId":"unusedVar","endLine":820,"endColumn":29,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'node' is defined but never used.","line":820,"column":31,"nodeType":"Identifier","messageId":"unusedVar","endLine":820,"endColumn":35,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'config' is defined but never used.","line":820,"column":37,"nodeType":"Identifier","messageId":"unusedVar","endLine":820,"endColumn":43,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-new","severity":2,"message":"Do not use 'new' for side effects.","line":859,"column":9,"nodeType":"ExpressionStatement","messageId":"noNewStatement","endLine":859,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'settings' is defined but never used.","line":926,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":926,"endColumn":42,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'settings' is defined but never used.","line":1005,"column":51,"nodeType":"Identifier","messageId":"unusedVar","endLine":1005,"endColumn":59,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":1037,"column":8,"nodeType":"MemberExpression","messageId":"unexpected","endLine":1037,"endColumn":19,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[28137,28181],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":1058,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":1058,"endColumn":15,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[28529,28557],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-new","severity":2,"message":"Do not use 'new' for side effects.","line":1095,"column":4,"nodeType":"ExpressionStatement","messageId":"noNewStatement","endLine":1095,"endColumn":44,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":4,"fatalErrorCount":0,"warningCount":15,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2024-2025, https://wikisphere.org\n */\n\n/* eslint-disable no-unused-vars */\n\nconst VisualDataDatatables = function ( el, elIndex ) {\n\tvar Datatable;\n\tvar CacheLimit = 40000;\n\tvar Table = $( el );\n\tvar TableData = Table.data();\n\tvar SynchInterval;\n\tvar FaviconHref;\n\tvar DatatableLibrary = $.fn.dataTable.ext;\n\tvar PreloadData = {};\n\tvar Count;\n\tvar ElIndex = elIndex;\n\n\tvar getCacheLimit = function ( obj ) {\n\t\treturn CacheLimit;\n\t};\n\n\tvar getCacheKey = function ( obj ) {\n\t\t// this ensures that the preload key\n\t\t// and the dynamic key match\n\t\t// this does not work: \"searchPanes\" in obj && Object.entries(obj.searchPanes).find(x => Object.keys(x).length ) ? obj.searchPanes : {},\n\t\tif ( 'searchPanes' in obj ) {\n\t\t\tfor ( var i in obj.searchPanes ) {\n\t\t\t\tif ( !Object.keys( obj.searchPanes[ i ] ).length ) {\n\t\t\t\t\tdelete obj.searchPanes[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn objectHash.sha1( {\n\t\t\torder: obj.order.map( ( x ) => {\n\t\t\t\treturn { column: x.column, dir: x.dir };\n\t\t\t} ),\n\t\t\t// search: obj.search,\n\t\t\tsearchPanes:\n\t\t\t\t'searchPanes' in obj &&\n\t\t\t\tVisualDataFunctions.objectEntries( obj.searchPanes ).find( ( x ) => Object.keys( x ).length ) ?\n\t\t\t\t\tobj.searchPanes :\n\t\t\t\t\t{},\n\t\t\tsearchBuilder: 'searchBuilder' in obj ? obj.searchBuilder : {}\n\t\t} );\n\t};\n\n\tvar getCacheData = function ( cacheKey, datatableData ) {\n\t\tif ( !( cacheKey in PreloadData ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar data = [];\n\t\tfor ( var i = datatableData.start; i < datatableData.start + datatableData.length; i++ ) {\n\t\t\tif ( i >= Count ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !( i in PreloadData[ cacheKey ].data ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdata.push( PreloadData[ cacheKey ].data[ i ] );\n\t\t}\n\n\t\treturn { count: PreloadData[ cacheKey ].count, data };\n\t};\n\n\tvar setCacheData = function ( json ) {\n\t\tvar cacheKey = json.cacheKey;\n\t\tif ( !( cacheKey in PreloadData ) ) {\n\t\t\tPreloadData[ cacheKey ] = { data: {} };\n\t\t}\n\n\t\tvar n = json.start;\n\t\tfor ( var row of json.data ) {\n\t\t\tPreloadData[ cacheKey ].data[ n ] = row;\n\t\t\tn++;\n\t\t}\n\n\t\tPreloadData[ cacheKey ].count = json.recordsFiltered;\n\t};\n\n\t// @credits https://stackoverflow.com/questions/32692618/how-to-export-all-rows-from-datatables-using-ajax\n\tvar exportAction = function ( e1, dt, button, config ) {\n\t\tvar self = this;\n\t\t// eslint-disable-next-line no-underscore-dangle\n\t\tvar oldStart = dt.settings()[ 0 ]._iDisplayStart;\n\t\tvar buttonClass = config.className.split( ' ' ).shift();\n\n\t\tvar funcName = null;\n\t\tswitch ( buttonClass ) {\n\t\t\tcase 'buttons-copy':\n\t\t\t\tfuncName = 'copyHtml5';\n\t\t\t\tbreak;\n\t\t\tcase 'buttons-excel':\n\t\t\t\tfuncName = ( DatatableLibrary.buttons.excelHtml5.available( dt, config ) ? 'excelHtml5' : 'excelFlash' );\n\t\t\t\tbreak;\n\t\t\tcase 'buttons-csv':\n\t\t\t\tfuncName = ( DatatableLibrary.buttons.csvHtml5.available( dt, config ) ? 'csvHtml5' : 'csvFlash' );\n\t\t\t\tbreak;\n\t\t\tcase 'buttons-pdf':\n\t\t\t\tfuncName = ( DatatableLibrary.buttons.pdfHtml5.available( dt, config ) ? 'pdfHtml5' : 'pdfFlash' );\n\t\t\t\tbreak;\n\t\t\tcase 'buttons-print':\n\t\t\t\tfuncName = 'print';\n\t\t\t\tbreak;\n\t\t}\n\n\t\tvar cb = function () {\n\t\t\tbutton.removeClass( 'processing' );\n\t\t};\n\n\t\tif ( !funcName ) {\n\t\t\tcb();\n\t\t\treturn;\n\t\t}\n\n\t\tdt.one( 'preXhr', function ( e2, s, data ) {\n\t\t\tdata.start = 0;\n\t\t\tdata.length = TableData.count;\n\n\t\t\tdt.one( 'preDraw', function ( e3, settings ) {\n\t\t\t\tDatatableLibrary.buttons[ funcName ].action.call( self, e3, dt, button, config, cb );\n\n\t\t\t\tdt.one( 'preXhr', function ( e4, s1, data1 ) {\n\t\t\t\t\t// eslint-disable-next-line no-underscore-dangle\n\t\t\t\t\tsettings._iDisplayStart = oldStart;\n\t\t\t\t\tdata1.start = oldStart;\n\t\t\t\t} );\n\n\t\t\t\tsetTimeout( dt.ajax.reload, 0 );\n\t\t\t\treturn false;\n\t\t\t} );\n\n\t\t} );\n\n\t\tdt.ajax.reload();\n\t};\n\n\tvar callApi = function (\n\t\tdata,\n\t\tcallback,\n\t\tsearchPanesOptions,\n\t\tdisplayLog\n\t) {\n\t\tif ( displayLog ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log( 'payload data', data );\n\t\t}\n\n\t\tvar payload = {\n\t\t\taction: 'visualdata-datatables',\n\t\t\tdata: JSON.stringify( data )\n\t\t};\n\n\t\tnew mw.Api()\n\t\t\t.postWithToken( 'csrf', payload )\n\t\t\t.done( function ( res ) {\n\t\t\t\tvar json = res[ payload.action ].result;\n\t\t\t\tvar log = res[ payload.action ].log;\n\n\t\t\t\tif ( displayLog ) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.log( 'result', json );\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.log( 'log', log );\n\t\t\t\t}\n\n\t\t\t\t// cache all retrieved rows for each sorting\n\t\t\t\t// dimension (column/dir), up to a fixed\n\t\t\t\t// threshold (CacheLimit)\n\t\t\t\tif ( json.cacheKey ) {\n\t\t\t\t\tsetCacheData( json );\n\t\t\t\t}\n\n\t\t\t\t// we retrieve more than \"length\"\n\t\t\t\t// expected by datatables, so return the\n\t\t\t\t// sliced result\n\t\t\t\tjson.data = json.data.slice( 0, json.datalength );\n\t\t\t\tjson.searchPanes = {\n\t\t\t\t\toptions: searchPanesOptions\n\t\t\t\t};\n\n\t\t\t\tcallback( json );\n\t\t\t} )\n\t\t\t.fail( function ( error ) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error( 'visualdata-datatables-api', error );\n\t\t\t} );\n\t};\n\n\tvar restoreBadge = function () {\n\t\tfunction drawBadge( favicon ) {\n\t\t\tif ( favicon ) {\n\t\t\t\tfavicon.parentNode.removeChild( favicon );\n\t\t\t}\n\t\t\tvar newLink = document.createElement( 'link' );\n\t\t\tnewLink.href = FaviconHref;\n\t\t\tnewLink.rel = 'icon';\n\t\t\tdocument.head.appendChild( newLink );\n\t\t}\n\t\tif ( FaviconHref ) {\n\t\t\tvar link = document.querySelector( \"link[rel~='icon']\" );\n\t\t\tdrawBadge( link );\n\t\t}\n\t};\n\n\t// @credits https://www.sitelint.com/blog/add-a-badge-to-the-browser-tab-favicon-using-javascript\n\t// @credits https://stackoverflow.com/questions/260857/changing-website-favicon-dynamically\n\tvar addBadge = function () {\n\t\tdocument.head = document.head || document.getElementsByTagName( 'head' )[ 0 ];\n\n\t\tfunction drawBadge( favicon ) {\n\t\t\tconst faviconSize = 32;\n\t\t\tconst canvas = document.createElement( 'canvas' );\n\t\t\tcanvas.width = faviconSize;\n\t\t\tcanvas.height = faviconSize;\n\t\t\tconst context = canvas.getContext( '2d' );\n\t\t\tconst img = document.createElement( 'img' );\n\n\t\t\tconst createBadge = () => {\n\t\t\t\tcontext.drawImage( img, 0, 0, faviconSize, faviconSize );\n\n\t\t\t\tcontext.beginPath();\n\t\t\t\tcontext.arc( canvas.width - faviconSize / 6, faviconSize / 6, faviconSize / 6, 0, 2 * Math.PI );\n\t\t\t\tcontext.fillStyle = '#e30';\n\t\t\t\tcontext.fill();\n\n\t\t\t\tif ( favicon ) {\n\t\t\t\t\tfavicon.parentNode.removeChild( favicon );\n\t\t\t\t}\n\t\t\t\tvar newIcon = document.createElement( 'link' );\n\t\t\t\tnewIcon.href = canvas.toDataURL( 'image/png' );\n\t\t\t\tnewIcon.rel = 'icon';\n\t\t\t\tdocument.head.appendChild( newIcon );\n\t\t\t};\n\n\t\t\timg.addEventListener( 'load', createBadge );\n\t\t\timg.src = favicon.href;\n\t\t\tFaviconHref = favicon.href;\n\t\t}\n\n\t\tvar link = document.querySelector( \"link[rel~='icon']\" );\n\t\tdrawBadge( link );\n\t};\n\n\tvar callApiSynch = function (\n\t\tdata,\n\t\tcallback,\n\t\tdisplayLog\n\t) {\n\t\tif ( displayLog ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log( 'payload data', data );\n\t\t}\n\n\t\tvar payload = {\n\t\t\taction: 'visualdata-datatables',\n\t\t\tdata: JSON.stringify( data )\n\t\t};\n\n\t\tnew mw.Api()\n\t\t\t.postWithToken( 'csrf', payload )\n\t\t\t.done( function ( res ) {\n\t\t\t\tvar result = res[ payload.action ].result;\n\t\t\t\tvar log = res[ payload.action ].log;\n\n\t\t\t\tif ( displayLog ) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.log( 'result', result );\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.log( 'log', log );\n\t\t\t\t}\n\n\t\t\t\tcallback( result );\n\t\t\t} )\n\t\t\t.fail( function ( error ) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error( 'visualdata-datatables-api-synch', error );\n\t\t\t} );\n\t};\n\n\tfunction objectValues( obj ) {\n\t\treturn Object.keys( obj ).map( function ( e ) {\n\t\t\treturn obj[ e ];\n\t\t} );\n\t}\n\n\tvar initColumnSort = function ( order, headers ) {\n\t\tvar ret = [];\n\t\t// eg. new_property asc, new_property_2 desc\n\t\tvar values = order.split( /\\s*,\\s*/ );\n\n\t\t// @see QueryProcessor -> getOptions\n\t\tfor ( var i in values ) {\n\t\t\tvar match = values[ i ].match( /^\\s*(.+?)\\s*(ASC|DESC)?\\s*$/i );\n\t\t\tif ( !match ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar propName = match[ 1 ];\n\t\t\tvar sort = match[ 2 ] ? match[ 2 ] : 'ASC';\n\t\t\tvar index = Object.keys( headers ).indexOf( propName );\n\t\t\tif ( index !== -1 ) {\n\t\t\t\tret.push( [ index, sort.toLowerCase() ] );\n\t\t\t}\n\t\t}\n\t\tif ( ret.length > 0 ) {\n\t\t\tTable.data( 'order', ret );\n\t\t} else {\n\t\t\t// default @see https://datatables.net/reference/option/order\n\t\t\tTable.data( 'order', [ [ 0, 'asc' ] ] );\n\t\t}\n\t};\n\n\tvar initSearchPanesColumns = function ( columnDefs, conf ) {\n\t\t// remove non existing columns (starts from 0)\n\t\tif ( 'columns' in conf.searchPanes ) {\n\t\t\tfor ( var i in conf.searchPanes.columns ) {\n\t\t\t\tif ( conf.searchPanes.columns[ i ] >= Object.keys( columnDefs ).length ) {\n\t\t\t\t\tdelete conf.searchPanes.columns[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( var i in columnDefs ) {\n\t\t\tif ( !( 'searchPanes' in columnDefs[ i ] ) ) {\n\t\t\t\tcolumnDefs[ i ].searchPanes = {};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t'show' in columnDefs[ i ].searchPanes &&\n\t\t\t\tcolumnDefs[ i ].searchPanes.show === false\n\t\t\t) {\n\t\t\t\tdelete columnDefs[ i ].searchPanes;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t'columns' in conf.searchPanes &&\n\t\t\t\tconf.searchPanes.columns.length &&\n\t\t\t\t$.inArray( i * 1, conf.searchPanes.columns ) < 0\n\t\t\t) {\n\t\t\t\tdelete columnDefs[ i ].searchPanes;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcolumnDefs[ i ].searchPanes.show = true;\n\t\t}\n\t};\n\n\t// this is used only if Ajax is disabled\n\tvar getPanesOptions = function ( data, columnDefs, conf ) {\n\t\tvar ret = {};\n\t\tvar dataLength = {};\n\t\tvar div = document.createElement( 'div' );\n\n\t\tfor ( var i in columnDefs ) {\n\t\t\tif ( 'searchPanes' in columnDefs[ i ] ) {\n\t\t\t\tret[ i ] = {};\n\t\t\t\tdataLength[ i ] = 0;\n\t\t\t}\n\t\t}\n\n\t\tfor ( var i in data ) {\n\t\t\tfor ( var ii in ret ) {\n\t\t\t\tvar key = Object.keys( data[ i ] )[ ii ];\n\n\t\t\t\tfor ( var iii in data[ i ][ key ] ) {\n\t\t\t\t\tvar value = data[ i ][ key ][ iii ];\n\n\t\t\t\t\tif ( value === '' ) {\n\t\t\t\t\t\tif ( !conf.searchPanes.showEmpty ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataLength[ ii ]++;\n\t\t\t\t\tvar label;\n\t\t\t\t\tif ( conf.searchPanes.htmlLabels === false ) {\n\t\t\t\t\t\tdiv.innerHTML = value;\n\t\t\t\t\t\tlabel = div.textContent || div.innerText || '';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlabel = value;\n\t\t\t\t\t}\n\n\t\t\t\t\t// this will exclude images as well if\n\t\t\t\t\t// conf.searchPanes.htmlLabels === false\n\t\t\t\t\tif ( label === '' ) {\n\t\t\t\t\t\tif ( !conf.searchPanes.showEmpty ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlabel = `<i>${ conf.searchPanes.emptyMessage }</i>`;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !( value in ret[ key ] ) ) {\n\t\t\t\t\t\tret[ key ][ value ] = {\n\t\t\t\t\t\t\tlabel: label,\n\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\tcount: 0\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tret[ key ][ value ].count++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( var i in ret ) {\n\t\t\tvar threshold =\n\t\t\t\t'threshold' in columnDefs[ i ].searchPanes ?\n\t\t\t\t\tcolumnDefs[ i ].searchPanes.threshold :\n\t\t\t\t\tconf.searchPanes.threshold;\n\n\t\t\t// @see https://datatables.net/extensions/searchpanes/examples/initialisation/threshold.htm\n\t\t\t// @see https://github.com/DataTables/SearchPanes/blob/818900b75dba6238bf4b62a204fdd41a9b8944b7/src/SearchPane.ts#L824\n\t\t\t// _uniqueRatio\n\t\t\tvar binLength = Object.keys( ret[ i ] ).length;\n\t\t\t// data.length;\n\t\t\tvar uniqueRatio = binLength / dataLength[ i ];\n\n\t\t\t//  || binLength <= 1\n\t\t\tif ( uniqueRatio > threshold ) {\n\t\t\t\tdelete ret[ i ];\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tret[ i ] = objectValues( ret[ i ] ).filter(\n\t\t\t\t( x ) => x.count >= conf.searchPanes.minCount\n\t\t\t);\n\n\t\t\tif ( !ret[ i ].length ) {\n\t\t\t\tdelete ret[ i ];\n\t\t\t}\n\t\t}\n\n\t\tfor ( var i in columnDefs ) {\n\t\t\tif ( !( i in ret ) ) {\n\t\t\t\t// delete columnDefs[i].searchPanes;\n\t\t\t\tcolumnDefs[ i ].searchPanes = { show: false };\n\t\t\t}\n\t\t}\n\n\t\t// *** doesn't have effect\n\t\tfor ( var i in ret ) {\n\t\t\tret[ i ].sort( function ( a, b ) {\n\t\t\t\tif ( a.value === '' && b.value !== '' ) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\tif ( a.value !== '' && b.value === '' ) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\treturn 0;\n\t\t\t} );\n\t\t}\n\n\t\treturn ret;\n\t};\n\n\tvar setPanesOptions = function ( data, searchPanesOptions, columnDefs ) {\n\t\tfor ( let i in searchPanesOptions ) {\n\t\t\t// @see https://datatables.net/reference/option/columns.searchPanes.combiner\n\t\t\tcolumnDefs[ i ].searchPanes.combiner =\n\t\t\t\t'combiner' in columnDefs[ i ].searchPanes ?\n\t\t\t\t\tcolumnDefs[ i ].searchPanes.combiner :\n\t\t\t\t\t'or';\n\t\t\tcolumnDefs[ i ].searchPanes.options = [];\n\n\t\t\t// @see https://datatables.net/reference/option/columns.searchPanes.options\n\t\t\tfor ( let ii in searchPanesOptions[ i ] ) {\n\t\t\t\tcolumnDefs[ i ].searchPanes.options.push( {\n\t\t\t\t\tlabel: searchPanesOptions[ i ][ ii ].label,\n\t\t\t\t\tvalue: function ( rowData, rowIdx ) {\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\tobjectValues( data[ rowIdx ] )[ i ].includes( searchPanesOptions[ i ][ ii ].value )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// @TODO sort panes after rendering using the following\n\t\t\t// https://github.com/DataTables/SearchPanes/blob/master/src/SearchPane.ts\n\t\t}\n\t};\n\n\tvar searchPanesOptionsServer = function (\n\t\tsearchPanesOptions,\n\t\tcolumnDefs,\n\t\tconf,\n\t\theadersRaw\n\t) {\n\t\tfunction indexFromPrintout( printout ) {\n\t\t\tfor ( var thisIndex in columnDefs ) {\n\t\t\t\tif ( columnDefs[ thisIndex ].name === printout ) {\n\t\t\t\t\treturn thisIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\t\tvar ret = {};\n\t\tfor ( var i in searchPanesOptions ) {\n\t\t\tvar index = indexFromPrintout( i );\n\t\t\tif ( index !== -1 ) {\n\t\t\t\tret[ index ] = searchPanesOptions[ i ];\n\t\t\t}\n\t\t}\n\n\t\tvar div = document.createElement( 'div' );\n\t\tfor ( var i in ret ) {\n\t\t\tif ( !( 'searchPanes' in columnDefs[ i ] ) ) {\n\t\t\t\tcolumnDefs[ i ].searchPanes = {};\n\t\t\t}\n\t\t\tcolumnDefs[ i ].searchPanes.show = Object.keys( ret[ i ] ).length > 0;\n\n\t\t\tfor ( var ii in ret[ i ] ) {\n\t\t\t\tif ( conf.searchPanes.htmlLabels === false && headersRaw[ i ] ) {\n\t\t\t\t\tdiv.innerHTML = ret[ i ][ ii ].label;\n\t\t\t\t\tret[ i ][ ii ].label = div.textContent || div.innerText || '';\n\t\t\t\t}\n\n\t\t\t\tret[ i ][ ii ].total = ret[ i ][ ii ].count;\n\t\t\t}\n\t\t}\n\n\t\tfor ( var i in columnDefs ) {\n\t\t\tif ( 'searchPanes' in columnDefs[ i ] && !( indexFromPrintout( columnDefs[ i ].name ) in ret ) ) {\n\t\t\t\tdelete columnDefs[ i ].searchPanes;\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n\n\tvar renderCards = function ( headers ) {\n\t\tif ( Table.hasClass( 'cards' ) ) {\n\t\t\tvar labels = objectValues( headers );\n\n\t\t\t// Add data-label attribute to each cell\n\t\t\t// (will be used by .visualdata.datatable.cards td:before)\n\t\t\t$( 'tbody tr', Table ).each( function () {\n\t\t\t\t$( this ).find( 'td' ).each( function ( column ) {\n\t\t\t\t\t$( this ).attr( 'data-label', labels[ column ] );\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\t// set same heigth for all cards\n\t\t\tvar max = 0;\n\t\t\t$( 'tbody tr', Table ).each( function () {\n\t\t\t\tmax = Math.max( $( this ).height(), max );\n\t\t\t} ).height( max );\n\t\t}\n\t};\n\n\tvar render = function () {\n\t\tCount = TableData.count;\n\t\tvar conf = TableData.conf;\n\t\tvar query = TableData.query;\n\t\tvar data = TableData.json;\n\t\tvar params = TableData.params;\n\t\tvar printouts = TableData.printouts;\n\t\tvar templates = TableData.templates;\n\t\tvar mapPathSchema = TableData.mapPathSchema;\n\t\tvar categoryFields = TableData.categoryFields;\n\t\tvar headers = TableData.headers;\n\t\t// var headersRaw = TableData.headersRaw;\n\t\tvar headersRaw = objectValues( TableData.headersRaw );\n\t\tvar printoutsOptions = TableData.printoutsOptions;\n\t\tvar searchPanesOptions = TableData.searchPanesOptions;\n\t\tvar useAjax = ( Count > data.length );\n\n\t\tvar displayLog = params.displayLog;\n\t\tif ( displayLog ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log( 'TableData', TableData );\n\t\t}\n\t\tinitColumnSort( query.params.order, headers );\n\t\tvar order = Table.data( 'order' );\n\n\t\tfunction isObject( obj ) {\n\t\t\treturn obj !== null && typeof obj === 'object' && !Array.isArray( obj );\n\t\t}\n\n\t\tif ( isObject( conf.scroller ) ) {\n\t\t\tif ( !( 'scrollY' in conf ) || !conf.scrollY ) {\n\t\t\t\tconf.scrollY = '300px';\n\n\t\t\t\t// expected type is string\n\t\t\t} else if ( !isNaN( conf.scrollY ) ) {\n\t\t\t\tconf.scrollY = conf.scrollY + 'px';\n\t\t\t}\n\t\t}\n\n\t\tvar searchPanes = isObject( conf.searchPanes );\n\t\tvar synch = isObject( conf.synch );\n\n\t\tvar searchBuilder = conf.searchBuilder;\n\t\tif ( searchBuilder ) {\n\t\t\t// if (options.dom.indexOf(\"Q\") === -1) {\n\t\t\t// options.dom = \"Q\" + options.dom;\n\t\t\t// }\n\n\t\t\t// @see https://datatables.net/extensions/searchbuilder/customConditions.html\n\t\t\t// @see https://github.com/DataTables/SearchBuilder/blob/master/src/searchBuilder.ts\n\t\t\tconf.searchBuilder = {\n\t\t\t\tdepthLimit: 1,\n\t\t\t\tconditions: {\n\t\t\t\t\thtml: {\n\t\t\t\t\t\tnull: null\n\t\t\t\t\t},\n\t\t\t\t\tstring: {\n\t\t\t\t\t\tnull: null\n\t\t\t\t\t},\n\t\t\t\t\tdate: {\n\t\t\t\t\t\tnull: null\n\t\t\t\t\t},\n\t\t\t\t\tnum: {\n\t\t\t\t\t\tnull: null\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t// add the pagelength at the proper place in the length menu\n\t\tif ( $.inArray( conf.pageLength, conf.lengthMenu ) < 0 ) {\n\t\t\tconf.lengthMenu.push( conf.pageLength );\n\t\t\tconf.lengthMenu.sort( function ( a, b ) {\n\t\t\t\treturn a - b;\n\t\t\t} );\n\t\t}\n\n\t\t// datatables columns.type\n\t\t// https://datatables.net/reference/option/columns.type\n\t\t/*\nstring\ndate\nnum\nnum-fmt\nhtml\nhtml-fmt\nhtml-num-fmt\n*/\n\t\tvar index = 0;\n\t\tvar columnDefs = [];\n\n\t\t// or use mapPathSchema[ printout ].format\n\t\tvar mapColumnIndexFormat = {};\n\t\tVisualDataFunctions.objectEntries( headers ).forEach( ( [ k, header ], thisIndex ) => {\n\t\t\tif ( mapPathSchema[ k ] ) {\n\t\t\t\tmapColumnIndexFormat[ thisIndex ] = mapPathSchema[ k ].format;\n\t\t\t}\n\t\t} );\n\n\t\tfor ( var key in headers ) {\n\t\t\tvar datatablesFormat;\n\t\t\tvar columnType;\n\t\t\tif ( key in mapPathSchema ) {\n\t\t\t\tcolumnType = mapPathSchema[ key ].type;\n\t\t\t\tswitch ( mapPathSchema[ key ].type ) {\n\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\tdatatablesFormat = 'string';\n\t\t\t\t\t\tcolumnType = 'boolean';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'string':\n\t\t\t\t\t\t// mapColumnIndexFormat[ Object.keys( headers ).indexOf( key ) ] = mapPathSchema[ key ].format;\n\t\t\t\t\t\tcolumnType = mapPathSchema[ key ].format;\n\t\t\t\t\t\tswitch ( mapPathSchema[ key ].format ) {\n\t\t\t\t\t\t\tcase 'color':\n\n\t\t\t\t\t\t\tcase 'date':\n\t\t\t\t\t\t\tcase 'datetime':\n\t\t\t\t\t\t\tcase 'datetime-local':\n\t\t\t\t\t\t\t\tdatatablesFormat = 'date';\n\t\t\t\t\t\t\tcase 'email':\n\n\t\t\t\t\t\t\tcase 'month':\n\t\t\t\t\t\t\tcase 'number':\n\t\t\t\t\t\t\tcase 'week':\n\t\t\t\t\t\t\t\tdatatablesFormat = 'num';\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase 'password':\n\t\t\t\t\t\t\tcase 'range':\n\t\t\t\t\t\t\tcase 'tel':\n\t\t\t\t\t\t\tcase 'text':\n\t\t\t\t\t\t\tcase 'textarea':\n\t\t\t\t\t\t\tcase 'time':\n\t\t\t\t\t\t\t\tdatatablesFormat = 'string';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'url':\n\t\t\t\t\t\t\t\tdatatablesFormat = 'html';\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tdatatablesFormat = 'string';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'number':\n\t\t\t\t\tcase 'integer':\n\t\t\t\t\t\tdatatablesFormat = 'num';\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tdatatablesFormat = 'string';\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// or categories\n\t\t\t\tcolumnType = 'page title';\n\t\t\t\tdatatablesFormat = 'html';\n\t\t\t}\n\n\t\t\tif ( !conf.columns.type ) {\n\t\t\t\t// @TODO use \"any-number\" for numeric values\n\t\t\t\tconf.columns.type = null;\n\t\t\t}\n\n\t\t\tcolumnDefs.push(\n\t\t\t\t$.extend(\n\t\t\t\t\t{\n\t\t\t\t\t\t// https://datatables.net/reference/option/columnDefs\n\t\t\t\t\t\t// data: ...\n\t\t\t\t\t\ttitle: headers[ key ],\n\t\t\t\t\t\tname: key,\n\t\t\t\t\t\tclassName: 'schema-type-' + columnType,\n\t\t\t\t\t\ttargets: [ index ],\n\n\t\t\t\t\t\t// @see https://datatables.net/reference/option/columns.data\n\t\t\t\t\t\t// @see https://datatables.net/examples/ajax/objects_subarrays.html\n\t\t\t\t\t\t// @see https://datatables.net/extensions/searchpanes/examples/advanced/renderArrays.html\n\t\t\t\t\t\t// data: function ( row, type, val, meta ) {\n\t\t\t\t\t\t// return row[ meta.col ].join( params[ 'values-separator' ] );\n\t\t\t\t\t\t// },\n\n\t\t\t\t\t\trender: function ( thisData, type, row, meta ) {\n\t\t\t\t\t\t\t// or use mapPathSchema[ printout ].format\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tmeta.col in mapColumnIndexFormat &&\n\t\t\t\t\t\t\t\tVisualDataFunctions.inArray( mapColumnIndexFormat[ meta.col ], [ 'time', 'date', 'datetime', 'datetime-local' ] )\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tvar printout = Object.keys( headers )[ meta.col ];\n\t\t\t\t\t\t\t\tvar printoutOptions = printoutsOptions[ printout ];\n\t\t\t\t\t\t\t\tthisData = thisData.map( function ( value ) {\n\t\t\t\t\t\t\t\t\treturn VisualDataFunctions.dateToLocalPrintout( value, mapColumnIndexFormat[ meta.col ], printoutOptions );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// if ( !headersRaw[ Object.keys( headers )[ meta.col ] ] ) {\n\t\t\t\t\t\t\tif ( !headersRaw[ meta.col ] ) {\n\t\t\t\t\t\t\t\tthisData = thisData.map( function ( value ) {\n\t\t\t\t\t\t\t\t\treturn VisualDataFunctions.escapeHTML( value );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn thisData.join( params[ 'values-separator' ] );\n\t\t\t\t\t\t},\n\t\t\t\t\t\t// @FIXME https://datatables.net/reference/option/columns.searchBuilderType\n\t\t\t\t\t\t// implement in the proper way\n\t\t\t\t\t\tsearchBuilderType: datatablesFormat\n\t\t\t\t\t},\n\t\t\t\t\tconf.columns,\n\t\t\t\t\t( !( 'columns' in printoutsOptions[ key ] ) ? {} : printoutsOptions[ key ].columns )\n\t\t\t\t)\n\t\t\t);\n\t\t\tindex++;\n\t\t}\n\n\t\tif ( conf.cards ) {\n\t\t\tconf.responsive = false;\n\t\t}\n\n\t\t// *** url params are passed for the use\n\t\t// with the template ResultPrinter which\n\t\t// may use the \"urlget\" parser function or similar\n\n\t\t// do not use VisualDataFunctions.objectEntries\n\t\tvar searchParams = new URLSearchParams( location.search );\n\t\tvar urlParams = {};\n\t\tfor ( const [ k, v ] of searchParams ) {\n\t\t\turlParams[ k ] = v;\n\t\t}\n\t\tdelete urlParams.title;\n\t\tdelete urlParams.action;\n\n\t\tif ( synch ) {\n\t\t\tvar payloadDataSync = {\n\t\t\t\tsynch: true,\n\t\t\t\tparams,\n\t\t\t\tsynchProperty: conf.synch.property,\n\t\t\t\tquery: query.query,\n\t\t\t\ttemplates,\n\t\t\t\tprintouts,\n\t\t\t\turlParams,\n\t\t\t\tsourcePage: mw.config.get( 'wgPageName' )\n\t\t\t};\n\n\t\t\tif ( !Array.isArray( conf.buttons ) ) {\n\t\t\t\tconf.buttons = [];\n\t\t\t}\n\n\t\t\t// https://datatables.net/reference/feature/buttons.buttons\n\t\t\tconf.buttons.unshift( {\n\t\t\t\ttext: mw.msg( 'visualdata-jsmodule-datatables-buttons-reload-label' ),\n\t\t\t\tattr: {\n\t\t\t\t\tid: 'visualdata-datatables-buttons-reload-' + ElIndex,\n\t\t\t\t\tstyle: 'display: none'\n\t\t\t\t},\n\t\t\t\taction: function ( e, dt, node, config ) {\n\t\t\t\t\t// called from the OOUII button\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// call each n seconds, if new items\n\t\t\t// exist, show the update button to\n\t\t\t// retrieve again the original query\n\t\t\tSynchInterval = setInterval( function () {\n\t\t\t\tvar callback = function ( result ) {\n\t\t\t\t\t// update time\n\t\t\t\t\tconf.queryTime = result.queryTime;\n\t\t\t\t\t// *** for now we leave it, we retrieve\n\t\t\t\t\t// instead the all table\n\t\t\t\t\t// $( self ).DataTable( conf ).row.add( json.data ).draw( false );\n\n\t\t\t\t\tif ( result.count > 0 ) {\n\t\t\t\t\t\tclearInterval( SynchInterval );\n\t\t\t\t\t\taddBadge();\n\n\t\t\t\t\t\t// $( '#visualdata-datatables-buttons-reload-' + ElIndex ).show();\n\t\t\t\t\t\tvar reloadButton = new OO.ui.ButtonWidget( {\n\t\t\t\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-datatables-buttons-reload-table-label' ),\n\t\t\t\t\t\t\t// or bell\n\t\t\t\t\t\t\ticon: 'reload',\n\t\t\t\t\t\t\tflags: [ 'destructive' ]\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\treloadButton.on( 'click', function () {\n\t\t\t\t\t\t\treloadButton.setDisabled( true );\n\t\t\t\t\t\t\treloadButton.$element.find( '.oo-ui-iconElement-icon' ).addClass( 'rotating' );\n\n\t\t\t\t\t\t\tvar thisCallback = function ( thisResult ) {\n\t\t\t\t\t\t\t\treloadButton.$element.find( '.oo-ui-iconElement-icon' ).removeClass( 'rotating' );\n\t\t\t\t\t\t\t\treloadButton.setDisabled( false );\n\t\t\t\t\t\t\t\tDatatable.destroy();\n\t\t\t\t\t\t\t\trestoreBadge();\n\t\t\t\t\t\t\t\tel = $( el ).replaceWithPush( thisResult.data );\n\t\t\t\t\t\t\t\t// eslint-disable-next-line no-new\n\t\t\t\t\t\t\t\tnew VisualDataDatatables( el );\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tcallApiSynch( $.extend( payloadDataSync, {\n\t\t\t\t\t\t\t\tapi: false\n\t\t\t\t\t\t\t} ),\n\t\t\t\t\t\t\tthisCallback,\n\t\t\t\t\t\t\tdisplayLog\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t$( '#visualdata-datatables-buttons-reload-' + ElIndex ).replaceWith( reloadButton.$element );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tcallApiSynch( $.extend( payloadDataSync, {\n\t\t\t\t\tqueryTime: conf.queryTime,\n\t\t\t\t\tapi: true\n\t\t\t\t} ),\n\t\t\t\tcallback,\n\t\t\t\tdisplayLog\n\t\t\t\t);\n\t\t\t}, conf.synch.interval * 1000 );\n\t\t}\n\n\t\t// default layout\n\t\t// https://datatables.net/reference/option/layout\n\t\tif ( conf.buttons.length &&\n\t\t\tconf.layout.topStart !== 'buttons' &&\n\t\t\tconf.layout.topEnd !== 'buttons' &&\n\t\t\tconf.layout.bottomStart !== 'buttons' &&\n\t\t\tconf.layout.bottomEnd !== 'buttons'\n\t\t) {\n\t\t\tconf.layout.top1Start = 'buttons';\n\t\t}\n\n\t\tif ( searchPanes ) {\n\t\t\t// https://datatables.net/examples/layout/ids-and-classes.html\n\t\t\tconf.layout.top2 = {\n\t\t\t\t// whatever class\n\t\t\t\trowClass: 'row-class',\n\t\t\t\tfeatures: 'searchPanes'\n\t\t\t};\n\n\t\t\tinitSearchPanesColumns( columnDefs, conf );\n\n\t\t\tif ( !useAjax ) {\n\t\t\t\tsearchPanesOptions = getPanesOptions(\n\t\t\t\t\tdata,\n\t\t\t\t\tcolumnDefs,\n\t\t\t\t\tconf\n\t\t\t\t);\n\t\t\t\tsetPanesOptions(\n\t\t\t\t\tdata,\n\t\t\t\t\tsearchPanesOptions,\n\t\t\t\t\tcolumnDefs\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsearchPanesOptions = searchPanesOptionsServer(\n\t\t\t\t\tsearchPanesOptions,\n\t\t\t\t\tcolumnDefs,\n\t\t\t\t\tconf,\n\t\t\t\t\theadersRaw\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconf.columnDefs = columnDefs;\n\n\t\tconf.drawCallback = function ( settings ) {\n\t\t\tif ( conf.cards ) {\n\t\t\t\trenderCards( headers );\n\t\t\t}\n\t\t};\n\n\t\tvar extendButtons = function ( obj ) {\n\t\t\tvar defaultExtend = function ( name ) {\n\t\t\t\treturn {\n\t\t\t\t\textend: name,\n\t\t\t\t\t// @see https://datatables.net/extensions/buttons/examples/print/columns.html\n\t\t\t\t\texportOptions: {\n\t\t\t\t\t\tcolumns: ':visible'\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tfor ( var i in conf.buttons ) {\n\t\t\t\t// @see https://datatables.net/reference/button/?extn=buttons\n\t\t\t\tswitch ( conf.buttons[ i ] ) {\n\t\t\t\t\tcase 'print':\n\t\t\t\t\tcase 'pdf':\n\t\t\t\t\tcase 'excel':\n\t\t\t\t\tcase 'csv':\n\t\t\t\t\tcase 'copy':\n\t\t\t\t\t\tconf.buttons[ i ] = $.extend( defaultExtend( conf.buttons[ i ] ), obj );\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// conf.destroy = true;\n\t\t// conf.retrieve = false;\n\t\tif ( !useAjax ) {\n\t\t\tconf.serverSide = false;\n\t\t\tconf.data = data;\n\n\t\t\textendButtons();\n\n\t\t\t// use Ajax only when required\n\t\t} else {\n\t\t\t// prevents double spinner\n\t\t\t// $(container).find(\".datatables-spinner\").hide();\n\n\t\t\textendButtons( { action: exportAction } );\n\n\t\t\t// cache using the column index and sorting\n\t\t\t// method, as pseudo-multidimensional array\n\t\t\t// column index + dir (asc/desc) + searchPanes (empty selection)\n\t\t\tvar cacheKey = getCacheKey( {\n\t\t\t\torder: order.map( ( x ) => {\n\t\t\t\t\treturn { column: x[ 0 ], dir: x[ 1 ] };\n\t\t\t\t} )\n\t\t\t} );\n\n\t\t\tsetCacheData( { cacheKey, data, recordsFiltered: Count, start: params.offset } );\n\n\t\t\tvar payloadData = {\n\t\t\t\tquery,\n\t\t\t\tcolumnDefs,\n\t\t\t\tprintouts,\n\t\t\t\tparams,\n\t\t\t\ttemplates,\n\t\t\t\tcategoryFields,\n\t\t\t\tsourcePage: mw.config.get( 'wgPageName' ),\n\t\t\t\tsettings: { count: Count, displayLog }\n\t\t\t};\n\n\t\t\tconf = $.extend( conf, {\n\t\t\t\t// *** attention! deferLoading when used in conjunction with\n\t\t\t\t// ajax, expects only the first page of data, if the preloaded\n\t\t\t\t// data contain more rows, datatables will show a wrong rows\n\t\t\t\t// counter. For this reason we renounce to use deferRender, and\n\t\t\t\t// instead we use the following hack: the Ajax function returns\n\t\t\t\t// the preloaded data as long they are available for the requested\n\t\t\t\t// slice, and then it uses an ajax call for not available data.\n\t\t\t\t// deferLoading: table.data(\"count\"),\n\t\t\t\tprocessing: true,\n\t\t\t\tserverSide: true,\n\t\t\t\tajax: function ( datatableData, thisCallback, settings ) {\n\n\t\t\t\t\t// must match initial cacheKey\n\t\t\t\t\tvar thisCacheKey = ( !VisualDataFunctions.getNestedProp( [ 'search', 'value' ], datatableData ) ?\n\t\t\t\t\t\tgetCacheKey( datatableData ) :\n\t\t\t\t\t\tnull );\n\n\t\t\t\t\t// returned cached data for the required\n\t\t\t\t\t// dimension (order column/dir)\n\t\t\t\t\tif ( thisCacheKey ) {\n\t\t\t\t\t\tvar cacheData = getCacheData( thisCacheKey, datatableData );\n\t\t\t\t\t\tif ( cacheData ) {\n\t\t\t\t\t\t\treturn thisCallback( {\n\t\t\t\t\t\t\t\tdraw: datatableData.draw,\n\t\t\t\t\t\t\t\tdata: cacheData.data,\n\t\t\t\t\t\t\t\trecordsTotal: Count,\n\t\t\t\t\t\t\t\trecordsFiltered: cacheData.count,\n\t\t\t\t\t\t\t\tsearchPanes: {\n\t\t\t\t\t\t\t\t\toptions: searchPanesOptions\n\t\t\t\t\t\t\t\t}\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\t// flush cache each 40,000 rows\n\t\t\t\t\t// *** another method is to compute the actual\n\t\t\t\t\t// size in bytes of each row, but it takes more\n\t\t\t\t\t// resources\n\t\t\t\t\tfor ( var ii in PreloadData ) {\n\t\t\t\t\t\tvar totalSize = objectValues( PreloadData[ ii ].data ).length;\n\n\t\t\t\t\t\tif ( totalSize > getCacheLimit() ) {\n\t\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\t\tconsole.log( 'flushing datatables cache!' );\n\t\t\t\t\t\t\tPreloadData[ ii ] = {};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcallApi(\n\t\t\t\t\t\t$.extend( payloadData, {\n\t\t\t\t\t\t\tdatatableData,\n\t\t\t\t\t\t\tcacheKey: thisCacheKey,\n\t\t\t\t\t\t\turlParams,\n\t\t\t\t\t\t\tapi: true\n\t\t\t\t\t\t} ),\n\t\t\t\t\t\tthisCallback,\n\t\t\t\t\t\tsearchPanesOptions,\n\t\t\t\t\t\tdisplayLog\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tif ( displayLog ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log( 'conf', conf );\n\t\t}\n\n\t\tDatatable = $( el ).DataTable( conf );\n\t};\n\n\trender();\n};\n\n$( function () {\n\t// https://stackoverflow.com/questions/6118778/jquery-replacewith-find-new-element\n\t$.fn.replaceWithPush = function ( a ) {\n\t\tvar $a = $( a );\n\t\tthis.replaceWith( $a );\n\t\treturn $a;\n\t};\n\n\tvar buttons = [];\n\t$( '.visualdata.datatable' ).each( function () {\n\t\tvar data = $( this ).data();\n\t\tif ( data.conf && ( 'buttons' in data.conf ) && Array.isArray( data.conf.buttons ) ) {\n\t\t\tbuttons = buttons.concat( data.conf.buttons );\n\t\t}\n\t} );\n\n\tvar modules = [];\n\tif ( buttons.includes( 'pdf' ) ) {\n\t\tmodules.push( 'ext.VisualData.Datatables.export.pdf' );\n\t}\n\n\tif ( buttons.includes( 'excel' ) ) {\n\t\tmodules.push( 'ext.VisualData.Datatables.export.excel' );\n\t}\n\n\tfunction initialize() {\n\t\t$( '.visualdata.datatable' ).each( function ( index ) {\n\t\t\t// eslint-disable-next-line no-new\n\t\t\tnew VisualDataDatatables( this, index );\n\t\t} );\n\t}\n\n\tif ( !modules.length ) {\n\t\tinitialize();\n\t} else {\n\t\tmw.loader.using( modules, function () {\n\t\t\tinitialize();\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":"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/VisualDataFormField.js","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 108. Maximum allowed is 100.","line":284,"column":1,"nodeType":"Program","messageId":"max","endLine":284,"endColumn":100},{"ruleId":"max-len","severity":1,"message":"This line has a length of 135. Maximum allowed is 100.","line":300,"column":1,"nodeType":"Program","messageId":"max","endLine":300,"endColumn":124},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":1042,"column":4,"nodeType":"CallExpression","endLine":1042,"endColumn":61}],"suppressedMessages":[{"ruleId":"no-unused-vars","severity":2,"message":"'VisualDataFormField' is assigned a value but never used.","line":25,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":25,"endColumn":26,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":245,"column":14,"nodeType":"Program","messageId":"unexpectedTab","endLine":245,"endColumn":15,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":245,"column":32,"nodeType":"Program","messageId":"unexpectedTab","endLine":245,"endColumn":33,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'value' is defined but never used.","line":351,"column":49,"nodeType":"Identifier","messageId":"unusedVar","endLine":351,"endColumn":54,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":423,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":423,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":426,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":426,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":456,"column":14,"nodeType":"Program","messageId":"unexpectedTab","endLine":456,"endColumn":15,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":456,"column":32,"nodeType":"Program","messageId":"unexpectedTab","endLine":456,"endColumn":33,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'value' is defined but never used.","line":527,"column":49,"nodeType":"Identifier","messageId":"unusedVar","endLine":527,"endColumn":54,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'value' is defined but never used.","line":532,"column":69,"nodeType":"Identifier","messageId":"unusedVar","endLine":532,"endColumn":74,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'data' is assigned a value but never used.","line":556,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":556,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'value' is defined but never used.","line":811,"column":50,"nodeType":"Identifier","messageId":"unusedVar","endLine":811,"endColumn":55,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":968,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":968,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":969,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":969,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":970,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":970,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":971,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":971,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":981,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":981,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":982,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":982,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":983,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":983,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":984,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":984,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1005,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1005,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1006,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1006,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1012,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1012,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1013,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1013,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1014,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1014,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1015,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1015,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1016,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1016,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'property' is defined but never used.","line":1188,"column":45,"nodeType":"Identifier","messageId":"unusedVar","endLine":1188,"endColumn":53,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright ©2023-2025, https://wikisphere.org\n */\n\n/* eslint-disable no-tabs */\n\n// eslint-disable-next-line no-unused-vars\nconst VisualDataFormField = function ( phpConfig, windowManager, schemas ) {\n\tvar Config = phpConfig;\n\tvar WindowManager = windowManager;\n\tvar Schemas = schemas;\n\tvar VisualDataInputConfigInst = new VisualDataInputConfig(\n\t\tphpConfig,\n\t\twindowManager\n\t);\n\n\tvar ProcessDialog;\n\tvar Model;\n\tvar ParentObj;\n\tvar panelLayout;\n\tvar CurrentKey;\n\tvar Callback;\n\tvar HandleOptionsInputsInt;\n\tvar HandleQueryOptionsInt;\n\n\tfunction inArray( val, arr ) {\n\t\treturn arr.includes( val );\n\t}\n\n\tfunction getCurrentItem() {\n\t\tif ( !( CurrentKey in ParentObj ) ) {\n\t\t\treturn null;\n\t\t}\n\t\treturn ParentObj[ CurrentKey ];\n\t}\n\n\tfunction getPropertyValue( value, propName ) {\n\t\treturn VisualDataSchemas.getPropertyValue( value, propName, {\n\t\t\tgetCurrentItem: getCurrentItem,\n\t\t\tgetModel: getModel\n\t\t} );\n\t}\n\n\tfunction getModel() {\n\t\treturn Model;\n\t}\n\n\tfunction getAvailableInputs(\n\t\tpropertyModel,\n\t\tJSONSchemaType,\n\t\tstringFormat,\n\t\tmultipleItems\n\t) {\n\t\tvar ret = VisualDataFunctions.getAvailableInputs(\n\t\t\tJSONSchemaType,\n\t\t\tstringFormat,\n\t\t\tConfig\n\t\t);\n\n\t\t// remove multiselects\n\t\tif ( multipleItems === false ) {\n\t\t\treturn ret.filter( ( x ) => !VisualDataFunctions.isMultiselect( x ) );\n\t\t}\n\n\t\t// remove options inputs and lookup widgets\n\t\t// except multiselect\n\t\treturn ret.filter(\n\t\t\t( x ) =>\n\t\t\t\t( !VisualDataFunctions.lookupInputs.includes( x ) &&\n\t\t\t\t\t!VisualDataFunctions.optionsInputs.includes( x ) ) ||\n\t\t\t\tVisualDataFunctions.isMultiselect( x )\n\t\t);\n\t}\n\n\tfunction UpdateModel( modelMap, visibleItems ) {\n\t\tvar optionsHasVisibleItems = HandleOptionsInputsInt.hasVisibleItems();\n\t\tvar queryHasVisibleItems = HandleQueryOptionsInt.hasVisibleItems();\n\n\t\tfor ( var i in modelMap ) {\n\t\t\tif ( visibleItems ) {\n\t\t\t\tModel[ i ] = modelMap[ i ];\n\n\t\t\t} else {\n\t\t\t\tvar visibleSharedOptions =\n\t\t\t\t\tObject.keys( HandleOptionsInputsInt.modelMap ).includes( i ) &&\n\t\t\t\t\tObject.keys( HandleQueryOptionsInt.modelMap ).includes( i ) &&\n\t\t\t\t\t( optionsHasVisibleItems || queryHasVisibleItems );\n\n\t\t\t\tif ( !visibleSharedOptions ) {\n\t\t\t\t\tdelete Model[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// @TODO move to VisualDataInputConfig ?\n\tfunction handleOptionsInputs( availableInputsInput, parentItems ) {\n\t\tvar items = [];\n\t\tvar layout = new OO.ui.PanelLayout( {\n\t\t\texpanded: false,\n\t\t\tpadded: true,\n\t\t\tframed: true,\n\t\t\tclasses: []\n\t\t} );\n\n\t\tvar fieldset = new OO.ui.FieldsetLayout( {\n\t\t\tlabel: 'Options'\n\t\t} );\n\n\t\tlayout.$element.append( fieldset.$element );\n\n\t\tparentItems.push( layout );\n\n\t\t// keep the variables separated\n\t\tvar optionsWikilistValue = getPropertyValue( 'options-wikilist' ) || '';\n\t\t// var optionsQueryValue = getPropertyValue( 'options-query' ) || '';\n\t\t// var optionsSMWQueryValue = getPropertyValue( 'options-smwquery' ) || '';\n\t\tvar optionsValues = getPropertyValue( 'options-values' ) || [];\n\n\t\tvar selectOptionsFromValue = getPropertyValue( 'selectOptionsFrom' );\n\n\t\t// @TODO add more data sources\n\t\tvar methods = [ 'values', 'wikilist', 'query' ];\n\n\t\tif ( Config.SMW ) {\n\t\t\tmethods.push( 'smwquery' );\n\t\t}\n\n\t\t// only for lookup widget\n\t\tvar methodsReduced = [ 'query' ];\n\t\tif ( Config.SMW ) {\n\t\t\tmethodsReduced.push( 'smwquery' );\n\t\t}\n\n\t\tvar inputIsEmpty = function ( thisMethod, value ) {\n\t\t\tswitch ( thisMethod ) {\n\t\t\t\tcase 'values':\n\t\t\t\t\treturn !value.length;\n\t\t\t\tdefault:\n\t\t\t\t\treturn value === '';\n\t\t\t}\n\t\t};\n\n\t\tif ( selectOptionsFromValue === '' ) {\n\t\t\tfor ( var method of methods ) {\n\t\t\t\tif ( !inputIsEmpty( method, getPropertyValue( 'options-' + method ) ) ) {\n\t\t\t\t\tselectOptionsFromValue = 'options-' + method;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar selectOptionsFrom = new OO.ui.RadioSelectInputWidget( {\n\t\t\toptions: methods.map( function ( x ) {\n\t\t\t\treturn {\n\t\t\t\t\tdata: 'options-' + x,\n\t\t\t\t\t// Messages that can be used here:\n\t\t\t\t\t// * visualdata-jsmodule-formfield-optionsfrom-values\n\t\t\t\t\t// * visualdata-jsmodule-formfield-optionsfrom-wikilist\n\t\t\t\t\t// * visualdata-jsmodule-formfield-optionsfrom-query\n\t\t\t\t\t// * visualdata-jsmodule-formfield-optionsfrom-smwquery\n\t\t\t\t\tlabel: mw.msg(\n\t\t\t\t\t\t'visualdata-jsmodule-formfield-optionsfrom-' + x\n\t\t\t\t\t)\n\t\t\t\t};\n\t\t\t} ),\n\t\t\tvalue: selectOptionsFromValue\n\t\t} );\n\n\t\tvar nullValueInput = new OO.ui.ToggleSwitchWidget( {\n\t\t\tvalue: getPropertyValue( 'options-allow-null' )\n\t\t} );\n\n\t\tvar fieldNullValue = new OO.ui.FieldLayout( nullValueInput, {\n\t\t\tlabel: '',\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-nullvalue' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldNullValue );\n\n\t\tvar fieldSelectOptionsFrom = new OO.ui.FieldLayout( selectOptionsFrom, {\n\t\t\tlabel: new OO.ui.HtmlSnippet(\n\t\t\t\tmw.msg( 'visualdata-jsmodule-formfield-options-from' )\n\t\t\t),\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldSelectOptionsFrom );\n\n\t\tvar messageWidgetOptionsQuery = new OO.ui.MessageWidget( {\n\t\t\ttype: 'info',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-message-options-query' ),\n\t\t\tclasses: [ 'VisualDataFormFieldMessage' ]\n\t\t} );\n\n\t\titems.push( messageWidgetOptionsQuery );\n\n\t\tvar optionsValuesInput = new OO.ui.TagMultiselectWidget( {\n\t\t\tselected: optionsValues,\n\t\t\tallowArbitrary: true,\n\t\t\torientation: 'vertical'\n\t\t} );\n\n\t\tvar fieldOptionsValues = new OO.ui.FieldLayout( optionsValuesInput, {\n\t\t\tlabel: '',\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-options-values' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldOptionsValues );\n\n\t\tvar wikilistInput = new mw.widgets.TitleInputWidget( {\n\t\t\tvalue: optionsWikilistValue\n\t\t} );\n\n\t\tvar fieldWikilist = new OO.ui.FieldLayout( wikilistInput, {\n\t\t\tlabel: '',\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-wikilist' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldWikilist );\n\n\t\t// ////////\t@credits: WikiTeq\t///////\n\t\tvar optionsLabelFormulaInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'options-label-formula' ),\n\t\t\tautosize: true,\n\t\t\trows: 1\n\t\t} );\n\n\t\tvar fieldOptionsLabelFormula = new OO.ui.FieldLayout(\n\t\t\toptionsLabelFormulaInput,\n\t\t\t{\n\t\t\t\tlabel: mw.msg(\n\t\t\t\t\t'visualdata-jsmodule-formfield-options-label-formula'\n\t\t\t\t),\n\t\t\t\thelp: mw.msg(\n\t\t\t\t\t'visualdata-jsmodule-formfield-options-label-formula-help'\n\t\t\t\t),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t}\n\t\t);\n\n\t\titems.push( fieldOptionsLabelFormula );\n\n\t\t// ///////////////////////////\n\n\t\tfunction hasVisibleItems() {\n\t\t\tfor ( var item of fieldset.items ) {\n\t\t\t\tif ( item.isVisible() ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tselectOptionsFrom.on( 'change', function ( value ) {\n\t\t\tfieldOptionsValues.toggle( value === 'options-values' );\n\t\t\tfieldWikilist.toggle( value === 'options-wikilist' );\n\t\t\tfieldOptionsLabelFormula.toggle( value !== 'options-query' && value !== 'options-smwquery' );\n\n\t\t\tvar optionInput = inArray( availableInputsInput.getValue(), VisualDataFunctions.optionsInputs );\n\t\t\tmessageWidgetOptionsQuery.toggle( optionInput && ( value === 'options-query' || value === 'options-smwquery' ) );\n\t\t} );\n\n\t\tvar modelMap = {\n\t\t\tselectOptionsFrom: selectOptionsFrom,\n\t\t\t'options-allow-null': nullValueInput,\n\t\t\t'options-values': optionsValuesInput,\n\t\t\t'options-wikilist': wikilistInput,\n\t\t\t'options-label-formula': optionsLabelFormulaInput\n\t\t};\n\n\t\tfunction onSelectAvailableInputs() {\n\t\t\tvar availableInputsValue = availableInputsInput.getValue();\n\n\t\t\tselectOptionsFrom.setOptions(\n\t\t\t\t( !inArray( availableInputsValue, VisualDataFunctions.lookupInputs ) ? methods : methodsReduced ).map( function ( x ) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdata: 'options-' + x,\n\n\t\t\t\t\t\t// Messages that can be used here:\n\t\t\t\t\t\t// * visualdata-jsmodule-formfield-optionsfrom-values\n\t\t\t\t\t\t// * visualdata-jsmodule-formfield-optionsfrom-wikilist\n\t\t\t\t\t\t// * visualdata-jsmodule-formfield-optionsfrom-query\n\t\t\t\t\t\t// * visualdata-jsmodule-formfield-optionsfrom-smwquery\n\t\t\t\t\t\tlabel: mw.msg(\n\t\t\t\t\t\t\t'visualdata-jsmodule-formfield-optionsfrom-' + x.toLowerCase()\n\t\t\t\t\t\t)\n\t\t\t\t\t};\n\t\t\t\t} )\n\t\t\t);\n\n\t\t\tvar thisSelectOptionsFromValue = selectOptionsFrom.getValue();\n\t\t\tvar optionInput = inArray( availableInputsValue, VisualDataFunctions.optionsInputs );\n\n\t\t\tfieldSelectOptionsFrom.toggle( optionInput ||\n\t\t\t\t( Config.SMW && inArray( availableInputsValue, VisualDataFunctions.lookupInputs ) )\n\t\t\t);\n\n\t\t\tmessageWidgetOptionsQuery.toggle( optionInput && ( thisSelectOptionsFromValue === 'options-query' || thisSelectOptionsFromValue === 'options-smwquery' ) );\n\t\t\tfieldNullValue.toggle( optionInput );\n\n\t\t\tfieldOptionsValues.toggle(\n\t\t\t\toptionInput &&\n\t\t\t\t\t( !thisSelectOptionsFromValue ||\n\t\t\t\t\t\tthisSelectOptionsFromValue === 'options-values' )\n\t\t\t);\n\t\t\tfieldWikilist.toggle( optionInput && thisSelectOptionsFromValue === 'options-wikilist' );\n\n\t\t\tfieldOptionsLabelFormula.toggle(\n\t\t\t\tthisSelectOptionsFromValue !== 'options-query' &&\n\t\t\t\tthisSelectOptionsFromValue !== 'options-smwquery' &&\n\t\t\t\tinArray( availableInputsValue, VisualDataFunctions.labelFormulaInputs ) &&\n\t\t\t\t!inArray( availableInputsValue, VisualDataFunctions.lookupInputs )\n\t\t\t);\n\n\t\t\tvar thisVisibleItems = hasVisibleItems();\n\t\t\tUpdateModel( modelMap, thisVisibleItems );\n\t\t\tlayout.toggle( thisVisibleItems );\n\t\t}\n\n\t\tfieldset.addItems( items );\n\n\t\tvar visibleItems = hasVisibleItems();\n\t\tlayout.toggle( visibleItems );\n\n\t\t// eslint-disable-next-line no-unused-vars\n\t\tavailableInputsInput.on( 'change', function ( value ) {\n\t\t\tonSelectAvailableInputs();\n\t\t} );\n\n\t\treturn { selectOptionsFrom, hasVisibleItems, modelMap, onSelectAvailableInputs };\n\t}\n\n\tfunction handleQueryOptions( availableInputsInput, parentItems ) {\n\t\tvar items = [];\n\t\tvar layout = new OO.ui.PanelLayout( {\n\t\t\texpanded: false,\n\t\t\tpadded: true,\n\t\t\tframed: true,\n\t\t\tclasses: []\n\t\t} );\n\n\t\tvar fieldset = new OO.ui.FieldsetLayout( {\n\t\t\tlabel: 'Options'\n\t\t} );\n\n\t\tlayout.$element.append( fieldset.$element );\n\n\t\tparentItems.push( layout );\n\n\t\tvar queryInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'options-query' )\n\t\t} );\n\n\t\tvar fieldQuery = new OO.ui.FieldLayout( queryInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-query-label' ),\n\t\t\thelp: new OO.ui.HtmlSnippet( mw.msg( 'visualdata-jsmodule-formfield-query-help' ) ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldQuery );\n\n\t\tvar SMWQueryInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'options-smwquery' )\n\t\t} );\n\n\t\tvar fieldSMWQuery = new OO.ui.FieldLayout( SMWQueryInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-smwquery-label' ),\n\t\t\thelp: new OO.ui.HtmlSnippet( mw.msg( 'visualdata-jsmodule-formfield-smwquery-help' ) ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldSMWQuery );\n\n\t\tvar schemaInput = new OO.ui.DropdownInputWidget( {\n\t\t\toptions: VisualDataFunctions.createDropDownOptions(\n\t\t\t\tVisualDataFunctions.sort( Object.keys( Schemas ) ),\n\t\t\t\t{ key: 'value' }\n\t\t\t),\n\t\t\tvalue: getPropertyValue( 'query-schema' )\n\t\t} );\n\n\t\tvar fieldSchema = new OO.ui.FieldLayout( schemaInput, {\n\t\t\tlabel: mw.msg(\n\t\t\t\t'visualdata-jsmodule-formfield-query-schema-label'\n\t\t\t),\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-query-schema-help' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldSchema );\n\n\t\tvar printoutsInputValue = getPropertyValue( 'query-printouts' ) || [];\n\n\t\t// var printoutsInput = new mw.widgets.TitlesMultiselectWidget({\n\t\t// \tselected: printoutsInputValue,\n\n\t\t// https://www.semantic-mediawiki.org/wiki/Help:Namespaces\n\t\t// \tnamespace: 102,\n\t\t// });\n\n\t\tvar printoutsInput = new OO.ui.TagMultiselectWidget( {\n\t\t\tallowArbitrary: true,\n\t\t\tselected: printoutsInputValue\n\t\t} );\n\n\t\tvar fieldPrintouts = new OO.ui.FieldLayout( printoutsInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-printouts' ),\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-printouts-help' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldPrintouts );\n\n\t\tvar optionFormulaInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'options-query-formula' )\n\t\t} );\n\n\t\tvar fieldOptionFormula = new OO.ui.FieldLayout( optionFormulaInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-optionformula' ),\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-optionformula-help' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldOptionFormula );\n\n\t\t// ////////\t@credits: WikiTeq\t///////\n\n\t\tvar optionsLabelFormulaInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'options-label-formula' ),\n\t\t\tautosize: true,\n\t\t\trows: 1\n\t\t} );\n\n\t\tvar fieldOptionsLabelFormula = new OO.ui.FieldLayout(\n\t\t\toptionsLabelFormulaInput,\n\t\t\t{\n\t\t\t\tlabel: mw.msg(\n\t\t\t\t\t'visualdata-jsmodule-formfield-options-label-formula'\n\t\t\t\t),\n\t\t\t\thelp: mw.msg(\n\t\t\t\t\t'visualdata-jsmodule-formfield-options-label-formula-help'\n\t\t\t\t),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t}\n\t\t);\n\n\t\titems.push( fieldOptionsLabelFormula );\n\t\t// ///////////////////////////\n\n\t\tvar modelMap = {\n\t\t\t'options-query': queryInput,\n\t\t\t'options-smwquery': SMWQueryInput,\n\t\t\t'query-schema': schemaInput,\n\t\t\t'query-printouts': printoutsInput,\n\t\t\t'options-query-formula': optionFormulaInput,\n\t\t\t'options-label-formula': optionsLabelFormulaInput\n\t\t};\n\n\t\tfunction hasVisibleItems() {\n\t\t\tfor ( var item of fieldset.items ) {\n\t\t\t\tif ( item.isVisible() ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tfunction onSelectAvailableInputs() {\n\t\t\tvar availableInputsValue = availableInputsInput.getValue();\n\t\t\tvar selectOptionsFromValue = HandleOptionsInputsInt.selectOptionsFrom.getValue();\n\n\t\t\tvar optionInput = ( ( selectOptionsFromValue === 'options-query' || selectOptionsFromValue === 'options-smwquery' ) &&\n\t\t\t\tinArray( availableInputsValue, VisualDataFunctions.optionsInputs ) );\n\t\t\tvar lookupInput = inArray( availableInputsValue, VisualDataFunctions.lookupInputs );\n\t\t\tvar labelFormulaInput = ( ( selectOptionsFromValue === 'options-query' || selectOptionsFromValue === 'options-smwquery' ) &&\n\t\t\t\tinArray( availableInputsValue, VisualDataFunctions.labelFormulaInputs ) );\n\n\t\t\tfieldQuery.toggle( ( lookupInput || optionInput ) && selectOptionsFromValue === 'options-query' );\n\t\t\tfieldSMWQuery.toggle( ( lookupInput || optionInput ) && selectOptionsFromValue === 'options-smwquery' );\n\t\t\tfieldPrintouts.toggle( lookupInput || optionInput );\n\t\t\tfieldSchema.toggle( ( lookupInput || optionInput ) && selectOptionsFromValue !== 'options-smwquery' );\n\t\t\tfieldOptionFormula.toggle( lookupInput || optionInput );\n\t\t\tfieldOptionsLabelFormula.toggle( labelFormulaInput );\n\n\t\t\tvar thisVisibleItems = hasVisibleItems();\n\t\t\tUpdateModel( modelMap, thisVisibleItems );\n\t\t\tlayout.toggle( thisVisibleItems );\n\t\t}\n\n\t\tfieldset.addItems( items );\n\n\t\tvar visibleItems = hasVisibleItems();\n\t\tlayout.toggle( visibleItems );\n\n\t\t// eslint-disable-next-line no-unused-vars\n\t\tavailableInputsInput.on( 'change', function ( value ) {\n\t\t\tonSelectAvailableInputs();\n\t\t} );\n\n\t\t// eslint-disable-next-line no-unused-vars\n\t\tHandleOptionsInputsInt.selectOptionsFrom.on( 'change', function ( value ) {\n\t\t\tonSelectAvailableInputs();\n\t\t} );\n\n\t\treturn { modelMap, hasVisibleItems, onSelectAvailableInputs };\n\t}\n\n\tfunction PanelLayout( config ) {\n\t\tPanelLayout.super.call( this, config );\n\n\t\tthis.fieldset = new OO.ui.FieldsetLayout( {\n\t\t\tlabel: ''\n\t\t} );\n\n\t\tthis.populateFieldset();\n\n\t\tthis.$element.append( this.fieldset.$element );\n\t}\n\n\tOO.inheritClass( PanelLayout, OO.ui.PanelLayout );\n\tPanelLayout.prototype.populateFieldset = function () {\n\t\tthis.fieldset.clearItems();\n\n\t\t// eslint-disable-next-line no-unused-vars\n\t\tvar data = this.data;\n\t\tvar items = [];\n\n\t\tvar currentItem = getCurrentItem();\n\t\tvar parentSchema = {};\n\n\t\t// @see VisualDataSchemas\n\t\tif (\n\t\t\tcurrentItem &&\n\t\t\tcurrentItem.type === 'array' &&\n\t\t\tVisualDataFunctions.isObject( currentItem.items )\n\t\t) {\n\t\t\tparentSchema = currentItem;\n\t\t\tcurrentItem = currentItem.items; // JSON.parse(JSON.stringify(currentItem.items));\n\t\t}\n\n\t\tvar nameInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'name' ) || CurrentKey\n\t\t} );\n\n\t\tModel.name = nameInput;\n\n\t\titems.push(\n\t\t\tnew OO.ui.FieldLayout( nameInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-name' ),\n\t\t\t\thelpInline: true,\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-name-help' ),\n\t\t\t\talign: 'top'\n\t\t\t} )\n\t\t);\n\n\t\tvar visibilityInputValue = getPropertyValue( 'visibility' );\n\n\t\tvar visibilityInput = new OO.ui.DropdownInputWidget( {\n\t\t\toptions: VisualDataFunctions.createDropDownOptions( {\n\t\t\t\tvisible: mw.msg( 'visualdata-jsmodule-formfield-visibility-visible' ),\n\t\t\t\tcondition: mw.msg( 'visualdata-jsmodule-formfield-visibility-condition' ),\n\t\t\t\thidden: mw.msg( 'visualdata-jsmodule-formfield-visibility-hidden' ),\n\t\t\t\t'oncreate-only': mw.msg(\n\t\t\t\t\t'visualdata-jsmodule-formfield-visibility-create-only'\n\t\t\t\t)\n\t\t\t} ),\n\t\t\tvalue: visibilityInputValue\n\t\t} );\n\n\t\tModel.visibility = visibilityInput;\n\n\t\titems.push(\n\t\t\tnew OO.ui.FieldLayout( visibilityInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-visibility-label' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-visibility-help' ),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t} )\n\t\t);\n\n\t\t// ------------------ show-if -----------------\n\n\t\tvar otherFields = Object.keys( ParentObj ).filter( ( x ) => {\n\t\t\treturn ( x !== CurrentKey && ParentObj[ x ].wiki.type === 'property' &&\n\t\t\t\tParentObj[ x ].wiki[ 'multiple-items' ] === false );\n\t\t} );\n\n\t\tvar showifFieldInput = new OO.ui.DropdownInputWidget( {\n\t\t\toptions: VisualDataFunctions.createDropDownOptions( otherFields, { key: 'value' } ),\n\t\t\tvalue: getPropertyValue( 'showif-field' )\n\t\t} );\n\n\t\tvar showifConditionInput = new OO.ui.DropdownInputWidget( {\n\t\t\t// @https://github.com/Knowledge-Wiki/SemanticResultFormats/blob/561e5304e17fccc894d7b38ab88a03b75606d6c8/formats/datatables/Api.php\n\t\t\toptions: VisualDataFunctions.createDropDownOptions( {\n\t\t\t\t'=': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-=' ),\n\t\t\t\t'!=': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!=' ),\n\t\t\t\tstarts: mw.msg( 'visualdata-jsmodule-formfield-showif-condition-starts' ),\n\t\t\t\t'!starts': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!starts' ),\n\t\t\t\tcontains: mw.msg( 'visualdata-jsmodule-formfield-showif-condition-contains' ),\n\t\t\t\t'!contains': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!contains' ),\n\t\t\t\tends: mw.msg( 'visualdata-jsmodule-formfield-showif-condition-ends' ),\n\t\t\t\t'!ends': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!ends' ),\n\t\t\t\t'!null': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!null' ),\n\t\t\t\tregex: mw.msg( 'visualdata-jsmodule-formfield-showif-condition-regex' )\n\t\t\t} ),\n\t\t\tvalue: getPropertyValue( 'showif-condition' )\n\t\t} );\n\n\t\tvar showifValueInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'showif-value' )\n\t\t} );\n\n\t\tshowifValueInput.toggle( getPropertyValue( 'showif-condition' ) !== '!null' );\n\n\t\tvar showifValueIsWikitextInput = new OO.ui.ToggleButtonWidget( {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-showif-wikitext' ),\n\t\t\tvalue: getPropertyValue( 'showif-value-wikitext' )\n\t\t} );\n\n\t\tshowifValueIsWikitextInput.toggle( getPropertyValue( 'showif-condition' ) !== '!null' );\n\n\t\tshowifConditionInput.on( 'change', function ( value ) {\n\t\t\tshowifValueInput.toggle( value !== '!null' );\n\t\t\tshowifValueIsWikitextInput.toggle( value !== '!null' );\n\t\t\tupdateModelShowif( getPropertyValue( 'visibility' ) === 'condition' );\n\t\t} );\n\n\t\tvar layoutHorizontal = new OO.ui.HorizontalLayout( { items: [\n\t\t\tshowifFieldInput,\n\t\t\tshowifConditionInput,\n\t\t\tshowifValueInput,\n\t\t\tshowifValueIsWikitextInput\n\t\t] } );\n\n\t\t// Model[ 'showif-field' ] = showifFieldInput;\n\t\t// Model[ 'showif-equal' ] = showifConditionInput;\n\t\t// Model[ 'showif-value' ] = showifValueInput;\n\n\t\tvar showifField = new OO.ui.FieldLayout(\n\t\t\tnew OO.ui.Widget( {\n\t\t\t\tcontent: [ layoutHorizontal ]\n\t\t\t} ),\n\t\t\t{\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-showif' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-showif-help' ),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t}\n\t\t);\n\n\t\titems.push( showifField );\n\n\t\tvar modelMap = {\n\t\t\t'showif-field': showifFieldInput,\n\t\t\t'showif-condition': showifConditionInput,\n\t\t\t'showif-value': showifValueInput,\n\t\t\t'showif-value-wikitext': showifValueIsWikitextInput\n\t\t};\n\n\t\tfunction updateModelShowif( thisVisibleItems ) {\n\t\t\tfor ( var i in modelMap ) {\n\t\t\t\tif ( thisVisibleItems ) {\n\t\t\t\t\tModel[ i ] = modelMap[ i ];\n\t\t\t\t} else {\n\t\t\t\t\tdelete Model[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( getPropertyValue( 'showif-condition' ) === '!null' ) {\n\t\t\t\tdelete Model[ 'showif-value' ];\n\t\t\t}\n\t\t}\n\n\t\tupdateModelShowif( visibilityInputValue === 'condition' );\n\t\tshowifField.toggle( visibilityInputValue === 'condition' );\n\n\t\tfunction onVisibilityInputChange( value ) {\n\t\t\tonToggleHiddenInput( value === 'hidden' );\n\t\t\tshowifField.toggle( value === 'condition' );\n\t\t\tupdateModelShowif( value === 'condition' );\n\t\t}\n\n\t\tvisibilityInput.on( 'change', function ( value ) {\n\t\t\tonVisibilityInputChange( value );\n\t\t} );\n\n\t\t// ------------------ show-if >>>>>>>>>>>>>>>>>\n\n\t\tvar labelValue = getPropertyValue( 'label' );\n\n\t\tvar labelInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: labelValue\n\t\t} );\n\n\t\tModel.label = labelInput;\n\n\t\tvar labelField = new OO.ui.FieldLayout( labelInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-label' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( labelField );\n\n\t\tvar helpMessageInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'help-message' ),\n\t\t\tautosize: true,\n\t\t\trows: 2\n\t\t} );\n\n\t\tModel[ 'help-message' ] = helpMessageInput;\n\n\t\tvar helpMessageField = new OO.ui.FieldLayout( helpMessageInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-help-message' ),\n\t\t\thelpInline: true,\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-help-message-help' ),\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( helpMessageField );\n\n\t\t// *** now a constant\n\t\tvar propertyModelValue = 'json-schema';\n\n\t\tvar jsonSchemaValue = getPropertyValue( 'jsonSchema-type' ) || 'string';\n\n\t\tvar jsonSchemaInput = new OO.ui.DropdownInputWidget( {\n\t\t\toptions: VisualDataFunctions.createDropDownOptions(\n\t\t\t\t[\n\t\t\t\t\t'string',\n\t\t\t\t\t'number',\n\t\t\t\t\t'integer',\n\t\t\t\t\t'boolean'\n\t\t\t\t\t// select rather a type and toggle \"multiple values\"\n\t\t\t\t\t// \"array\",\n\t\t\t\t],\n\t\t\t\t{ key: 'value' }\n\t\t\t),\n\t\t\tvalue: jsonSchemaValue\n\t\t} );\n\n\t\tModel[ 'jsonSchema-type' ] = jsonSchemaInput;\n\n\t\tvar fieldjsonSchemaInput = new OO.ui.FieldLayout( jsonSchemaInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-schematypes' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldjsonSchemaInput );\n\n\t\tvar textFormat = [\n\t\t\t'color',\n\t\t\t'date',\n\t\t\t'datetime',\n\t\t\t// 'datetime-local',\n\t\t\t'email',\n\t\t\t'month',\n\t\t\t'password',\n\t\t\t'number',\n\t\t\t'range',\n\t\t\t'tel',\n\t\t\t'text',\n\t\t\t'textarea',\n\t\t\t'time',\n\t\t\t'url',\n\t\t\t'week'\n\t\t];\n\n\t\tvar jsonSchemaFormatValue = getPropertyValue( 'jsonSchema-format' ) || 'text';\n\t\tvar jsonSchemaFormatInput = new OO.ui.DropdownInputWidget( {\n\t\t\t// , { key: \"value\" }\n\t\t\toptions: VisualDataFunctions.createDropDownOptions( textFormat, {\n\t\t\t\tkey: 'value'\n\t\t\t} ),\n\t\t\tvalue: jsonSchemaFormatValue\n\t\t} );\n\n\t\t// eslint-disable-next-line no-unused-vars\n\t\tjsonSchemaFormatInput.on( 'change', function ( value ) {\n\t\t\tredrawAvailableInputs();\n\t\t} );\n\n\t\tModel[ 'jsonSchema-format' ] = jsonSchemaFormatInput;\n\n\t\tvar fieldjsonSchemaFormatInput = new OO.ui.FieldLayout(\n\t\t\tjsonSchemaFormatInput,\n\t\t\t{\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-schematextsubtypes' ),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t}\n\t\t);\n\n\t\titems.push( fieldjsonSchemaFormatInput );\n\n\t\tjsonSchemaInput.on( 'change', function ( value ) {\n\t\t\tswitch ( value ) {\n\t\t\t\tcase 'string':\n\t\t\t\t\tfieldjsonSchemaFormatInput.toggle( true );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'integer':\n\t\t\t\tcase 'number':\n\t\t\t\tcase 'boolean':\n\t\t\t\t\tfieldjsonSchemaFormatInput.toggle( false );\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tredrawAvailableInputs();\n\t\t} );\n\n\t\tfieldjsonSchemaInput.toggle( propertyModelValue === 'json-schema' );\n\t\tfieldjsonSchemaFormatInput.toggle(\n\t\t\tpropertyModelValue === 'json-schema' && jsonSchemaValue === 'string'\n\t\t);\n\n\t\tvar multipleItemsInputValue =\n\t\t\tgetPropertyValue( 'multiple-items' ) || parentSchema.type === 'array';\n\t\tvar multipleItemsInput = new OO.ui.ToggleSwitchWidget( {\n\t\t\tvalue: multipleItemsInputValue\n\t\t} );\n\n\t\tModel[ 'multiple-items' ] = multipleItemsInput;\n\n\t\tvar layoutParentSchema = VisualDataSchemas.parentSchemaContainer(\n\t\t\t( Model.parentSchema = {} ),\n\t\t\t{\n\t\t\t\tgetPropertyValue: getPropertyValue\n\t\t\t}\n\t\t);\n\t\t// layoutParentSchema.toggle( multipleItemsInputValue );\n\n\t\tvar messageWidget = new OO.ui.MessageWidget( {\n\t\t\ttype: 'info',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-message-more-inputs' ),\n\t\t\tclasses: [ 'VisualDataFormFieldMessage' ]\n\t\t} );\n\n\t\tvar fieldMultipleValues = new OO.ui.FieldLayout( multipleItemsInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-multiple-values' ),\n\t\t\thelp: '',\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( fieldMultipleValues );\n\t\titems.push( layoutParentSchema );\n\n\t\tvar availableInputsValue = getPropertyValue( 'preferred-input' );\n\t\t// preferred input based on property type\n\t\tvar availableInputsInput = new OO.ui.DropdownInputWidget( {\n\t\t\t// , { key: \"value\" }\n\t\t\toptions: VisualDataFunctions.createDropDownOptions(\n\t\t\t\tgetAvailableInputs(\n\t\t\t\t\tpropertyModelValue,\n\t\t\t\t\tjsonSchemaValue,\n\t\t\t\t\tjsonSchemaFormatValue,\n\t\t\t\t\tmultipleItemsInputValue\n\t\t\t\t),\n\t\t\t\t{\n\t\t\t\t\tkey: 'value'\n\t\t\t\t}\n\t\t\t),\n\t\t\tvalue: availableInputsValue\n\t\t} );\n\n\t\tModel[ 'preferred-input' ] = availableInputsInput;\n\n\t\tvar inputConfigButton = new OO.ui.ButtonWidget( {\n\t\t\ticon: 'settings',\n\t\t\tflags: []\n\t\t} );\n\n\t\tvar defaultInputConfig = getPropertyValue( 'input-config' ) || {};\n\n\t\tModel[ 'input-config' ] = new VisualDataFunctions.MockupOOUIClass(\n\t\t\tdefaultInputConfig\n\t\t);\n\n\t\tinputConfigButton.on( 'click', function () {\n\t\t\tVisualDataInputConfigInst.openDialog(\n\t\t\t\tModel[ 'input-config' ],\n\t\t\t\tavailableInputsInput.getValue(),\n\t\t\t\tVisualDataFunctions.getInputHelpUrl( availableInputsInput.getValue() ),\n\t\t\t\tnull\n\t\t\t);\n\t\t} );\n\n\t\titems.push( messageWidget );\n\n\t\titems.push(\n\t\t\tnew OO.ui.ActionFieldLayout( availableInputsInput, inputConfigButton, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-availableinputs' ),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t} )\n\t\t);\n\n\t\tHandleOptionsInputsInt = handleOptionsInputs( availableInputsInput, items );\n\t\tHandleQueryOptionsInt = handleQueryOptions( availableInputsInput, items );\n\n\t\t// this will also call UpdateModel\n\t\tHandleOptionsInputsInt.onSelectAvailableInputs();\n\t\tHandleQueryOptionsInt.onSelectAvailableInputs();\n\n\t\tvar requiredInput = new OO.ui.ToggleSwitchWidget( {\n\t\t\tvalue: !!getPropertyValue( 'required' )\n\t\t} );\n\n\t\tModel.required = requiredInput;\n\n\t\tvar fieldRequiredInput = new OO.ui.FieldLayout( requiredInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-required' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\tmultipleItemsInput.on( 'change', function ( value ) {\n\t\t\tredrawAvailableInputs();\n\t\t\tlayoutParentSchema.toggle( value );\n\t\t\tfieldRequiredInput.toggle( !value );\n\t\t\tnameInput.setDisabled( value );\n\t\t} );\n\n\t\tfieldRequiredInput.toggle( !multipleItemsInputValue );\n\n\t\titems.push( fieldRequiredInput );\n\n\t\tfunction getDefaultValueInput() {\n\t\t\t// @ATTENTION ! don't get the specific input othwerwise\n\t\t\t// the default values cannot be parsed as wikitext\n\t\t\t// print always a textInput and cast\n\t\t\t// the value server-side\n\n\t\t\tvar ret;\n\n\t\t\t// var availableInputs = getAvailableInputs(\n\t\t\t// \tgetPropertyValue(\"propertyModel\") || \"json-schema\",\n\t\t\t// \tgetPropertyValue(\"jsonSchema-type\"),\n\t\t\t// \t\"text\",\n\t\t\t// \tgetPropertyValue(\"multiple-items\")\n\t\t\t// );\n\n\t\t\t// @TODO use instead availableInputsInput.getValue()\n\t\t\t// as long as all the inputs support the standard\n\t\t\t// OOUI interface for the use with OO.ui.TagMultiselectWidget\n\t\t\t// -> inputWidget\n\t\t\t// var intputName = availableInputs[0]; // availableInputsInput.getValue()\n\n\t\t\t// var inputWidget = VisualDataFunctions.inputInstanceFromName(\n\t\t\t// \tintputName,\n\t\t\t// \t{\n\t\t\t// \t\tid: \"visualdata-jsmodule-formfield-default-value-input\",\n\t\t\t// \t}\n\t\t\t// );\n\n\t\t\tvar inputWidget = new OO.ui.TextInputWidget( {\n\t\t\t\t// value: getPropertyValue( 'default' ),\n\t\t\t\tid: 'visualdata-jsmodule-formfield-default-value-input'\n\t\t\t} );\n\n\t\t\tif ( !getPropertyValue( 'multiple-items' ) ) {\n\t\t\t\tif ( 'default' in Model ) {\n\t\t\t\t\tvar value = Model.default.getValue();\n\t\t\t\t\tif ( Array.isArray( value ) && value.length ) {\n\t\t\t\t\t\tModel.default.setValue( value[ 0 ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tinputWidget.setValue( getPropertyValue( 'default' ) );\n\t\t\t\t// set the proper input for each type\n\n\t\t\t\tret = inputWidget;\n\t\t\t\t// return new OO.ui.TextInputWidget({\n\t\t\t\t// \tvalue: getPropertyValue(\"default\"),\n\t\t\t\t// \tid: \"visualdata-jsmodule-formfield-default-value-input\",\n\t\t\t\t// });\n\t\t\t} else {\n\t\t\t\t// OO.ui.TagMultiselectWidget -> inputWidget: inputWidget does not work\n\t\t\t\t// with OO.ui.ToggleSwitchWidget\n\t\t\t\t// if (intputName === \"OO.ui.ToggleSwitchWidget\") {\n\t\t\t\t// \tinputWidget = new OO.ui.NumberInputWidget({\n\t\t\t\t// \t\tmin: 0,\n\t\t\t\t// \t\tmax: 1,\n\t\t\t\t// \t\tid: \"visualdata-jsmodule-formfield-default-value-input\",\n\t\t\t\t// \t});\n\t\t\t\t// }\n\n\t\t\t\tvar value = [];\n\t\t\t\tvar val = getPropertyValue( 'default' );\n\n\t\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\t\tvalue = val;\n\t\t\t\t} else if ( val !== '' ) {\n\t\t\t\t\tvalue = [ val ];\n\t\t\t\t}\n\n\t\t\t\tret = new OO.ui.TagMultiselectWidget( {\n\t\t\t\t\tvalue: value,\n\t\t\t\t\tselected: value,\n\t\t\t\t\tallowArbitrary: true,\n\t\t\t\t\tallowEditTags: true,\n\t\t\t\t\tallowReordering: true,\n\t\t\t\t\t// 0 means unlimited\n\t\t\t\t\t// tagLimit: !!multipleItemsInputValue ? 0 : 1,\n\t\t\t\t\tdraggable: true,\n\t\t\t\t\tinputPosition: 'outline',\n\t\t\t\t\tinputWidget: inputWidget,\n\t\t\t\t\tid: 'visualdata-jsmodule-formfield-default-value-input'\n\t\t\t\t} );\n\t\t\t}\n\t\t\t$( '#visualdata-jsmodule-formfield-default-value-input' ).replaceWith(\n\t\t\t\tret.$element\n\t\t\t);\n\n\t\t\treturn ret;\n\t\t}\n\n\t\tvar defaultValueInput = getDefaultValueInput();\n\n\t\tModel.default = defaultValueInput;\n\n\t\titems.push(\n\t\t\tnew OO.ui.FieldLayout( defaultValueInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-default' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-default-value-help' ),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t} )\n\t\t);\n\n\t\tvar publishFileInput = new OO.ui.DropdownInputWidget( {\n\t\t\toptions: VisualDataFunctions.createDropDownOptions( {\n\t\t\t\tpublish: mw.msg( 'visualdata-jsmodule-formfield-publishfile-publish' ),\n\t\t\t\tsaveonly: mw.msg( 'visualdata-jsmodule-formfield-publishfile-saveonly' )\n\t\t\t} ),\n\t\t\tvalue: ( !getPropertyValue( 'filepath' ) ? 'publish' : 'saveonly' )\n\t\t} );\n\n\t\tvar publishFileField = new OO.ui.FieldLayout( publishFileInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-publishfile' ),\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-publishfile-help' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( publishFileField );\n\n\t\tvar valueFormulaInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'value-formula' ),\n\t\t\tautosize: true,\n\t\t\trows: 1\n\t\t} );\n\n\t\tModel[ 'value-formula' ] = valueFormulaInput;\n\n\t\tvar valueFormulaField = new OO.ui.FieldLayout( valueFormulaInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-valueformula' ),\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-valueformula-help' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( valueFormulaField );\n\n\t\tvar filePathInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'filepath' )\n\t\t} );\n\n\t\tModel.filepath = filePathInput;\n\n\t\tvar filePathField = new OO.ui.FieldLayout( filePathInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-filepath' ),\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-filepath-help' ),\n\t\t\thelpInline: true,\n\t\t\talign: 'top'\n\t\t} );\n\n\t\titems.push( filePathField );\n\n\t\tfunction onSelectAvailableInputs() {\n\t\t\tvar thisAvailableInputsValue = availableInputsInput.getValue();\n\t\t\tvar thisDefaultValueInput = getDefaultValueInput();\n\n\t\t\tModel.default = defaultValueInput;\n\n\t\t\tif (\n\t\t\t\tthisAvailableInputsValue === 'OO.ui.SelectFileWidget' &&\n\t\t\t\t!( 'accept' in thisDefaultValueInput )\n\t\t\t) {\n\t\t\t\tthisDefaultValueInput.accept = Config.allowedMimeTypes;\n\t\t\t}\n\n\t\t\tpublishFileField.toggle( thisAvailableInputsValue === 'OO.ui.SelectFileWidget' );\n\t\t\tvalueFormulaField.toggle( thisAvailableInputsValue !== 'OO.ui.SelectFileWidget' || publishFileInput.getValue() === 'publish' );\n\t\t\tfilePathField.toggle( thisAvailableInputsValue === 'OO.ui.SelectFileWidget' && publishFileInput.getValue() === 'saveonly' );\n\t\t}\n\n\t\tpublishFileInput.on( 'change', function () {\n\t\t\tonSelectAvailableInputs();\n\t\t} );\n\n\t\tavailableInputsInput.on( 'change', function () {\n\t\t\tonSelectAvailableInputs();\n\t\t} );\n\n\t\tonSelectAvailableInputs();\n\n\t\tfunction onToggleHiddenInput( hidden ) {\n\t\t\tif ( hidden ) {\n\t\t\t\tModel[ 'preferred-input' ].setValue( 'OO.ui.TextInputWidget' );\n\t\t\t}\n\t\t\tavailableInputsInput.setDisabled( hidden );\n\t\t\trequiredInput.setDisabled( hidden );\n\t\t\tlayoutParentSchema.toggle( ( getPropertyValue( 'multiple-items' ) || parentSchema.type === 'array' ) );\n\t\t\tnameInput.setDisabled( layoutParentSchema.isVisible() );\n\t\t\tlabelField.toggle( !hidden );\n\t\t\thelpMessageField.toggle( !hidden );\n\t\t}\n\n\t\tonVisibilityInputChange( visibilityInputValue );\n\n\t\tfunction redrawAvailableInputs() {\n\t\t\tavailableInputsInput.setOptions(\n\t\t\t\tVisualDataFunctions.createDropDownOptions(\n\t\t\t\t\tgetAvailableInputs(\n\t\t\t\t\t\tgetPropertyValue( 'propertyModel' ) || 'json-schema',\n\t\t\t\t\t\tgetPropertyValue( 'jsonSchema-type' ),\n\t\t\t\t\t\tgetPropertyValue( 'jsonSchema-format' ),\n\t\t\t\t\t\tgetPropertyValue( 'multiple-items' )\n\t\t\t\t\t),\n\t\t\t\t\t{\n\t\t\t\t\t\tkey: 'value'\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t);\n\n\t\t\tvar thisDefaultValueInput = getDefaultValueInput();\n\t\t\tModel.default = thisDefaultValueInput;\n\t\t}\n\n\t\titems = items.filter( function ( x ) {\n\t\t\treturn !( 'items' in x ) || x.items.length;\n\t\t} );\n\n\t\tthis.isEmpty = !items.length;\n\n\t\tthis.fieldset.addItems( items );\n\n\t\tsetTimeout( function () {\n\t\t\tVisualDataFunctions.removeNbspFromLayoutHeader(\n\t\t\t\t'#visualdata-processDialogEditField'\n\t\t\t);\n\t\t}, 30 );\n\t};\n\n\t// eslint-disable-next-line no-unused-vars\n\tPanelLayout.prototype.addItem = function ( property ) {\n\t\tthis.populateFieldset();\n\t};\n\n\tfunction ProcessDialog( config ) {\n\t\tProcessDialog.super.call( this, config );\n\t}\n\tOO.inheritClass( ProcessDialog, OO.ui.ProcessDialog );\n\n\tProcessDialog.static.name = 'myDialog';\n\t// ProcessDialog.static.title = mw.msg(\n\t// \"visualdata-jsmodule-manageproperties-define-property\"\n\t// );\n\tProcessDialog.static.actions = [\n\t\t{\n\t\t\taction: 'save',\n\t\t\tmodes: 'edit',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-save' ),\n\t\t\tflags: [ 'primary', 'progressive' ]\n\t\t},\n\t\t{\n\t\t\tmodes: 'edit',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-cancel' ),\n\t\t\tflags: [ 'safe', 'close' ]\n\t\t}\n\t];\n\n\tProcessDialog.prototype.initialize = function () {\n\t\tProcessDialog.super.prototype.initialize.apply( this, arguments );\n\n\t\tpanelLayout = new PanelLayout( {\n\t\t\texpanded: false,\n\t\t\tpadded: true,\n\t\t\tclasses: [],\n\t\t\tdata: {}\n\t\t} );\n\n\t\tvar frameA = new OO.ui.PanelLayout( {\n\t\t\t$content: [ panelLayout.$element ],\n\t\t\texpanded: false,\n\t\t\t// framed: false,\n\t\t\tpadded: false,\n\t\t\tdata: { name: 'manageforms' }\n\t\t} );\n\n\t\tthis.$body.append( frameA.$element );\n\t};\n\n\tProcessDialog.prototype.getActionProcess = function ( action ) {\n\t\tvar dialog = this;\n\n\t\tvar currentItem = getCurrentItem() || {\n\t\t\ttype: '',\n\t\t\twiki: { type: 'property' }\n\t\t};\n\t\tvar parentSchema = currentItem;\n\t\tif (\n\t\t\tcurrentItem.type === 'array' &&\n\t\t\tVisualDataFunctions.isObject( currentItem.items )\n\t\t) {\n\t\t\tcurrentItem = currentItem.items;\n\t\t}\n\n\t\tfunction getValueRec( model, thisObj ) {\n\t\t\tfor ( var i in model ) {\n\t\t\t\tif ( !( 'getValue' in model[ i ] ) ) {\n\t\t\t\t\tgetValueRec( model[ i ], ( thisObj[ i ] = {} ) );\n\t\t\t\t} else {\n\t\t\t\t\tthisObj[ i ] = VisualDataSchemas.getWidgetValue( model[ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch ( action ) {\n\t\t\tcase 'save':\n\t\t\t\tvar obj = { type: 'property' };\n\t\t\t\tgetValueRec( Model, obj );\n\n\t\t\t\tvar objName = obj[ 'multiple-items' ] ? obj.parentSchema.name : obj.name;\n\n\t\t\t\t// remove unsupported value\n\t\t\t\tif ( 'SMW-property' in obj ) {\n\t\t\t\t\tdelete obj[ 'SMW-property' ];\n\t\t\t\t}\n\n\t\t\t\tvar alert = null;\n\t\t\t\tif ( objName === '' ) {\n\t\t\t\t\talert = mw.msg( 'visualdata-jsmodule-schemas-alert-noname' );\n\t\t\t\t} else if ( objName !== CurrentKey && objName in ParentObj ) {\n\t\t\t\t\talert = mw.msg( 'visualdata-jsmodule-schemas-alert-existing-item' );\n\t\t\t\t}\n\n\t\t\t\tif ( alert ) {\n\t\t\t\t\tVisualDataFunctions.OOUIAlert( new OO.ui.HtmlSnippet( alert ), {\n\t\t\t\t\t\tsize: 'medium'\n\t\t\t\t\t} );\n\t\t\t\t\treturn ProcessDialog.super.prototype.getActionProcess.call(\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\taction\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tVisualDataFunctions.renameObjectKey( ParentObj, CurrentKey, objName );\n\n\t\t\t\tParentObj[ objName ] = VisualDataSchemas.handleSaveArray(\n\t\t\t\t\tparentSchema,\n\t\t\t\t\tobj\n\t\t\t\t);\n\n\t\t\t\tCallback();\n\n\t\t\t\treturn new OO.ui.Process( function () {\n\t\t\t\t\tdialog.close( { action: action } );\n\t\t\t\t} );\n\t\t}\n\n\t\treturn ProcessDialog.super.prototype.getActionProcess.call( this, action );\n\t};\n\n\tProcessDialog.prototype.getTeardownProcess = function ( data ) {\n\t\treturn ProcessDialog.super.prototype.getTeardownProcess\n\t\t\t.call( this, data )\n\t\t\t.first( function () {\n\t\t\t\tWindowManager.removeActiveWindow();\n\t\t\t}, this );\n\t};\n\n\t/**\n\t * Override getBodyHeight to create a tall dialog relative to the screen.\n\t *\n\t * @return {number} Body height\n\t */\n\tProcessDialog.prototype.getBodyHeight = function () {\n\t\t// see here https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n\t\t// this.page1.content.$element.outerHeight( true );\n\t\treturn window.innerHeight - 100;\n\t};\n\n\tfunction openDialog( callback, parentObj, fieldName ) {\n\t\tCallback = callback;\n\t\tModel = {};\n\n\t\t// *** place here properties to copy\n\t\t// @FIXME with arrays this is mistakenly copying to\n\t\t// the child, not the parent schema\n\t\tif ( fieldName in parentObj && 'uuid' in parentObj[ fieldName ].wiki ) {\n\t\t\tModel.uuid = new VisualDataFunctions.MockupOOUIClass(\n\t\t\t\tparentObj[ fieldName ].wiki.uuid );\n\t\t}\n\n\t\tParentObj = parentObj;\n\n\t\tCurrentKey =\n\t\t\tfieldName ||\n\t\t\tVisualDataFunctions.createNewKey(\n\t\t\t\tparentObj,\n\t\t\t\tmw.msg( 'visualdata-jsmodule-formfield-newlabel' )\n\t\t\t);\n\n\t\tvar processDialog = new ProcessDialog( {\n\t\t\tsize: 'large',\n\t\t\tclasses: [],\n\t\t\tid: 'visualdata-processDialogEditField'\n\t\t} );\n\n\t\tWindowManager.newWindow( processDialog, {\n\t\t\ttitle:\n\t\t\t\tmw.msg(\n\t\t\t\t\t// The following messages are used here:\n\t\t\t\t\t// * visualdata-jsmodule-manageproperties-define-property\n\t\t\t\t\t// * visualdata-jsmodule-manageproperties-define-property - [name]\n\t\t\t\t\t'visualdata-jsmodule-formfield-definefield'\n\t\t\t\t) + ( fieldName ? ' - ' + fieldName : '' )\n\t\t} );\n\t}\n\n\treturn {\n\t\topenDialog\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":"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/VisualDataForms.js","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 101. Maximum allowed is 100.","line":26,"column":1,"nodeType":"Program","messageId":"max","endLine":26,"endColumn":102},{"ruleId":"no-jquery/no-sizzle","severity":1,"message":"Selector extensions are not allowed","line":79,"column":6,"nodeType":"CallExpression","endLine":79,"endColumn":58},{"ruleId":"no-jquery/no-sizzle","severity":1,"message":"Selector extensions are not allowed","line":213,"column":5,"nodeType":"CallExpression","endLine":213,"endColumn":29},{"ruleId":"max-len","severity":1,"message":"This line has a length of 117. Maximum allowed is 100.","line":513,"column":1,"nodeType":"Program","messageId":"max","endLine":513,"endColumn":88},{"ruleId":"max-len","severity":1,"message":"This line has a length of 125. Maximum allowed is 100.","line":530,"column":1,"nodeType":"Program","messageId":"max","endLine":530,"endColumn":96},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":577,"column":5,"nodeType":"CallExpression","endLine":591,"endColumn":9},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":577,"column":5,"nodeType":"CallExpression","endLine":596,"endColumn":9},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":878,"column":5,"nodeType":"CallExpression","endLine":895,"endColumn":8},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":878,"column":5,"nodeType":"CallExpression","endLine":896,"endColumn":8},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":969,"column":5,"nodeType":"CallExpression","endLine":969,"endColumn":41},{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":1007,"column":8,"nodeType":"VariableDeclarator","endLine":1007,"endColumn":72},{"ruleId":"no-jquery/no-parse-html-literal","severity":1,"message":"Prefer DOM building to parsing HTML literals","line":1007,"column":17,"nodeType":"CallExpression","endLine":1007,"endColumn":72},{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":1456,"column":4,"nodeType":"AssignmentExpression","endLine":1456,"endColumn":38},{"ruleId":"no-jquery/no-parse-html-literal","severity":1,"message":"Prefer DOM building to parsing HTML literals","line":1458,"column":26,"nodeType":"CallExpression","endLine":1458,"endColumn":78},{"ruleId":"no-jquery/no-parse-html-literal","severity":1,"message":"Prefer DOM building to parsing HTML literals","line":2185,"column":5,"nodeType":"CallExpression","endLine":2185,"endColumn":42},{"ruleId":"max-len","severity":1,"message":"This line has a length of 117. Maximum allowed is 100.","line":2333,"column":1,"nodeType":"Program","messageId":"max","endLine":2333,"endColumn":109},{"ruleId":"max-len","severity":1,"message":"This line has a length of 127. Maximum allowed is 100.","line":2370,"column":1,"nodeType":"Program","messageId":"max","endLine":2370,"endColumn":116},{"ruleId":"max-len","severity":1,"message":"This line has a length of 109. Maximum allowed is 100.","line":2582,"column":1,"nodeType":"Program","messageId":"max","endLine":2582,"endColumn":92},{"ruleId":"max-len","severity":1,"message":"This line has a length of 102. Maximum allowed is 100.","line":2916,"column":1,"nodeType":"Program","messageId":"max","endLine":2916,"endColumn":85},{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":2934,"column":7,"nodeType":"VariableDeclarator","endLine":2934,"endColumn":25},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":3102,"column":9,"nodeType":"CallExpression","endLine":3126,"endColumn":13},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":3102,"column":9,"nodeType":"CallExpression","endLine":3131,"endColumn":13},{"ruleId":"max-len","severity":1,"message":"This line has a length of 102. Maximum allowed is 100.","line":3107,"column":1,"nodeType":"Program","messageId":"max","endLine":3107,"endColumn":70},{"ruleId":"no-jquery/no-sizzle","severity":1,"message":"Selector extensions are not allowed","line":3231,"column":10,"nodeType":"CallExpression","endLine":3231,"endColumn":34},{"ruleId":"max-len","severity":1,"message":"This line has a length of 108. Maximum allowed is 100.","line":3381,"column":1,"nodeType":"Program","messageId":"max","endLine":3381,"endColumn":94},{"ruleId":"max-len","severity":1,"message":"This line has a length of 105. Maximum allowed is 100.","line":3386,"column":1,"nodeType":"Program","messageId":"max","endLine":3386,"endColumn":91},{"ruleId":"no-jquery/no-parse-html-literal","severity":1,"message":"Prefer DOM building to parsing HTML literals","line":3601,"column":15,"nodeType":"CallExpression","endLine":3603,"endColumn":6},{"ruleId":"max-len","severity":1,"message":"This line has a length of 119. Maximum allowed is 100.","line":3625,"column":1,"nodeType":"Program","messageId":"max","endLine":3625,"endColumn":108},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":3672,"column":3,"nodeType":"CallExpression","endLine":3672,"endColumn":39},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":3716,"column":3,"nodeType":"CallExpression","endLine":3716,"endColumn":29}],"suppressedMessages":[{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'constructorName_'.","line":71,"column":8,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":72,"endColumn":39,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":99,"column":41,"nodeType":"Identifier","messageId":"unusedVar","endLine":99,"endColumn":47,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'resolve' is defined but never used.","line":103,"column":43,"nodeType":"Identifier","messageId":"unusedVar","endLine":103,"endColumn":50,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":103,"column":52,"nodeType":"Identifier","messageId":"unusedVar","endLine":103,"endColumn":58,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":118,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":118,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'res' is defined but never used.","line":132,"column":64,"nodeType":"Identifier","messageId":"unusedVar","endLine":132,"endColumn":67,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":136,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":136,"endColumn":19,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[4111,4132],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'item' is defined but never used.","line":142,"column":33,"nodeType":"Identifier","messageId":"unusedVar","endLine":142,"endColumn":37,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'items' is defined but never used.","line":144,"column":36,"nodeType":"Identifier","messageId":"unusedVar","endLine":144,"endColumn":41,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":215,"column":39,"nodeType":"Identifier","messageId":"unusedVar","endLine":215,"endColumn":45,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'resolve' is defined but never used.","line":221,"column":41,"nodeType":"Identifier","messageId":"unusedVar","endLine":221,"endColumn":48,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":221,"column":50,"nodeType":"Identifier","messageId":"unusedVar","endLine":221,"endColumn":56,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'schema' is defined but never used.","line":345,"column":26,"nodeType":"Identifier","messageId":"unusedVar","endLine":345,"endColumn":32,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'schema' is defined but never used.","line":351,"column":26,"nodeType":"Identifier","messageId":"unusedVar","endLine":351,"endColumn":32,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'callback' is defined but never used.","line":355,"column":54,"nodeType":"Identifier","messageId":"unusedVar","endLine":355,"endColumn":62,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":423,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":423,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'model_'.","line":426,"column":10,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":426,"endColumn":42,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'field_'.","line":432,"column":10,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":432,"endColumn":37,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":451,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":451,"endColumn":18,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[12138,12159],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":587,"column":9,"nodeType":"MemberExpression","messageId":"unexpected","endLine":587,"endColumn":22,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[16334,16393],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":594,"column":7,"nodeType":"MemberExpression","messageId":"unexpected","endLine":594,"endColumn":20,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[16540,16592],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'match_'.","line":641,"column":10,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":641,"endColumn":48,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'match_'.","line":658,"column":10,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":658,"endColumn":53,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'estimatedRemainingTime' is defined but never used.","line":743,"column":40,"nodeType":"Identifier","messageId":"unusedVar","endLine":743,"endColumn":62,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'res' is defined but never used.","line":761,"column":26,"nodeType":"Identifier","messageId":"unusedVar","endLine":761,"endColumn":29,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-inner-declarations","severity":2,"message":"Move function declaration to function body root.","line":862,"column":4,"nodeType":"FunctionDeclaration","messageId":"moveDeclToRoot","endLine":906,"endColumn":5,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":943,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":943,"endColumn":16,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[25832,25874],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":948,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":948,"endColumn":16,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[25981,26025],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1196,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1196,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1197,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1197,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'loadDataBeforeSelect' is assigned a value but never used.","line":1203,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":1203,"endColumn":27,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":1226,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":1226,"endColumn":19,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[33866,33907],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/msg-doc","severity":2,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":1232,"column":60,"nodeType":"CallExpression","endLine":1232,"endColumn":75,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1293,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1293,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1294,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1294,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'res' is defined but never used.","line":1325,"column":14,"nodeType":"Identifier","messageId":"unusedVar","endLine":1325,"endColumn":17,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":1337,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":1337,"endColumn":19,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[36665,36706],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/msg-doc","severity":2,"message":"All possible message keys should be documented. See https://w.wiki/4r9a for details.","line":1343,"column":60,"nodeType":"CallExpression","endLine":1343,"endColumn":75,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1362,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1362,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1366,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1366,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1367,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1367,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1368,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1368,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1369,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1369,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1370,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1370,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1371,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1371,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1371,"column":11,"nodeType":"Program","messageId":"unexpectedTab","endLine":1371,"endColumn":12,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1372,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1372,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1391,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":1391,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1392,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":1392,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1393,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":1393,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"wrap-iife","severity":2,"message":"Move the invocation into the parens that contain the function.","line":1418,"column":20,"nodeType":"CallExpression","messageId":"moveInvocation","endLine":1438,"endColumn":8,"fix":{"range":[39189,39192],"text":"())"},"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":2,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":1447,"column":39,"nodeType":"ObjectExpression","endLine":1453,"endColumn":4,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1591,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":1591,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1592,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":1592,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1593,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":1593,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1594,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":1594,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'directive' is defined but never used.","line":1652,"column":66,"nodeType":"Identifier","messageId":"unusedVar","endLine":1652,"endColumn":75,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1663,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":1663,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'schemaName_'.","line":1701,"column":14,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":1701,"endColumn":25,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'schemaName_'.","line":1702,"column":5,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":1702,"endColumn":33,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'schemaName_'.","line":1703,"column":18,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":1703,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'schemaName_'.","line":1707,"column":7,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":1707,"endColumn":37,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'schemaName_'.","line":1711,"column":6,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":1711,"endColumn":42,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'schemaName_'.","line":1716,"column":19,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":1716,"endColumn":46,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'schemaName_'.","line":1732,"column":6,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":1732,"endColumn":42,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'schemaName_'.","line":1738,"column":5,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":1738,"endColumn":23,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":1782,"column":7,"nodeType":"MemberExpression","messageId":"unexpected","endLine":1782,"endColumn":20,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[47799,47864],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1865,"column":10,"nodeType":"Program","messageId":"unexpectedTab","endLine":1865,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1898,"column":10,"nodeType":"Program","messageId":"unexpectedTab","endLine":1898,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'inputName' is assigned a value but never used.","line":1927,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":1927,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2164,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":2164,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2165,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":2165,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2166,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":2166,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'widget_'.","line":2279,"column":8,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":2279,"endColumn":70,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":2326,"column":8,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":2326,"endColumn":34,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'widget_'.","line":2333,"column":8,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":2333,"endColumn":108,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'thisPath_'.","line":2372,"column":9,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":2372,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'_' is defined but never used.","line":2403,"column":25,"nodeType":"Identifier","messageId":"unusedVar","endLine":2403,"endColumn":26,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":2440,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":2440,"endColumn":17,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[65277,65298],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2458,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2458,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2459,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2459,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2460,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2460,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2461,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2461,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2462,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2462,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2463,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2463,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2464,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2464,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2465,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2465,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'items_'.","line":2562,"column":10,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":2562,"endColumn":21,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":2567,"column":11,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":2567,"endColumn":58,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'pathNoIndex_'.","line":2569,"column":11,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":2571,"endColumn":30,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'widget_'.","line":2582,"column":11,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":2582,"endColumn":91,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2681,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2681,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2682,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2682,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2683,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2683,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2684,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2684,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2685,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2685,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2686,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2686,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2687,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2687,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2688,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2688,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2689,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2689,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2690,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2690,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2691,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2691,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2692,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2692,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2693,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2693,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2694,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2694,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2789,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2789,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2790,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":2790,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2897,"column":21,"nodeType":"Program","messageId":"unexpectedTab","endLine":2897,"endColumn":22,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2904,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":2904,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2905,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":2905,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2906,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":2906,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2907,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":2907,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-alert","severity":2,"message":"Unexpected alert.","line":2950,"column":5,"nodeType":"CallExpression","messageId":"unexpected","endLine":2950,"endColumn":69,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":2978,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":2978,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-alert","severity":2,"message":"Unexpected confirm.","line":3050,"column":6,"nodeType":"CallExpression","messageId":"unexpected","endLine":3052,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":3129,"column":11,"nodeType":"MemberExpression","messageId":"unexpected","endLine":3129,"endColumn":24,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[83740,83791],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3141,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3141,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'thisObserver' is defined but never used.","line":3257,"column":63,"nodeType":"Identifier","messageId":"unusedVar","endLine":3257,"endColumn":75,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'matchedClasses' is defined but never used.","line":3278,"column":49,"nodeType":"Identifier","messageId":"unusedVar","endLine":3278,"endColumn":63,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3283,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3283,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3285,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3285,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'res' is defined but never used.","line":3305,"column":62,"nodeType":"Identifier","messageId":"unusedVar","endLine":3305,"endColumn":65,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":3309,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":3309,"endColumn":15,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[88693,88712],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":2,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":3351,"column":45,"nodeType":"ObjectExpression","endLine":3358,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3382,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":3382,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3383,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":3383,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3384,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":3384,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3385,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":3385,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3386,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":3386,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":2,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":3413,"column":44,"nodeType":"ObjectExpression","endLine":3420,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3495,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3495,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3496,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3496,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3497,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3497,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3498,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3498,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"mediawiki/class-doc","severity":2,"message":"All possible CSS classes should be documented. See https://w.wiki/PS2 for details.","line":3536,"column":36,"nodeType":"ObjectExpression","endLine":3543,"endColumn":4,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3546,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3546,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3547,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3547,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3548,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3548,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3549,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3549,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3550,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3550,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3551,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3551,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3552,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3552,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3553,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3553,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3554,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3554,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3557,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3557,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3558,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3558,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3559,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3559,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3560,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3560,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3561,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3561,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3562,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3562,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3563,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3563,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3564,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3564,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":3576,"column":4,"nodeType":"CallExpression","endLine":3576,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3622,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3622,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3623,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3623,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3624,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3624,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3625,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3625,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3626,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3626,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3627,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3627,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3628,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3628,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3629,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3629,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3631,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3631,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3632,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3632,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3633,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3633,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3634,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3634,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3635,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3635,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3636,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3636,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3638,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3638,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3656,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3656,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3657,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3657,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":3669,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":3669,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'mutations' is defined but never used.","line":3797,"column":52,"nodeType":"Identifier","messageId":"unusedVar","endLine":3797,"endColumn":61,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'thisObserver' is defined but never used.","line":3797,"column":63,"nodeType":"Identifier","messageId":"unusedVar","endLine":3797,"endColumn":75,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":7,"fatalErrorCount":0,"warningCount":23,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2021-2025, https://wikisphere.org\n */\n\n/* eslint-disable no-tabs */\n/* eslint-disable no-unused-vars */\n/* eslint-disable no-underscore-dangle */\n\nconst VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowManager, initForms ) {\n\tvar Model = {};\n\tvar ModelSchemas;\n\tvar OuterStack;\n\tvar PropertiesStack;\n\tvar processDialogSearch;\n\tvar DialogSearchName = 'dialogSearch';\n\tvar ToolbarMain;\n\tvar ActionToolbarMain;\n\tvar ActionWidget;\n\tvar SubmitButton;\n\tvar ValidateButton;\n\tvar GoBackButton;\n\t// var DeleteButton;\n\t// shallow copy\n\tvar InitialSchemas = Form.schemas.slice();\n\tvar Fields;\n\tvar DialogName = 'dialogForm';\n\tvar StoredJsonData = VisualDataFunctions.deepCopy( Form.jsonData );\n\tvar ModelFlatten = [];\n\tvar SelectedSchema;\n\tvar PreviousSchemas = {};\n\tvar ProcessModel = {};\n\tvar InputWidgets;\n\tvar SchemasLayout;\n\tvar Initialized = false;\n\tvar PendingRecursive;\n\tvar QueuedWidgets;\n\tvar Maps = [];\n\tvar TargetSlotField;\n\tvar MutationObservers = {};\n\tvar FormID;\n\n\tfunction inArray( val, arr ) {\n\t\treturn arr.includes( val );\n\t}\n\n\tfunction escapeJsonPointer( str ) {\n\t\treturn VisualDataFunctions.escapeJsonPointer( str );\n\t}\n\n\tfunction showLazyWidget( constructorName ) {\n\t\tvar promises = [];\n\t\t// @IMPORTANT use \"let\" if used with timeout !!\n\t\tfor ( let i in InputWidgets ) {\n\t\t\tvar constructorName_ = InputWidgets[ i ].constructorName ||\n\t\t\t\tInputWidgets[ i ].constructor.name;\n\n\t\t\tif ( constructorName_ === constructorName ||\n\t\t\t\t( 'constructorName' in InputWidgets[ i ] &&\n\t\t\t\t\tInputWidgets[ i ].constructorName === constructorName )\n\t\t\t) {\n\t\t\t\tif (\n\t\t\t\t\tInputWidgets[ i ].$element.parent().is( ':visible' )\n\t\t\t\t) {\n\t\t\t\t\tpromises.push( InputWidgets[ i ].initialize() );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn promises;\n\t}\n\n\tasync function loadMaps() {\n\t\tfunction initMap( obj ) {\n\t\t\tif ( obj.data.schema.wiki.coordinates === false ) {\n\t\t\t\tvar latFieldId = makeElementId( `${ obj.data.path }/latitude` );\n\t\t\t\tvar lonFieldId = makeElementId( `${ obj.data.path }/longitude` );\n\t\t\t\tvar escapeSelector = jQuery.escapeSelector;\n\n\t\t\t\tfor ( let fieldId of [ latFieldId, lonFieldId ] ) {\n\t\t\t\t\tlet callbackCond = function () {\n\t\t\t\t\t\treturn $( '#' + escapeSelector( fieldId ) ).length;\n\t\t\t\t\t};\n\t\t\t\t\tlet callback = function ( resolve, reject ) {\n\t\t\t\t\t\t$( '#' + escapeSelector( fieldId ) ).hide();\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t};\n\t\t\t\t\tlet callbackMaxAttempts = function ( resolve, reject ) {\n\t\t\t\t\t\t$( '#' + escapeSelector( fieldId ) ).hide();\n\t\t\t\t\t};\n\t\t\t\t\tVisualDataFunctions.waitUntil(\n\t\t\t\t\t\tcallbackCond,\n\t\t\t\t\t\tcallback,\n\t\t\t\t\t\tcallbackMaxAttempts,\n\t\t\t\t\t\t5\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ( new VisualDataMaptiler() )\n\t\t\t\t.initialize( obj.element, obj.data );\n\t\t}\n\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tmw.loader.using( 'ext.VisualData.Maptiler', function () {\n\t\t\t\tvar promises = [];\n\t\t\t\t// @IMPORTANT use \"let\" if used with timeout !!\n\t\t\t\tfor ( let obj of Maps ) {\n\t\t\t\t\t// @FIXME find a better way\n\t\t\t\t\tvar schemaName = obj.data.path.split( '/' )[ 0 ];\n\t\t\t\t\t// *** load only if the form/tab is visible\n\t\t\t\t\t// to prevent inconsistencies of display\n\t\t\t\t\tif ( schemaName === SelectedSchema ) {\n\t\t\t\t\t\tpromises.push( initMap( obj ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tVisualDataFunctions.promisesAllSettled( promises ).then( ( res ) => {\n\t\t\t\t\tresolve();\n\t\t\t\t} ).catch( ( err ) => {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.error( err );\n\t\t\t\t} );\n\t\t\t} );\n\t\t} );\n\t}\n\n\tfunction onSetPropertiesStack( item ) {}\n\n\tfunction onChangePropertiesStack( items ) {}\n\n\tfunction onTabSelect( selectedSchema ) {\n\t\tSelectedSchema = selectedSchema;\n\t\tsetTimeout( function () {\n\t\t\tonMutationChange( selectedSchema );\n\t\t}, 30 );\n\t}\n\n\tfunction makeElementId( path ) {\n\t\treturn `VisualDataGroupWidgetPanel-${ FormID }-${ path }`.replace(\n\t\t\t/ /g,\n\t\t\t'_'\n\t\t);\n\t}\n\n\tfunction callbackShowError( schemaName, errorMessage, errors, hiddenErrors ) {\n\n\t\t// remove previous error messages\n\t\tfor ( var i in Fields ) {\n\t\t\tif ( Fields[ i ].constructor.name === 'OoUiMessageWidget' ) {\n\t\t\t\tFields[ i ].toggle( false );\n\t\t\t} else {\n\t\t\t\tFields[ i ].setErrors( [] );\n\t\t\t}\n\t\t}\n\n\t\tif ( !schemaName ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar escapedSchemaName = escapeJsonPointer( schemaName );\n\n\t\tFields[ escapedSchemaName ].toggle( true );\n\t\tFields[ escapedSchemaName ].setType( 'error' );\n\n\t\tvar errorMessage = mw.msg( 'visualdata-jsmodule-forms-form-error' );\n\t\tif ( hiddenErrors && Object.keys( hiddenErrors ).length ) {\n\t\t\tfor ( var path in hiddenErrors ) {\n\t\t\t\terrorMessage += '<br />' + hiddenErrors[ path ];\n\t\t\t}\n\t\t}\n\n\t\tFields[ escapedSchemaName ].setLabel(\n\t\t\tnew OO.ui.HtmlSnippet( errorMessage )\n\t\t);\n\n\t\tfor ( var path in errors ) {\n\t\t\tif ( !( path in Fields ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( Fields[ path ].constructor.name === 'OoUiMessageWidget' ) {\n\t\t\t\tFields[ path ].setType( 'error' );\n\t\t\t\tFields[ path ].setLabel( errors[ path ] );\n\n\t\t\t\tFields[ path ].toggle( true );\n\t\t\t} else {\n\t\t\t\tFields[ path ].setErrors( [ errors[ path ] ] );\n\t\t\t}\n\t\t}\n\n\t\tselectSchema( schemaName );\n\n\t\tvar el = window.document.querySelector( '#' +\n\t\t\tjQuery.escapeSelector( makeElementId( escapedSchemaName ) ) );\n\n\t\tif ( el ) {\n\t\t\tlet callbackCond = function () {\n\t\t\t\t$( el ).is( ':visible' );\n\t\t\t};\n\t\t\tlet callback = function ( resolve, reject ) {\n\t\t\t\tel.scrollIntoView( {\n\t\t\t\t\tbehavior: 'smooth'\n\t\t\t\t} );\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tlet callbackMaxAttempts = function ( resolve, reject ) {\n\t\t\t\tel.scrollIntoView( {\n\t\t\t\t\tbehavior: 'smooth'\n\t\t\t\t} );\n\t\t\t};\n\n\t\t\tVisualDataFunctions.waitUntil(\n\t\t\t\tcallbackCond,\n\t\t\t\tcallback,\n\t\t\t\tcallbackMaxAttempts,\n\t\t\t\t5\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction selectSchema( schemaName, init ) {\n\t\tif ( !schemaName ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar escapedSchemaName = escapeJsonPointer( schemaName );\n\n\t\tvar el = window.document.querySelector( '#' +\n\t\t\tjQuery.escapeSelector( makeElementId( escapedSchemaName ) ) );\n\n\t\tif ( !el ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// indexLayout\n\t\tif ( 'setTabPanel' in SchemasLayout ) {\n\t\t\tSchemasLayout.setTabPanel( schemaName );\n\n\t\t\tif ( init ) {\n\t\t\t\tSchemasLayout.on( 'set', function () {\n\t\t\t\t\tonTabSelect( SchemasLayout.getCurrentTabPanelName() );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t// booklet\n\t\t} else if ( 'setPage' in SchemasLayout ) {\n\t\t\tSchemasLayout.setPage( schemaName );\n\n\t\t\tif ( init ) {\n\t\t\t\tSchemasLayout.on( 'set', function () {\n\t\t\t\t\tonTabSelect( SchemasLayout.getCurrentPageName() );\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction getInputWidget( config ) {\n\t\tvar field = config.model.schema.wiki;\n\n\t\tif ( !( 'input-config' in field ) ) {\n\t\t\tfield[ 'input-config' ] = {};\n\t\t}\n\t\tvar required = 'required' in field && field.required;\n\n\t\t// create deep copy, otherwise changes are\n\t\t// copied to Forms[ form ].properties[ property ][ 'input-config' ]\n\t\tvar inputConfig = $.extend(\n\t\t\t{}, // *** important !! cast to object\n\t\t\tVisualDataFunctions.deepCopy( field[ 'input-config' ] ),\n\t\t\t{ value: config.data, required: required }\n\t\t);\n\n\t\tif ( 'options-values-parsed' in field ) {\n\t\t\tinputConfig.options = field[ 'options-values-parsed' ];\n\t\t}\n\n\t\tvar inputName =\n\t\t\t!( 'visibility' in field ) || field.visibility !== 'hidden' ?\n\t\t\t\tVisualDataFunctions.inputNameFromLabel(\n\t\t\t\t\tVisualDataFunctions.getPreferredInput( config.model.schema )\n\t\t\t\t) :\n\t\t\t\t'OO.ui.HiddenInputWidget';\n\n\t\t// FIXME with HiddenInputWidget, value is null (as string)\n\t\tconfig.model.inputName = inputName;\n\n\t\tif ( !( 'name' in config ) || config.name.trim() === '' ) {\n\t\t\tinputConfig.name = `${ FormID }-${ config.model.path }`;\n\t\t} else {\n\t\t\tinputConfig.name = config.name;\n\t\t}\n\n\t\tif ( Array.isArray( inputConfig.value ) ) {\n\t\t\tfor ( var i in inputConfig.value ) {\n\t\t\t\tif ( inputConfig.value[ i ].trim() === '' ) {\n\t\t\t\t\tdelete inputConfig.value[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// @see https://www.semantic-mediawiki.org/wiki/Help:Special_property_Allows_value\n\t\t// SemanticMediaWiki/src/DataValues/ValueValidator/AllowsListConstraintValueValidator.php\n\t\tif ( inArray( inputName, VisualDataFunctions.optionsInputs ) ) {\n\t\t\tif ( inputConfig.options && Object.keys( inputConfig.options ).length ) {\n\t\t\t\tinputConfig.options = VisualDataFunctions.createDropDownOptions(\n\t\t\t\t\tinputConfig.options\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tinputConfig.options = [];\n\t\t\t}\n\t\t}\n\t\tinputConfig.data = {\n\t\t\t// path: config.model.path,\n\t\t\t// schema: config.model.schema,\n\t\t\tmodel: config.model,\n\t\t\tperformQuery\n\t\t};\n\t\treturn ( InputWidgets[ inputConfig.name ] =\n\t\t\tVisualDataFunctions.inputInstanceFromName( inputName, inputConfig ) );\n\t}\n\n\tfunction isNewSchema( schemaName ) {\n\t\treturn !inArray( schemaName, InitialSchemas );\n\t}\n\n\tfunction getCategories() {\n\t\treturn Form.categories;\n\t}\n\n\tfunction getFieldAlign( schema ) {\n\t\treturn 'layout-align' in Form.options ?\n\t\t\tForm.options[ 'layout-align' ] :\n\t\t\t'top';\n\t}\n\n\tfunction getHelpInline( schema ) {\n\t\treturn !( 'popup-help' in Form.options ? Form.options[ 'popup-help' ] : false );\n\t}\n\n\tasync function updateFieldsVisibility( sourceModel, callback ) {\n\t\tvar field = sourceModel.schema.wiki;\n\n\t\tfunction escapeRegExp( string ) {\n\t\t\treturn string.replace( /[.*+?^${}()|[\\]\\\\]/g, '\\\\$&' );\n\t\t}\n\n\t\tfunction toggleVisibility( value, thisModel, thisField ) {\n\t\t\tvar refValue = VisualDataFunctions.castType(\n\t\t\t\t( !thisField[ 'showif-value-wikitext' ] ? thisField[ 'showif-value' ] : thisField[ 'showif-value-parsed' ] ),\n\t\t\t\tsourceModel.schema.type\n\t\t\t);\n\n\t\t\tvar res;\n\t\t\tif ( sourceModel.removed ) {\n\t\t\t\tres = false;\n\n\t\t\t} else {\n\t\t\t\tswitch ( thisField[ 'showif-condition' ] ) {\n\t\t\t\t\tcase '=':\n\t\t\t\t\t\tres = ( refValue === value );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '!=':\n\t\t\t\t\t\tres = ( refValue !== value );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'starts':\n\t\t\t\t\t\tres = ( value.indexOf( refValue ) === 0 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '!starts':\n\t\t\t\t\t\tres = ( value.indexOf( refValue ) !== 0 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'contains':\n\t\t\t\t\t\tres = ( value.includes( refValue ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '!contains':\n\t\t\t\t\t\tres = ( !value.includes( refValue ) );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'ends':\n\t\t\t\t\t\tvar regExp = new RegExp( escapeRegExp( refValue ) + '$' );\n\t\t\t\t\t\tres = regExp.test( value );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '!ends':\n\t\t\t\t\t\tvar regExp = new RegExp( escapeRegExp( refValue ) + '$' );\n\t\t\t\t\t\tres = !regExp.test( value );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '!null':\n\t\t\t\t\t\tres = ( !!value );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'regex':\n\t\t\t\t\t\tvar regExp = new RegExp( refValue );\n\t\t\t\t\t\tres = regExp.test( value );\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthisModel.removed = !res;\n\t\t\t// Fields[ model.path ].toggle( res );\n\t\t\tvar el = window.document.querySelector( '#' +\n\t\t\t\tjQuery.escapeSelector( makeElementId( thisModel.path ) ) );\n\n\t\t\t$( el ).toggle( res );\n\t\t}\n\n\t\t// *** attention, VEForAll was causing an infinite loop\n\t\t// by adding the following class:\n\t\t// ve-for-all-waiting-for-update\n\t\t// use mutation observer's disconnect(); and\n\t\t// initialize again\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tProcessModel.getValue( sourceModel ).then( function ( value ) {\n\t\t\t\tfor ( var i in sourceModel.parent ) {\n\t\t\t\t\tvar model_ = sourceModel.parent[ i ];\n\n\t\t\t\t\tif ( sourceModel.schemaName !== model_.schemaName ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar field_ = model_.schema.wiki;\n\t\t\t\t\tif ( model_.schema.type === 'array' ) {\n\t\t\t\t\t\tfield_ = model_.schema.items.wiki;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !( 'showif-field' in field_ ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// consider only same level\n\t\t\t\t\tif ( field_[ 'showif-field' ] !== field.name ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\ttoggleVisibility( value, model_, field_ );\n\t\t\t\t}\n\t\t\t\tresolve();\n\t\t\t} ).catch( ( err ) => {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error( err );\n\t\t\t} );\n\t\t} );\n\t}\n\n\tfunction clearDependentFields( model ) {\n\t\tfor ( var thisModel of ModelFlatten ) {\n\t\t\tif ( thisModel.schemaName !== model.schemaName ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tvar field = thisModel.schema.wiki;\n\t\t\tif ( !( 'options-query' in field ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar query = field[ 'options-query' ];\n\t\t\tvar regExp = new RegExp( '<' + model.pathNoIndex + '>' );\n\t\t\tif ( regExp.test( query ) ) {\n\t\t\t\tthisModel.input.setValue( !thisModel.multiselect ? '' : [] );\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction updateDependentFields( sourceModel ) {\n\n\t\t// @TODO complete with other optionsInputs\n\t\tvar allowedInputsByContructor = [\n\t\t\t'OoUiDropdownInputWidget',\n\t\t\t'OoUiMenuTagMultiselectWidget'\n\t\t];\n\t\tfor ( let model of ModelFlatten ) {\n\t\t\tlet constructorName = model.input.constructorName || model.input.constructor.name;\n\t\t\tif ( !inArray( constructorName, allowedInputsByContructor ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ( sourceModel.schemaName !== model.schemaName ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar field = model.schema.wiki;\n\t\t\tif ( !( 'options-query' in field ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tvar query = field[ 'options-query' ];\n\t\t\tvar regExp = new RegExp( '<' + sourceModel.pathNoIndex + '>' );\n\t\t\tif ( regExp.test( query ) ) {\n\t\t\t\tProcessModel.getModel( 'schema', sourceModel.schemaName ).then( function ( res ) {\n\t\t\t\t\tfor ( var i in res.flatten ) {\n\n\t\t\t\t\t\tif ( res.flatten[ i ].pathNoIndex === sourceModel.pathNoIndex ) {\n\t\t\t\t\t\t\tperformQuery( model, res.flatten[ i ].value ).then( ( data_ ) => {\n\n\t\t\t\t\t\t\t\t// @TODO complete with other optionsInputs\n\t\t\t\t\t\t\t\tswitch ( constructorName ) {\n\t\t\t\t\t\t\t\t\tcase 'OoUiDropdownInputWidget':\n\t\t\t\t\t\t\t\t\t\t// *** @FIXME this unfortunately does not work.\n\t\t\t\t\t\t\t\t\t\t// see here https://doc.wikimedia.org/mediawiki-core/1.39.5/js/source/oojs-ui-core.html#OO-ui-DropdownInputWidget\n\t\t\t\t\t\t\t\t\t\tvar value = model.input.getValue();\n\t\t\t\t\t\t\t\t\t\tif ( !( value in data_ ) ) {\n\t\t\t\t\t\t\t\t\t\t\tvalue = null;\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tmodel.input.setOptions( VisualDataFunctions.createDropDownOptions( data_ ) );\n\t\t\t\t\t\t\t\t\t\tmodel.input.setValue( value );\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'OoUiMenuTagMultiselectWidget':\n\t\t\t\t\t\t\t\t\t\tmodel.input.menu.clearItems();\n\t\t\t\t\t\t\t\t\t\t// Map to an array of OO.ui.MenuOptionWidgets\n\t\t\t\t\t\t\t\t\t\tvar values = model.input.getValue();\n\t\t\t\t\t\t\t\t\t\tvar items = [];\n\t\t\t\t\t\t\t\t\t\tfor ( var j in data_ ) {\n\t\t\t\t\t\t\t\t\t\t\titems.push(\n\t\t\t\t\t\t\t\t\t\t\t\tnew OO.ui.MenuOptionWidget( {\n\t\t\t\t\t\t\t\t\t\t\t\t\tdata: j,\n\t\t\t\t\t\t\t\t\t\t\t\t\tlabel: data_[ j ]\n\t\t\t\t\t\t\t\t\t\t\t\t} )\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\tmodel.input.addOptions( items );\n\t\t\t\t\t\t\t\t\t\tmodel.input.setValue( values.filter( ( x ) => Object.keys( data_ ).includes( x ) ) );\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\tbreak;\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\t}\n\n\tasync function performQuery( model, inputValue ) {\n\t\tvar field = model.schema.wiki;\n\t\tvar query = field[ 'options-query' ] || field[ 'options-smwquery' ];\n\n\t\t// conditionally get the model\n\t\tvar found = false;\n\t\tvar match;\n\t\t// must be declared as val to avoid infinite loop\n\t\tvar regex = /<([^<>]+)>/g;\n\t\twhile ( ( match = regex.exec( query ) ) !== null ) {\n\t\t\tif ( match && match[ 1 ] !== 'value' ) {\n\t\t\t\tfound = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif ( found ) {\n\t\t\t// return Promise.resolve([]);\n\t\t\tvar res = await ProcessModel.getModel( 'schema', model.schemaName );\n\t\t\tvar parent = model.path.slice( 0, Math.max( 0, model.path.indexOf( '/' ) ) );\n\t\t}\n\n\t\tfunction doQuery( thisQuery ) {\n\t\t\tvar payload = {\n\t\t\t\taction: 'visualdata-queryoptions',\n\t\t\t\tdata: JSON.stringify( {\n\t\t\t\t\tquery: thisQuery,\n\t\t\t\t\tproperties: field[ 'query-printouts' ],\n\t\t\t\t\tschema: field[ 'query-schema' ] || '',\n\t\t\t\t\t'options-query-formula': field[ 'options-query-formula' ] || null,\n\t\t\t\t\t'options-label-formula': field[ 'options-label-formula' ] || null\n\t\t\t\t} )\n\t\t\t};\n\n\t\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\t\tnew mw.Api()\n\t\t\t\t\t.postWithToken( 'csrf', payload )\n\t\t\t\t\t.done( function ( thisRes ) {\n\t\t\t\t\t\tif ( payload.action in thisRes ) {\n\t\t\t\t\t\t\tvar thisData = thisRes[ payload.action ];\n\t\t\t\t\t\t\tif ( 'result' in thisData ) {\n\t\t\t\t\t\t\t\tthisData = thisData.result;\n\t\t\t\t\t\t\t\tresolve( thisData );\n\t\t\t\t\t\t\t} else if ( 'error' in thisData ) {\n\t\t\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\t\t\tconsole.error( 'visualdata-queryoptions', thisData.error );\n\t\t\t\t\t\t\t\treject( thisData.error );\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\t.fail( function ( thisRes ) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.error( 'visualdata-queryoptions', thisRes );\n\t\t\t\t\t\treject( thisRes );\n\t\t\t\t\t} );\n\t\t\t} ).catch( ( err ) => {\n\t\t\t\tVisualDataFunctions.OOUIAlert( `error: ${ err }`, { size: 'medium' } );\n\t\t\t\treturn [];\n\t\t\t} );\n\t\t}\n\n\t\t// e.g. [[organization::<organizations/name>~]]\n\t\tfunction replaceValue( strRight, printout, printoutLeft ) {\n\t\t\tvar fullPath = parent + '/' + printout;\n\t\t\tvar replacements = [];\n\n\t\t\tif ( fullPath in res.flatten ) {\n\t\t\t\tif ( !Array.isArray( res.flatten[ fullPath ].value ) ) {\n\t\t\t\t\treplacements.push( res.flatten[ fullPath ].value );\n\t\t\t\t} else {\n\t\t\t\t\treplacements = replacements.concat( res.flatten[ fullPath ].value );\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\t// could be an array\n\t\t\t\tfor ( var i in res.flatten ) {\n\t\t\t\t\tif ( model.schemaName + '/' + res.flatten[ i ].pathNoIndex === fullPath ) {\n\t\t\t\t\t\treplacements.push( res.flatten[ i ].value );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !replacements.length ) {\n\t\t\t\treplacements.push( '' );\n\t\t\t}\n\n\t\t\treturn replacements.map( function ( val ) {\n\t\t\t\treturn ( printoutLeft ? printoutLeft + '::' : '' ) + strRight.replace( /<([^<>]+)>/, val );\n\t\t\t} ).join( '||' );\n\t\t}\n\n\t\t// must match QueryProcessor -> parseQuery\n\t\tvar parsedQuery = query.replace( /\\[\\[(.+?)\\]\\]/g, function ( thisMatch, content ) {\n\t\t\tvar arr = content.split( '||' );\n\n\t\t\tvar subquery = [];\n\t\t\tfor ( var value of arr ) {\n\t\t\t\tif ( !value.includes( '::' ) ) {\n\t\t\t\t\tvar trimmed = value.trim();\n\t\t\t\t\tvar match_ = trimmed.match( /<([^<>]+)>/ );\n\n\t\t\t\t\t// match_[1] is the subject value\n\t\t\t\t\tif ( match_ ) {\n\t\t\t\t\t\tif ( match_[ 1 ] === 'value' ) {\n\t\t\t\t\t\t\ttrimmed = trimmed.replace( /<([^<>]+)>/, inputValue );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttrimmed = replaceValue( trimmed, match_[ 1 ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsubquery.push( trimmed );\n\n\t\t\t\t} else {\n\t\t\t\t\tvar [ prop, rawValue ] = value.split( '::' );\n\t\t\t\t\tvar trimmedProp = prop.trim();\n\t\t\t\t\tvar trimmedValue = rawValue.trim();\n\n\t\t\t\t\tvar match_ = trimmedValue.match( /<([^<>]+)>/ );\n\t\t\t\t\t// match_[1] is the printout value\n\t\t\t\t\tvar condValue = '';\n\t\t\t\t\tif ( match_ ) {\n\t\t\t\t\t\tif ( match_[ 1 ] === 'value' ) {\n\t\t\t\t\t\t\ttrimmedValue = trimmedValue.replace( /<([^<>]+)>/, inputValue );\n\t\t\t\t\t\t\tcondValue = trimmedProp + '::' + trimmedValue;\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcondValue = replaceValue( trimmedValue, match_[ 1 ], trimmedProp );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcondValue = value;\n\t\t\t\t\t}\n\n\t\t\t\t\tsubquery.push( condValue );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn '[[' + subquery.join( '||' ) + ']]';\n\t\t} );\n\n\t\treturn doQuery( parsedQuery );\n\t}\n\n\tvar FileItemWidget = function ( config ) {\n\t\tconfig = config || {};\n\t\tFileItemWidget.super.call( this, config );\n\n\t\tvar self = this;\n\t\tthis.parentWidget = config.parentWidget;\n\t\tthis.parentWidget.setFileKey( null );\n\n\t\tOO.ui.mixin.GroupWidget.call(\n\t\t\tthis,\n\t\t\t$.extend(\n\t\t\t\t{\n\t\t\t\t\t$group: this.$element\n\t\t\t\t},\n\t\t\t\tconfig\n\t\t\t)\n\t\t);\n\n\t\tvar deleteButton = new OO.ui.ButtonWidget( {\n\t\t\ticon: 'trash'\n\t\t\t// flags: [\"destructive\"],\n\t\t} );\n\n\t\tvar inputConfig = {\n\t\t\trequired: true,\n\t\t\tvalue: config.value\n\t\t};\n\n\t\tvar inputWidget = VisualDataFunctions.inputInstanceFromName(\n\t\t\t'OO.ui.TextInputWidget',\n\t\t\tinputConfig\n\t\t);\n\n\t\tthis.inputWidget = inputWidget;\n\n\t\tvar filePreview = new OO.ui.Widget( {\n\t\t\tclasses: [ 'mw-upload-bookletLayout-filePreview' ]\n\t\t} );\n\t\tvar progressBarWidget = new OO.ui.ProgressBarWidget( {\n\t\t\tprogress: 0\n\t\t} );\n\n\t\tthis.progressBarWidget = progressBarWidget;\n\t\tthis.textInputWidget = inputWidget;\n\n\t\tthis.messageWidget = new OO.ui.MessageWidget( {\n\t\t\ttype: 'error',\n\t\t\tlabel: '',\n\t\t\tclasses: [ 'visualdata-upload-messagewidget' ]\n\t\t} );\n\n\t\tfilePreview.$element.append( progressBarWidget.$element );\n\t\tfilePreview.$element.append( inputWidget.$element );\n\t\tfilePreview.$element.append( this.messageWidget.$element );\n\n\t\tprogressBarWidget.toggle( !config.loaded );\n\t\tinputWidget.toggle( config.loaded );\n\t\tthis.messageWidget.toggle( false );\n\n\t\tthis.progress = function ( progress, estimatedRemainingTime ) {\n\t\t\tself.progressBarWidget.setProgress( progress * 100 );\n\t\t};\n\n\t\tthis.uploadComplete = function ( file, res ) {\n\t\t\tself.progressBarWidget.toggle( false );\n\t\t\tself.textInputWidget.toggle( true );\n\n\t\t\tself.parentWidget.setFileKey( res.upload.filekey );\n\t\t};\n\n\t\tthis.errorMessage = function ( errorMessage ) {\n\t\t\tself.textInputWidget.toggle( false );\n\t\t\tself.progressBarWidget.toggle( false );\n\t\t\tself.messageWidget.setLabel( errorMessage.getMessage() );\n\t\t\tself.messageWidget.toggle( true );\n\t\t};\n\n\t\tthis.fail = function ( res ) {};\n\n\t\tvar widget = new OO.ui.ActionFieldLayout( filePreview, deleteButton, {\n\t\t\tlabel: '',\n\t\t\talign: 'top'\n\t\t\t// classes: [\"inputName-\" + config.inputName],\n\t\t} );\n\n\t\tthis.$element.append( widget.$element );\n\n\t\tdeleteButton.connect( this, {\n\t\t\tclick: 'onDeleteButtonClick'\n\t\t} );\n\t};\n\n\tOO.inheritClass( FileItemWidget, OO.ui.Widget );\n\tOO.mixinClass( FileItemWidget, OO.ui.mixin.GroupWidget );\n\n\tFileItemWidget.prototype.onDeleteButtonClick = function () {\n\t\tthis.emit( 'delete', 'file' );\n\n\t\tthis.parentWidget.clearFileClick( this );\n\t};\n\n\tvar FileUploadGroupWidget = function ( config ) {\n\t\t// Configuration initialization\n\t\tconfig = config || {};\n\n\t\t// Parent constructor\n\t\tFileUploadGroupWidget.super.call( this, config );\n\n\t\t// Mixin constructors\n\t\tOO.ui.mixin.GroupElement.call(\n\t\t\tthis,\n\t\t\t$.extend(\n\t\t\t\t{\n\t\t\t\t\t$group: this.$element\n\t\t\t\t},\n\t\t\t\tconfig\n\t\t\t)\n\t\t);\n\n\t\tthis.addItems( config.items || [] );\n\t};\n\n\tOO.inheritClass( FileUploadGroupWidget, OO.ui.Widget );\n\tOO.mixinClass( FileUploadGroupWidget, OO.ui.mixin.GroupElement );\n\n\tvar ItemWidget = function ( config ) {\n\t\tvar self = this;\n\t\tconfig = config || {};\n\t\tItemWidget.super.call( this, config );\n\n\t\tvar schema = config.model.schema;\n\t\tvar fieldAlign = getFieldAlign( schema );\n\t\tvar helpInline = getHelpInline( schema );\n\n\t\tvar inputWidget = getInputWidget( config );\n\n\t\tinputWidget.on( 'change', function () {\n\t\t\t// updateFieldsVisibility( config.model );\n\t\t\tclearDependentFields( config.model );\n\t\t} );\n\n\t\tinputWidget.$element.find( 'input' ).on( 'blur', function () {\n\t\t\tupdateFieldsVisibility( config.model );\n\t\t\tupdateDependentFields( config.model );\n\t\t\tupdateDefaultValue( config.model );\n\t\t} );\n\n\t\tconfig.model.input = inputWidget;\n\n\t\tModelFlatten.push( config.model );\n\n\t\tconfig.model.multiselect = VisualDataFunctions.isMultiselect(\n\t\t\tschema.wiki[ 'preferred-input' ]\n\t\t);\n\n\t\tconfig.model.isFile = config.model.inputName === 'OO.ui.SelectFileWidget';\n\n\t\tif ( config.model.isFile ) {\n\t\t\tvar fileItemWidget;\n\n\t\t\tvar restoreButton = new OO.ui.ButtonWidget( {\n\t\t\t\ticon: 'restore'\n\t\t\t} );\n\n\t\t\trestoreButton.toggle( false );\n\n\t\t\tvar fileUploadGroupWidget = new FileUploadGroupWidget( {\n\t\t\t\titems: [ inputWidget, restoreButton ]\n\t\t\t} );\n\n\t\t\tthis.setFileKey = function ( filekey ) {\n\t\t\t\tconfig.model.filekey = filekey;\n\t\t\t};\n\n\t\t\tvar loadedFiles = {};\n\n\t\t\t// @FIXME\n\t\t\t// eslint-disable-next-line no-inner-declarations\n\t\t\tfunction createFileItemWidget( filename, loaded ) {\n\t\t\t\t// inputWidget is the SelectFileWidget\n\t\t\t\tinputWidget.toggle( false );\n\n\t\t\t\t// if ( loaded ) {\n\t\t\t\tconfig.model.previousFilename = filename;\n\t\t\t\t// }\n\n\t\t\t\tvar thisFileItemWidget = new FileItemWidget( {\n\t\t\t\t\tclasses: [ 'VisualDataFileItemWidget' ],\n\t\t\t\t\tvalue: filename,\n\t\t\t\t\tloaded: loaded,\n\t\t\t\t\tparentWidget: self\n\t\t\t\t} );\n\n\t\t\t\t// @see oojs-ui-core.js -> OO.ui.SelectFileInputWidget.prototype.updateUI\n\t\t\t\tinputWidget.loadAndGetImageUrl( inputWidget.getValue() ).done( ( thisUrl ) => {\n\t\t\t\t\tvar $thumbnail = $( '<div>' )\n\t\t\t\t\t\t.addClass( 'oo-ui-selectFileInputWidget-dropTarget' )\n\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\tposition: 'relative',\n\t\t\t\t\t\t\t'max-width': '50em',\n\t\t\t\t\t\t\t'border-top': 'none'\n\t\t\t\t\t\t} ).append( $( '<div>' )\n\t\t\t\t\t\t\t.addClass( 'oo-ui-selectFileInputWidget-thumbnail oo-ui-selectFileWidget-thumbnail' )\n\t\t\t\t\t\t\t.css( 'background-image', 'url( ' + thisUrl + ' )'\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\tthisFileItemWidget.$element\n\t\t\t\t\t\t.addClass( 'oo-ui-selectFileInputWidget-withThumbnail oo-ui-selectFileWidget-withThumbnail' )\n\t\t\t\t\t\t.append( $thumbnail );\n\n\t\t\t\t} ).fail( () => {\n\t\t\t\t} );\n\n\t\t\t\tloadedFiles[ filename ] = thisFileItemWidget;\n\t\t\t\tfileUploadGroupWidget.addItems( [ thisFileItemWidget ] );\n\n\t\t\t\t// overwrite the model, we want to\n\t\t\t\t// validate the filename\n\t\t\t\tconfig.model.input = thisFileItemWidget.inputWidget;\n\n\t\t\t\treturn thisFileItemWidget;\n\t\t\t}\n\n\t\t\t// create fileItemWidget with existing filename\n\t\t\tif ( typeof config.data === 'string' && config.data.trim() !== '' ) {\n\t\t\t\tfileItemWidget = createFileItemWidget( config.data, true );\n\t\t\t}\n\n\t\t\tthis.clearFileClick = function ( item ) {\n\t\t\t\trestoreButton.toggle( true );\n\n\t\t\t\t// inputWidget is the SelectFileWidget\n\t\t\t\tinputWidget.toggle( true );\n\t\t\t\tinputWidget.setValue( null );\n\n\t\t\t\t// TextInputWidget used for validation\n\t\t\t\tconfig.model.input.setValue( null );\n\n\t\t\t\t// this will remove fileItemWidget\n\t\t\t\tfileUploadGroupWidget.removeItems( [ item ] );\n\t\t\t};\n\n\t\t\trestoreButton.on( 'click', function () {\n\t\t\t\tinputWidget.toggle( false );\n\t\t\t\trestoreButton.toggle( false );\n\t\t\t\tfileUploadGroupWidget.removeItems( [ fileItemWidget ] );\n\t\t\t\tfileItemWidget = createFileItemWidget(\n\t\t\t\t\t// the previous content of fileItemWidget.inputWidget\n\t\t\t\t\t// (a TextInputWidget with filename)\n\t\t\t\t\tconfig.model.previousFilename,\n\t\t\t\t\ttrue\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\t// @FIXME move to FileItemWidget\n\n\t\t\tthis.on( 'fileUploaded', function ( file ) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log( 'event fileUploaded', file );\n\t\t\t} );\n\n\t\t\tthis.on( 'fileUploadInit', function ( file ) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log( 'event fileUploadInit', file );\n\t\t\t\trestoreButton.toggle( false );\n\t\t\t\tfileItemWidget = createFileItemWidget( file.name, false );\n\t\t\t} );\n\n\t\t\tthis.on(\n\t\t\t\t'fileUploadProgress',\n\t\t\t\tfunction ( file, progress, estimatedRemainingTime ) {\n\t\t\t\t\tloadedFiles[ file.name ].progress( progress, estimatedRemainingTime );\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tthis.on( 'fileUploadComplete', function ( file, res ) {\n\t\t\t\tloadedFiles[ file.name ].uploadComplete( file, res );\n\t\t\t} );\n\n\t\t\tthis.on( 'fileUploadErrorMessage', function ( file, errorMessage ) {\n\t\t\t\tloadedFiles[ file.name ].errorMessage( errorMessage );\n\t\t\t} );\n\n\t\t\tthis.on( 'fileUploadFail', function ( file, res ) {\n\t\t\t\tloadedFiles[ file.name ].fail( res );\n\t\t\t} );\n\n\t\t\tvar upload = new VisualDataUpload();\n\t\t\tupload.initialize( inputWidget, this );\n\t\t\tinputWidget.on( 'change', upload.uploadFiles.bind( upload ) );\n\t\t}\n\n\t\t// schema.description is removed if wiki['help-message'] was \"\"\n\t\tvar helpMessage = ( 'help-message' in schema.wiki && 'description' in schema ? schema.description : '' );\n\n\t\tvar fieldLayout = new OO.ui.FieldLayout(\n\t\t\t!config.model.isFile ? inputWidget : fileUploadGroupWidget, {\n\t\t\t\tlabel: new OO.ui.HtmlSnippet( 'label' in schema.wiki && 'title' in schema ? schema.title : '' ),\n\t\t\t\talign: fieldAlign,\n\t\t\t\thelpInline: helpMessage ? helpInline : true,\n\t\t\t\thelp: new OO.ui.HtmlSnippet( helpMessage )\n\t\t\t\t// classes: [`visualdata-input-${ config.model.path }`],\n\t\t\t}\n\t\t);\n\n\t\tFields[ config.model.path ] = fieldLayout;\n\n\t\tif ( config.optionsList ) {\n\t\t\tvar deleteButton = new OO.ui.ButtonWidget( {\n\t\t\t\ticon: 'close',\n\t\t\t\tclasses: [ 'visualdata-input-widget-right' ]\n\t\t\t} );\n\n\t\t\tdeleteButton.on( 'click', function () {\n\t\t\t\tconfig.optionsList.removeItem( config.widget );\n\t\t\t} );\n\n\t\t\tvar icon = new OO.ui.IconWidget( {\n\t\t\t\ticon: 'draggable'\n\t\t\t\t// title: 'drag to sort'\n\t\t\t} );\n\n\t\t\tvar moveEl = $( '<div class=\"visualdata-input-widget-move\"></div>' );\n\t\t\tmoveEl.append( icon.$element );\n\n\t\t\tfieldLayout.$field.addClass( 'visualdata-input-widget-field-container' );\n\t\t\tfieldLayout.$field.append( [ deleteButton.$element ] );\n\t\t\tfieldLayout.$field.prepend( [ moveEl ] );\n\t\t}\n\n\t\tthis.$element.append( fieldLayout.$element );\n\t};\n\n\tOO.inheritClass( ItemWidget, OO.ui.Widget );\n\tOO.mixinClass( ItemWidget, OO.ui.mixin.GroupWidget );\n\n\t// @see https://gerrit.wikimedia.org/r/plugins/gitiles/oojs/ui/+/c2805c7e9e83e2f3a857451d46c80231d1658a0f/demos/classes/SearchWidgetDialog.js\n\tfunction ProcessDialogSearch( config ) {\n\t\tProcessDialogSearch.super.call( this, config );\n\t}\n\tOO.inheritClass( ProcessDialogSearch, OO.ui.ProcessDialog );\n\tProcessDialogSearch.static.name = DialogSearchName;\n\n\tProcessDialogSearch.prototype.initialize = function () {\n\t\tProcessDialogSearch.super.prototype.initialize.apply( this, arguments );\n\t\tvar self = this;\n\t\tvar selectedSchemas = Form.schemas;\n\t\tthis.selectedItems = [];\n\t\tfunction getItems( value ) {\n\t\t\tvar values;\n\t\t\tswitch ( self.data.toolName ) {\n\t\t\t\tcase 'addremoveschemas':\n\t\t\t\t\tself.selectedItems = selectedSchemas;\n\t\t\t\t\tvalues = Object.keys( Schemas );\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ( value ) {\n\t\t\t\tvar valueLowerCase = value.toLowerCase();\n\t\t\t\tvalues = values.filter(\n\t\t\t\t\t( x ) => x.toLowerCase().includes( valueLowerCase )\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn VisualDataFunctions.sort( values ).map( ( x ) => {\n\t\t\t\tvar menuOptionWidget = new OO.ui.MenuOptionWidget( {\n\t\t\t\t\tdata: x,\n\t\t\t\t\tlabel: x,\n\t\t\t\t\tselected: inArray( x, self.selectedItems )\n\t\t\t\t} );\n\t\t\t\treturn menuOptionWidget;\n\t\t\t} );\n\t\t}\n\n\t\tvar searchWidget = new OO.ui.SearchWidget( {\n\t\t\t// id: \"visualdata-import-search-widget\",\n\t\t} );\n\n\t\tsearchWidget.results.addItems( getItems() );\n\n\t\t// searchWidget.getResults() is a SelectWidget\n\t\t// https://doc.wikimedia.org/oojs-ui/master/js/#!/api/OO.ui.SelectWidget\n\t\tvar searchWidgetResults = searchWidget.getResults();\n\t\tsearchWidgetResults.multiselect = true;\n\n\t\tsearchWidgetResults.on( 'press', function ( value ) {\n\t\t\tif ( value === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( inArray( value.data, self.selectedItems ) ) {\n\t\t\t\tself.selectedItems.splice( self.selectedItems.indexOf( value.data ), 1 );\n\t\t\t} else {\n\t\t\t\tself.selectedItems.push( value.data );\n\t\t\t}\n\t\t} );\n\t\tsearchWidget.onQueryChange = function ( value ) {\n\t\t\tsearchWidget.results.clearItems();\n\t\t\tsearchWidget.results.addItems( getItems( value ) );\n\t\t};\n\n\t\tthis.$body.append( [ searchWidget.$element ] );\n\t};\n\n\tProcessDialogSearch.prototype.getBodyHeight = function () {\n\t\treturn 300;\n\t};\n\n\tProcessDialogSearch.static.actions = [\n\t\t{\n\t\t\taction: 'save',\n\t\t\t// modes: \"edit\",\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-searchdialog-save' ),\n\t\t\tflags: [ 'primary', 'progressive' ]\n\t\t},\n\t\t{\n\t\t\t// modes: \"edit\",\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-cancel' ),\n\t\t\tflags: [ 'safe', 'close' ]\n\t\t}\n\t];\n\tProcessDialogSearch.prototype.getActionProcess = function ( action ) {\n\t\tvar dialog = this;\n\n\t\tif ( action === 'save' ) {\n\t\t\tvar values = processDialogSearch.selectedItems;\n\t\t\t// ProcessModel.getModel(\"fetch\").then(function (res) {\n\t\t\t// Form.jsonData.schemas = res;\n\n\t\t\tswitch ( dialog.data.toolName ) {\n\t\t\t\tcase 'addremoveschemas':\n\t\t\t\t\tfor ( var i in ModelSchemas ) {\n\t\t\t\t\t\tif ( !inArray( i, values ) ) {\n\t\t\t\t\t\t\t// delete Form.jsonData.schemas[ i ];\n\t\t\t\t\t\t\tdelete ModelSchemas[ i ];\n\t\t\t\t\t\t\tdelete Fields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tvar missingSchemas = [];\n\t\t\t\t\tfor ( var i of values ) {\n\t\t\t\t\t\tif ( !( i in Schemas ) || !Object.keys( Schemas[ i ] ).length ) {\n\t\t\t\t\t\t\tmissingSchemas.push( i );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// select first schema of new selection\n\t\t\t\t\tfor ( var i of values ) {\n\t\t\t\t\t\tif ( !( i in ModelSchemas ) ) {\n\t\t\t\t\t\t\tSelectedSchema = i;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( missingSchemas.length ) {\n\t\t\t\t\t\tVisualData.loadSchemas( missingSchemas );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tupdatePanels();\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// });\n\t\t}\n\n\t\treturn new OO.ui.Process( function () {\n\t\t\tdialog.close( { action: action } );\n\t\t} );\n\n\t\t// return ProcessDialog.super.prototype.getActionProcess.call( this, action );\n\t};\n\tProcessDialogSearch.prototype.getTeardownProcess = function ( data ) {\n\t\treturn ProcessDialogSearch.super.prototype.getTeardownProcess\n\t\t\t.call( this, data )\n\t\t\t.first( function () {\n\t\t\t\tWindowManager.removeActiveWindow();\n\t\t\t}, this );\n\t};\n\n\tfunction openSearchDialog( toolName ) {\n\t\tprocessDialogSearch = new ProcessDialogSearch( {\n\t\t\tsize: 'medium',\n\t\t\t// classes: [\"visualdata-search-dialog\"],\n\t\t\tdata: { toolName: toolName }\n\t\t} );\n\n\t\tWindowManager.newWindow( processDialogSearch, {\n\t\t\ttitle: mw.msg(\n\t\t\t\t'visualdata-jsmodule-forms-dialogsearch-selectschemas'\n\t\t\t)\n\t\t} );\n\t}\n\n\t// @see https://doc.wikimedia.org/oojs-ui/master/js/#!/api/OO.ui.Toolbar\n\t// @see https://gerrit.wikimedia.org/r/plugins/gitiles/oojs/ui/+/c2805c7e9e83e2f3a857451d46c80231d1658a0f/demos/pages/toolbars.js\n\tfunction createToolbar( /* disabled */ ) {\n\t\tvar toolFactory = new OO.ui.ToolFactory();\n\t\tvar toolGroupFactory = new OO.ui.ToolGroupFactory();\n\n\t\tvar toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory, {\n\t\t\tactions: true\n\t\t} );\n\n\t\tvar onSelect = function ( self ) {\n\t\t\tvar self = arguments.length ? self : this;\n\t\t\tvar toolName = self.getName();\n\n\t\t\tswitch ( toolName ) {\n\t\t\t\tcase 'addremoveschemas':\n\t\t\t\t\topenSearchDialog( toolName );\n\t\t\t\t\tbreak;\n\t\t\t\t// case \"createschema\":\n\t\t\t\t// \tVisualDataSchemas.openDialog(null, false);\n\t\t\t\t// \tbreak;\n\t\t\t}\n\n\t\t\tself.setActive( false );\n\t\t};\n\n\t\tvar loadDataBeforeSelect = function () {\n\t\t\tvar dataToLoad = VisualData.matchLoadedData( Config, [\n\t\t\t\t'schemas'\n\t\t\t] );\n\n\t\t\tif ( !dataToLoad.length ) {\n\t\t\t\treturn onSelect( this );\n\t\t\t}\n\n\t\t\tthis.setDisabled( true );\n\t\t\tthis.pushPending();\n\n\t\t\tVisualData.loadData( Config, dataToLoad )\n\t\t\t\t.then( ( res ) => {\n\t\t\t\t\tif ( 'schemas' in res ) {\n\t\t\t\t\t\tSchemas = res.schemas;\n\t\t\t\t\t}\n\t\t\t\t\tthis.setDisabled( false );\n\t\t\t\t\tthis.popPending();\n\t\t\t\t\tonSelect( this );\n\t\t\t\t} )\n\t\t\t\t.catch( ( error ) => {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.error( 'loadData error', error );\n\t\t\t\t\tthis.popPending();\n\t\t\t\t\tthis.setDisabled( false );\n\t\t\t\t\tthis.setActive( false );\n\n\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\tVisualDataFunctions.OOUIAlert( new OO.ui.HtmlSnippet( mw.msg( error ) ), {\n\t\t\t\t\t\tsize: 'medium'\n\t\t\t\t\t} );\n\t\t\t\t} );\n\t\t};\n\n\t\tvar toolGroup = [];\n\n\t\tif ( Config.context !== 'parserfunction' ) {\n\t\t\ttoolGroup.push( {\n\t\t\t\tname: 'addremoveschemas',\n\t\t\t\ticon: 'add',\n\t\t\t\ttitle: mw.msg(\n\t\t\t\t\t'visualdata-jsmodule-forms-addremoveschemas'\n\t\t\t\t),\n\t\t\t\tonSelect: onSelect\n\t\t\t} );\n\t\t}\n\n\t\tVisualDataFunctions.createToolGroup( toolFactory, 'group', toolGroup );\n\n\t\ttoolbar.setup( [\n\t\t\t{\n\t\t\t\tname: 'my-group',\n\t\t\t\t// type: \"bar\",\n\t\t\t\t// label: \"Create property\",\n\t\t\t\tinclude: [ { group: 'group' } ]\n\t\t\t}\n\t\t] );\n\n\t\treturn toolbar;\n\t}\n\n\tfunction createActionToolbar( /* disabled */ ) {\n\t\t// see https://gerrit.wikimedia.org/r/plugins/gitiles/oojs/ui/+/refs/tags/v0.40.4/demos/pages/toolbars.js\n\t\tvar toolFactory = new OO.ui.ToolFactory();\n\t\tvar toolGroupFactory = new OO.ui.ToolGroupFactory();\n\n\t\tvar toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory, {\n\t\t\tactions: false\n\t\t} );\n\n\t\tvar onSelect = function ( self ) {\n\t\t\tvar self = arguments.length ? self : this;\n\t\t\tvar selected = self.getName();\n\n\t\t\tvar panels = OuterStack.getItems();\n\t\t\tfor ( var panel of panels ) {\n\t\t\t\tif ( panel.getData().name === selected ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tOuterStack.setItem( panel );\n\n\t\t\t// *** this prevents inconsistencies of the datatable layout\n\t\t\tswitch ( selected ) {\n\t\t\t\tcase 'manage-schemas':\n\t\t\t\t\tVisualDataSchemas.initialize();\n\t\t\t\t\tbreak;\n\t\t\t\t// case \"manage-forms\":\n\t\t\t\t// \t\tVisualDataForms.initialize();\n\t\t\t\t// \t\tbreak;\n\t\t\t}\n\n\t\t\tself.setActive( false );\n\t\t};\n\n\t\tvar loadDataBeforeSelect = function () {\n\t\t\tvar dataToLoad = VisualData.matchLoadedData( Config, [\n\t\t\t\t// \"forms\",\n\t\t\t\t'schemas'\n\t\t\t\t// \"semantic-properties\",\n\t\t\t\t// \"imported-vocabularies\",\n\t\t\t\t// \"type-labels\",\n\t\t\t\t// \"property-labels\",\n\t\t\t] );\n\n\t\t\tif ( !dataToLoad.length ) {\n\t\t\t\treturn onSelect( this );\n\t\t\t}\n\n\t\t\t// this.setDisabled(true);\n\t\t\t// this.pushPending();\n\n\t\t\tActionWidget = new OO.ui.ActionWidget();\n\t\t\tToolbarMain.$bar.wrapInner( '<div class=\"wrapper\"></div>' );\n\t\t\tActionWidget.setPendingElement( ToolbarMain.$bar.find( '.wrapper' ) );\n\t\t\tActionWidget.pushPending();\n\n\t\t\t$( ToolbarMain.$bar ).find( '.wrapper' ).css( 'pointer-events', 'none' );\n\n\t\t\tVisualData.loadData( Config, dataToLoad )\n\t\t\t\t.then( ( res ) => {\n\t\t\t\t\t// this.setDisabled(false);\n\t\t\t\t\t// this.popPending();\n\t\t\t\t\tActionWidget.popPending();\n\t\t\t\t\t$( ToolbarMain.$bar ).find( '.wrapper' ).css( 'pointer-events', 'auto' );\n\n\t\t\t\t\t// VisualDataForms.initialize(Self, Forms);\n\n\t\t\t\t\tonSelect( this );\n\t\t\t\t} )\n\t\t\t\t.catch( ( error ) => {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.error( 'loadData error', error );\n\t\t\t\t\tActionWidget.popPending();\n\t\t\t\t\t$( ToolbarMain.$bar ).find( '.wrapper' ).css( 'pointer-events', 'auto' );\n\t\t\t\t\tthis.setActive( false );\n\n\t\t\t\t\t// eslint-disable-next-line mediawiki/msg-doc\n\t\t\t\t\tVisualDataFunctions.OOUIAlert( new OO.ui.HtmlSnippet( mw.msg( error ) ), {\n\t\t\t\t\t\tsize: 'medium'\n\t\t\t\t\t} );\n\t\t\t\t} );\n\t\t};\n\n\t\tvar toolGroup = [\n\t\t\t{\n\t\t\t\tname: 'visualdata',\n\t\t\t\ticon: null,\n\t\t\t\ttitle: mw.msg( 'visualdata-jsmodule-forms-edit-data' ),\n\t\t\t\tonSelect: onSelect\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'manage-schemas',\n\t\t\t\ticon: null,\n\t\t\t\ttitle: mw.msg( 'visualdata-jsmodule-forms-manage-schemas' ),\n\t\t\t\tonSelect: loadDataBeforeSelect\n\t\t\t\t// config: {\n\t\t\t\t// \tdata: { disabled: disabled },\n\t\t\t\t// },\n\t\t\t}\n\t\t\t// {\n\t\t\t// \tname: 'manage-forms',\n\t\t\t// \ticon: null,\n\t\t\t// \ttitle: mw.msg( 'visualdata-jsmodule-forms-manage-forms' ),\n\t\t\t// \tonSelect: loadDataBeforeSelect\n\t\t\t// \t// config: {\n\t\t\t// \t// \tdata: { disabled: disabled },\n\t\t\t// \t// },\n\t\t\t// }\n\t\t];\n\n\t\ttoolbar.setup( [\n\t\t\t// see https://gerrit.wikimedia.org/r/plugins/gitiles/oojs/ui/+/c2805c7e9e83e2f3a857451d46c80231d1658a0f/demos/pages/toolbars.js\n\t\t\t{\n\t\t\t\tname: 'editorSwitch',\n\t\t\t\talign: 'after',\n\t\t\t\ttype: 'list',\n\t\t\t\tlabel: 'Switch editor',\n\t\t\t\tinvisibleLabel: true,\n\t\t\t\ticon: 'menu',\n\t\t\t\tinclude: [ { group: 'selectSwitch' } ]\n\t\t\t}\n\t\t] );\n\n\t\t// @see https://gerrit.wikimedia.org/r/plugins/gitiles/oojs/ui/+/c2805c7e9e83e2f3a857451d46c80231d1658a0f/demos/pages/toolbars.js\n\t\t// VisualDataFunctions.createDisabledToolGroup(\n\t\t// \ttoolGroupFactory,\n\t\t// \tOO.ui.ListToolGroup,\n\t\t// \t\"editorSwitch\",\n\t\t// );\n\n\t\tVisualDataFunctions.createToolGroup(\n\t\t\ttoolFactory,\n\t\t\t'selectSwitch',\n\t\t\ttoolGroup\n\t\t);\n\n\t\treturn toolbar;\n\t}\n\n\tvar GroupWidget = function ( config, data ) {\n\t\tconfig = config || {};\n\t\tGroupWidget.super.call( this, config );\n\n\t\tOO.ui.mixin.GroupWidget.call(\n\t\t\tthis,\n\t\t\t$.extend( { $group: this.$element }, config )\n\t\t);\n\t\t// OO.EventEmitter.call( this );\n\n\t\tthis.data = data;\n\n\t\t// eslint-disable-next-line wrap-iife\n\t\tvar showBorder = ( function () {\n\t\t\tif (\n\t\t\t\tdata.root ||\n\t\t\t\tdata.schema.wiki.type === 'content-block' ||\n\t\t\t\tdata.schema.wiki.type === 'property'\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tdata.schema.type === 'array' &&\n\t\t\t\tVisualDataFunctions.getNestedProp( [ 'items', 'wiki', 'preferred-input' ], data.schema ) &&\n\t\t\t\tdata.schema.items.type !== 'object' &&\n\t\t\t\tVisualDataFunctions.isMultiselect(\n\t\t\t\t\tdata.schema.items.wiki[ 'preferred-input' ]\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t} )();\n\n\t\tvar classes = [ 'VisualDataGroupWidgetPanel' + ( !showBorder ? '-border' : '' ) ];\n\n\t\tif ( data.isObjectList ) {\n\t\t\tclasses.push( 'sortable' );\n\t\t}\n\n\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\tvar layout = new OO.ui.PanelLayout( {\n\t\t\texpanded: false,\n\t\t\tpadded: showBorder,\n\t\t\tframed: showBorder,\n\t\t\tclasses,\n\t\t\tid: makeElementId( data.path )\n\t\t} );\n\n\t\tif ( data.root ) {\n\t\t\tthis.data.rootEl = layout.$element;\n\n\t\t\tvar $containerRight = $( '<div class=\"visualdata-form-container-right\">' );\n\t\t\tlayout.$element.append( $containerRight );\n\n\t\t\tif ( Config.context === 'EditData' ) {\n\t\t\t\tvar deleteButton = new OO.ui.ButtonWidget( {\n\t\t\t\t\ticon: 'trash',\n\t\t\t\t\tframed: false,\n\t\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-delete-schema' ),\n\t\t\t\t\tinvisibleLabel: true,\n\t\t\t\t\tflags: [ 'destructive' ]\n\t\t\t\t} );\n\n\t\t\t\tdeleteButton.on( 'click', function () {\n\t\t\t\t\tForm.schemas.splice( Form.schemas.indexOf( data.schema.wiki.name ), 1 );\n\t\t\t\t\t// delete Form.jsonData.schemas[ data.schema.wiki.name ];\n\t\t\t\t\t// Schemas[ data.schema.wiki.name ] = {};\n\t\t\t\t\tdelete ModelSchemas[ data.schema.wiki.name ];\n\t\t\t\t\tdelete Fields[ data.schema.wiki.name ];\n\t\t\t\t\tfor ( var i in InputWidgets ) {\n\t\t\t\t\t\tif ( i.indexOf( FormID + '-' + data.schema.wiki.name + '/' ) === 0 ) {\n\t\t\t\t\t\t\tdelete InputWidgets[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tupdatePanels();\n\t\t\t\t} );\n\n\t\t\t\t$containerRight.append( deleteButton.$element );\n\t\t\t}\n\n\t\t\tif ( Config.canmanageschemas ) {\n\t\t\t\tvar editButton = new OO.ui.ButtonWidget( {\n\t\t\t\t\t// 'settings'\n\t\t\t\t\ticon: 'edit',\n\t\t\t\t\tframed: false,\n\t\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-edit-schema' ),\n\t\t\t\t\tinvisibleLabel: true\n\t\t\t\t\t// classes: [\"VisualDataOptionsListDeleteButton\"],\n\t\t\t\t} );\n\n\t\t\t\teditButton.on( 'click', function () {\n\t\t\t\t\tVisualDataSchemas.openSchemaDialog(\n\t\t\t\t\t\t[ data.schema.wiki.name ],\n\t\t\t\t\t\t'properties'\n\t\t\t\t\t);\n\t\t\t\t} );\n\n\t\t\t\t$containerRight.append( editButton.$element );\n\t\t\t}\n\t\t}\n\n\t\tvar messageWidget = new OO.ui.MessageWidget( {\n\t\t\tclasses: [ 'VisualDataGroupWidgetMessageWidget' ]\n\t\t} );\n\n\t\t// @TODO toggle parent as well if all children\n\t\t// aren't visible\n\t\tif ( data.schema.type === 'array' ) {\n\t\t\tthis.toggle(\n\t\t\t\t!VisualDataFunctions.getNestedProp(\n\t\t\t\t\t[ 'schema', 'items', 'options', 'hidden' ],\n\t\t\t\t\tdata\n\t\t\t\t)\n\t\t\t);\n\n\t\t} else {\n\t\t\tthis.toggle(\n\t\t\t\t!VisualDataFunctions.getNestedProp(\n\t\t\t\t\t[ 'schema', 'options', 'hidden' ],\n\t\t\t\t\tdata\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tmessageWidget.toggle( false );\n\n\t\tFields[ data.path ] = messageWidget;\n\n\t\tlayout.$element.append( messageWidget.$element );\n\n\t\tswitch ( data.schema.wiki.layout ) {\n\t\t\tcase 'horizontal':\n\t\t\t\tthis.layoutHorizontal = new OO.ui.HorizontalLayout();\n\t\t\t\tlayout.$element.append( this.layoutHorizontal.$element );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// title and description are mapped to label and\n\t\t\t\t// help-message in the property field, and\n\t\t\t\t// schema.wiki.title and schema.wiki.description\n\t\t\t\t// contain the wikitext, not the parsed output\n\n\t\t\t\tthis.fieldset = new OO.ui.FieldsetLayout( {\n\t\t\t\t\tlabel: new OO.ui.HtmlSnippet( 'title' in data.schema.wiki && 'title' in data.schema ? data.schema.title : '' )\n\t\t\t\t} );\n\n\t\t\t\tif ( 'description' in data.schema.wiki && 'description' in data.schema ) {\n\t\t\t\t\tthis.fieldset.addItems( [\n\t\t\t\t\t\tnew OO.ui.Element( {\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\tnew OO.ui.HtmlSnippet( data.schema.description )\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\n\t\t\t\tlayout.$element.append( this.fieldset.$element );\n\n\t\t\t\tif ( data.schema.wiki.type === 'geolocation' && data.schema.wiki.map === true ) {\n\t\t\t\t\tif ( !Maps.length ) {\n\t\t\t\t\t\t( new VisualDataMaptiler() ).load();\n\t\t\t\t\t}\n\t\t\t\t\tMaps.push( { data, element: layout.$element } );\n\t\t\t\t}\n\n\t\t\t\tthis.connect( this, {\n\t\t\t\t\tformLoaded: 'formLoaded'\n\t\t\t\t} );\n\t\t}\n\n\t\t/*\n\t\t// @TODO implement button switch for oneOf, anyOf\n\t\tthis.buttonSelectWidget = new OO.ui.ButtonSelectWidget();\n\n\t\tvar self = this;\n\t\tthis.buttonSelectWidget.on(\"choose\", function (item, seleted) {\n\t\t\tself.booklet.setPage(item.data);\n\t\t});\n\n\t\tlayout.$element.append(this.buttonSelectWidget.$element);\n\n\t\t// var directives = [ 'anyOf', 'oneOf', 'allOf' ];\n\n\t\t// for ( var directive of directives ) {\n\t\t// \tthis['fieldset-' + directive] = new OO.ui.FieldsetLayout({\n\t\t// \t\t// label: data.wiki.title,\n\t\t// \t});\n\t\t// \tlayout.$element.append(this['fieldset-' + directive].$element);\n\t\t// }\n\n\t\tthis.booklet = new OO.ui.BookletLayout({\n\t\t\toutlined: false,\n\t\t\texpanded: true,\n\t\t\tpadded: false,\n\t\t\tclasses: [\"VisualDataGroupWidgetBooklet\"],\n\t\t});\n\n\t\tlayout.$element.append(this.booklet.$element);\n\n\t\t*/\n\n\t\tthis.$element.append( layout.$element );\n\t};\n\n\tOO.inheritClass( GroupWidget, OO.ui.Widget );\n\tOO.mixinClass( GroupWidget, OO.ui.mixin.GroupWidget );\n\t// OO.mixinClass( GroupWidget, OO.EventEmitter );\n\n\tGroupWidget.prototype.formLoaded = function () {\n\t\tvar self = this;\n\t\tsetTimeout( function () {\n\t\t\tVisualDataFunctions.removeNbspFromLayoutHeader( 'form' );\n\t\t}, 30 );\n\n\t\tsetTimeout( function () {\n\t\t\tVisualDataFunctions.removeNbspFromLayoutHeader(\n\t\t\t\t'#visualdataform-wrapper-dialog-' + FormID\n\t\t\t);\n\t\t}, 30 );\n\n\t\tvar schemaName = self.data.model.schemaName;\n\n\t\tsetTimeout( function () {\n\t\t\tonMutationChange( schemaName, self.data.rootEl.get( 0 ) );\n\t\t}, 30 );\n\n\t\tfor ( var model of ModelFlatten ) {\n\t\t\tif ( model.schemaName === schemaName ) {\n\t\t\t\tupdateDependentFields( model );\n\t\t\t}\n\t\t}\n\n\t\tsetTimeout( function () {\n\t\t\tinitForms( false );\n\t\t}, 30 );\n\t};\n\n\tGroupWidget.prototype.addItems = function ( items ) {\n\t\tif ( this.data.schema.wiki.layout === 'horizontal' ) {\n\t\t\tthis.layoutHorizontal.addItems( items );\n\t\t} else {\n\t\t\tthis.fieldset.addItems( items );\n\t\t}\n\t};\n\n\tGroupWidget.prototype.addCombinedItem = function ( item, title, directive ) {\n\t\t// this['fieldset-' + directive].addItems(items);\n\n\t\tvar items = [\n\t\t\tnew OO.ui.ButtonOptionWidget( {\n\t\t\t\tdata: title,\n\t\t\t\tlabel: title\n\t\t\t} )\n\t\t];\n\t\tthis.buttonSelectWidget.addItems( items );\n\n\t\t//\tthis['fieldset-' + directive]..addItems(items);\n\n\t\tif ( this.buttonSelectWidget.items.length === 1 ) {\n\t\t\tthis.buttonSelectWidget.selectItem( items[ 0 ] );\n\t\t}\n\n\t\tvar ThisPageLayout = function ( name, config ) {\n\t\t\tThisPageLayout.super.call( this, name, config );\n\t\t\tthis.$element.append( item.$element );\n\t\t};\n\t\tOO.inheritClass( ThisPageLayout, OO.ui.PageLayout );\n\n\t\tvar page = new ThisPageLayout( title );\n\n\t\tthis.booklet.addPages( [ page ] );\n\t};\n\n\tfunction PanelLayout( config ) {\n\t\tPanelLayout.super.call( this, config );\n\n\t\tvar data = this.data;\n\t\tvar content;\n\n\t\tif ( !( 'layout' in Form.options ) ) {\n\t\t\tForm.options.layout = 'tabs';\n\t\t}\n\n\t\t// @TODO implement booklet also outside dialog\n\t\tif ( Form.options.layout === 'booklet' && Form.options.view !== 'popup' && Form.options.view !== 'button' ) {\n\t\t\tForm.options.layout = 'tabs';\n\t\t}\n\n\t\tfunction getWidgets() {\n\t\t\tMaps = [];\n\t\t\tPendingRecursive = 0;\n\t\t\tQueuedWidgets = {};\n\t\t\tvar ret = {};\n\n\t\t\tfor ( var schemaName_ of Form.schemas ) {\n\t\t\t\tQueuedWidgets[ schemaName_ ] = [];\n\t\t\t\tvar schema = Schemas[ schemaName_ ];\n\n\t\t\t\tvar previousSchema =\n\t\t\t\t\tschemaName_ in PreviousSchemas ?\n\t\t\t\t\t\tPreviousSchemas[ schemaName_ ] :\n\t\t\t\t\t\t{};\n\n\t\t\t\tif ( !( schemaName_ in Form.jsonData.schemas ) ) {\n\t\t\t\t\tForm.jsonData.schemas[ schemaName_ ] = {};\n\t\t\t\t}\n\n\t\t\t\tvar path = `${ escapeJsonPointer( schemaName_ ) }`;\n\t\t\t\tvar pathNoIndex = '';\n\t\t\t\tvar model = ( ModelSchemas[ schemaName_ ] = {\n\t\t\t\t\tparent: ModelSchemas,\n\t\t\t\t\tchildIndex: schemaName_,\n\t\t\t\t\tparentSchema: null\n\t\t\t\t} );\n\t\t\t\tvar widget = new GroupWidget(\n\t\t\t\t\t{},\n\t\t\t\t\t{ root: true, schema, path, model }\n\t\t\t\t);\n\n\t\t\t\tprocessSchema(\n\t\t\t\t\twidget,\n\t\t\t\t\tschema,\n\t\t\t\t\tpreviousSchema,\n\t\t\t\t\tschemaName_,\n\t\t\t\t\tmodel,\n\t\t\t\t\tForm.jsonData.schemas[ schemaName_ ],\n\t\t\t\t\tpath,\n\t\t\t\t\tpathNoIndex,\n\t\t\t\t\tfalse\n\t\t\t\t);\n\n\t\t\t\tret[ schemaName_ ] = widget;\n\t\t\t}\n\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction getFreeTextInput( wikitext, thisConfig ) {\n\t\t\tvar thisInputWidget;\n\n\t\t\tthisConfig = $.extend(\n\t\t\t\t{\n\t\t\t\t\tname: `${ FormID }-model-freetext`,\n\t\t\t\t\tid: `${ FormID }-model-freetext`\n\t\t\t\t},\n\t\t\t\tthisConfig\n\t\t\t);\n\n\t\t\tif ( !wikitext || !Config.VEForAll ) {\n\t\t\t\tthisInputWidget = new OO.ui.MultilineTextInputWidget(\n\t\t\t\t\t$.extend(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tautosize: true,\n\t\t\t\t\t\t\trows: 6\n\t\t\t\t\t\t},\n\t\t\t\t\t\tthisConfig\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tthisInputWidget = new VisualDataVisualEditor( thisConfig );\n\t\t\t}\n\t\t\tModel.freetext = thisInputWidget;\n\t\t\tInputWidgets[ thisConfig.name ] = thisInputWidget;\n\t\t\treturn thisInputWidget;\n\t\t}\n\n\t\tswitch ( data.name ) {\n\t\t\tcase 'schemas':\n\t\t\t\tif ( !( 'schemas' in Form.jsonData ) ) {\n\t\t\t\t\tForm.jsonData.schemas = {};\n\t\t\t\t}\n\n\t\t\t\tfor ( var thisSchemaName of Form.schemas ) {\n\t\t\t\t\tif ( !( thisSchemaName in Schemas ) ) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.error( \"required schema doesn't exist\", thisSchemaName );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tForm.schemas = Form.schemas.filter( ( x ) => x in Schemas );\n\n\t\t\t\tif ( !SelectedSchema || !Form.schemas.includes( SelectedSchema ) ) {\n\t\t\t\t\t// @credits https://gerrit.wikimedia.org/r/c/mediawiki/extensions/VisualData/+/1034934\n\t\t\t\t\tif ( 'selected-schema' in Form.options &&\n\t\t\t\t\t\tForm.options[ 'selected-schema' ] !== '' &&\n\t\t\t\t\t\tinArray( Form.options[ 'selected-schema' ], Form.schemas )\n\t\t\t\t\t) {\n\t\t\t\t\t\tSelectedSchema = Form.options[ 'selected-schema' ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tSelectedSchema = ( Form.schemas.length ? Form.schemas[ 0 ] : null );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar layout = Form.options.layout;\n\t\t\t\tvar widgets = getWidgets();\n\n\t\t\t\tif ( !SelectedSchema ) {\n\t\t\t\t\tthis.isEmpty = true;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tvar ThisPageLayout = function ( name, thisConfig ) {\n\t\t\t\t\tThisPageLayout.super.call( this, name, thisConfig );\n\t\t\t\t};\n\n\t\t\t\tOO.inheritClass( ThisPageLayout, OO.ui.PageLayout );\n\n\t\t\t\tThisPageLayout.prototype.setupOutlineItem = function () {\n\t\t\t\t\tthis.outlineItem.setLabel( this.name );\n\t\t\t\t};\n\n\t\t\t\tvar ThisTabPanelLayout = function ( name, thisConfig ) {\n\t\t\t\t\tthis.name = name;\n\t\t\t\t\tThisTabPanelLayout.super.call( this, name, thisConfig );\n\t\t\t\t};\n\n\t\t\t\tOO.inheritClass( ThisTabPanelLayout, OO.ui.TabPanelLayout );\n\t\t\t\tThisTabPanelLayout.prototype.setupTabItem = function () {\n\t\t\t\t\tthis.tabItem.setLabel( this.name );\n\n\t\t\t\t\tthis.deleteButton = new OO.ui.ButtonWidget( {\n\t\t\t\t\t\ticon: 'close',\n\t\t\t\t\t\tframed: false,\n\t\t\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-delete-schema' ),\n\t\t\t\t\t\tinvisibleLabel: true,\n\t\t\t\t\t\tclasses: [ 'VisualDataTabPanelLayoutTabItemDeleteButton' ]\n\t\t\t\t\t} );\n\n\t\t\t\t\tthis.deleteButton.on( 'click', function () {\n\t\t\t\t\t\tForm.schemas.splice( Form.schemas.indexOf( this.name ), 1 );\n\t\t\t\t\t\t// delete Form.jsonData.schemas[ data.schema.wiki.name ];\n\t\t\t\t\t\tdelete ModelSchemas[ this.name ];\n\t\t\t\t\t\tdelete Fields[ this.name ];\n\t\t\t\t\t\tupdatePanels();\n\t\t\t\t\t} );\n\n\t\t\t\t\tthis.deleteButton.toggle( this.name === SelectedSchema );\n\t\t\t\t\t// @TODO\n\t\t\t\t\t// this.tabItem.$label.append( this.deleteButton.$element );\n\t\t\t\t};\n\n\t\t\t\tThisTabPanelLayout.prototype.toggleCloseButton = function () {\n\t\t\t\t};\n\n\t\t\t\tswitch ( layout ) {\n\t\t\t\t\tcase 'single':\n\t\t\t\t\t\tcontent = widgets[ SelectedSchema ];\n\t\t\t\t\t\tthis.$element.addClass( 'PanelPropertiesStackPanelSingle' );\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'booklet':\n\t\t\t\t\t\tvar booklet = new OO.ui.BookletLayout( {\n\t\t\t\t\t\t\toutlined: true,\n\t\t\t\t\t\t\texpanded: true,\n\t\t\t\t\t\t\tpadded: false\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t// booklet.on( 'set', function () {\n\t\t\t\t\t\t// \tonTabSelect( booklet.getCurrentPageName() );\n\t\t\t\t\t\t// } );\n\n\t\t\t\t\t\tSchemasLayout = booklet;\n\n\t\t\t\t\t\tvar items = [];\n\n\t\t\t\t\t\tfor ( var schemaName in widgets ) {\n\t\t\t\t\t\t\tvar tabPanel = new ThisPageLayout( schemaName );\n\t\t\t\t\t\t\ttabPanel.$element.append( widgets[ schemaName ].$element );\n\t\t\t\t\t\t\titems.push( tabPanel );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbooklet.addPages( items );\n\t\t\t\t\t\tcontent = booklet;\n\t\t\t\t\t\tbooklet.setPage( SelectedSchema );\n\n\t\t\t\t\t\tthis.$element.addClass( 'PanelPropertiesStackPanelBooklet' );\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'tabs':\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvar indexLayout = new OO.ui.IndexLayout( {\n\t\t\t\t\t\t\tframed: true,\n\t\t\t\t\t\t\tshowMenu: false,\n\t\t\t\t\t\t\texpanded: true,\n\t\t\t\t\t\t\tpadded: false,\n\t\t\t\t\t\t\tautoFocus: false\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\tSchemasLayout = indexLayout;\n\n\t\t\t\t\t\t// indexLayout.on( 'set', function () {\n\t\t\t\t\t\t// \tonTabSelect( indexLayout.getCurrentTabPanelName() );\n\t\t\t\t\t\t// } );\n\n\t\t\t\t\t\tvar items = [];\n\t\t\t\t\t\tfor ( var schemaName in widgets ) {\n\t\t\t\t\t\t\tvar tabPanel = new ThisTabPanelLayout( schemaName );\n\t\t\t\t\t\t\ttabPanel.$element.append( widgets[ schemaName ].$element );\n\t\t\t\t\t\t\titems.push( tabPanel );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tindexLayout.addTabPanels( items );\n\t\t\t\t\t\tindexLayout.setTabPanel( SelectedSchema );\n\t\t\t\t\t\tcontent = indexLayout;\n\n\t\t\t\t\t\tthis.$element.addClass( 'PanelPropertiesStackPanelTabs' );\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'article':\n\t\t\t\tvar items = [];\n\t\t\t\tvar userDefinedInput;\n\t\t\t\tvar userDefinedField;\n\t\t\t\tvar freeTextField;\n\t\t\t\tvar categoriesField;\n\t\t\t\tvar contentModelField;\n\n\t\t\t\tif ( data.userDefined ) {\n\t\t\t\t\tvar inputName = 'mw.widgets.TitleInputWidget';\n\n\t\t\t\t\tuserDefinedInput = new mw.widgets.TitleInputWidget( {\n\t\t\t\t\t\tname: `${ FormID }-model-target-title`,\n\t\t\t\t\t\tvalue: !( 'userDefined' in Form ) ? '' : Form.userDefined,\n\t\t\t\t\t\t// @FIXME if the stack panel is hidden\n\t\t\t\t\t\t// this will create a browser error\n\t\t\t\t\t\trequired: true\n\t\t\t\t\t} );\n\n\t\t\t\t\tModel[ 'target-title' ] = userDefinedInput;\n\n\t\t\t\t\tuserDefinedField = new OO.ui.FieldLayout( userDefinedInput, {\n\t\t\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-pagename' ),\n\t\t\t\t\t\talign: data.fieldAlign\n\t\t\t\t\t\t// classes: [\"ItemWidget\", \"inputName-\" + inputName],\n\t\t\t\t\t} );\n\t\t\t\t\titems.push( userDefinedField );\n\t\t\t\t}\n\n\t\t\t\tif ( data.editTargetSlot ) {\n\t\t\t\t\tvar targetSlotInput = new OO.ui.DropdownInputWidget( {\n\t\t\t\t\t\tname: `${ FormID }-model-target-slot`,\n\t\t\t\t\t\toptions: VisualDataFunctions.createDropDownOptions( {\n\t\t\t\t\t\t\tjsondata: mw.msg( 'visualdata-jsmodule-forms-target-slot-option-jsondata' ),\n\t\t\t\t\t\t\tmain: mw.msg( 'visualdata-jsmodule-forms-target-slot-option-main' )\n\t\t\t\t\t\t} ),\n\t\t\t\t\t\tvalue: Form.options[ 'target-slot' ]\n\t\t\t\t\t} );\n\n\t\t\t\t\tModel[ 'target-slot' ] = targetSlotInput;\n\n\t\t\t\t\ttargetSlotInput.on( 'change', function ( value ) {\n\t\t\t\t\t\tif ( freeTextField ) {\n\t\t\t\t\t\t\tfreeTextField.toggle( value !== 'main' );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( contentModelField ) {\n\t\t\t\t\t\t\tcontentModelField.toggle( value !== 'main' );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t\tTargetSlotField = new OO.ui.FieldLayout( targetSlotInput, {\n\t\t\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-target-slot' ),\n\t\t\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-forms-target-slot-help' ),\n\t\t\t\t\t\thelpInline: true,\n\t\t\t\t\t\talign: data.fieldAlign\n\t\t\t\t\t} );\n\n\t\t\t\t\t// TargetSlotField.toggle( false );\n\n\t\t\t\t\titems.push( TargetSlotField );\n\t\t\t\t}\n\n\t\t\t\tif ( data.editFreeText ) {\n\t\t\t\t\tvar inputWidget = getFreeTextInput( data.contentModel === 'wikitext', {\n\t\t\t\t\t\tvalue: Form.freetext,\n\t\t\t\t\t\t// @FIXME this could be removed\n\t\t\t\t\t\tcontentModel: data.contentModel\n\t\t\t\t\t} );\n\n\t\t\t\t\tfreeTextField = new OO.ui.FieldLayout( inputWidget, {\n\t\t\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-freetext' ),\n\t\t\t\t\t\talign: data.fieldAlign\n\t\t\t\t\t} );\n\n\t\t\t\t\tfreeTextField.toggle( Form.options[ 'target-slot' ] !== 'main' );\n\n\t\t\t\t\titems.push( freeTextField );\n\t\t\t\t}\n\n\t\t\t\tif ( data.editCategories ) {\n\t\t\t\t\tvar categories = data.categories;\n\n\t\t\t\t\tvar categoriesInput = new mw.widgets.CategoryMultiselectWidget( {\n\t\t\t\t\t\tname: `${ FormID }-model-categories`\n\t\t\t\t\t\t// value: categories,\n\t\t\t\t\t} );\n\n\t\t\t\t\tModel.categories = categoriesInput;\n\n\t\t\t\t\t// ***prevents error \"Cannot read properties of undefined (reading 'apiUrl')\"\n\t\t\t\t\tfor ( var category of categories ) {\n\t\t\t\t\t\tcategoriesInput.addTag( category );\n\t\t\t\t\t}\n\n\t\t\t\t\tcategoriesField = new OO.ui.FieldLayout( categoriesInput, {\n\t\t\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-categories' ),\n\t\t\t\t\t\talign: data.fieldAlign,\n\t\t\t\t\t\tclasses: [ 'VisualDataItemWidget' ]\n\t\t\t\t\t} );\n\n\t\t\t\t\titems.push( categoriesField );\n\t\t\t\t}\n\n\t\t\t\tif ( data.editContentModel ) {\n\t\t\t\t\tvar contentModelInput = new OO.ui.DropdownInputWidget( {\n\t\t\t\t\t\tname: `${ FormID }-model-content-model`,\n\t\t\t\t\t\toptions: VisualDataFunctions.createDropDownOptions(\n\t\t\t\t\t\t\tConfig.contentModels\n\t\t\t\t\t\t),\n\t\t\t\t\t\tvalue: data.contentModel\n\t\t\t\t\t} );\n\n\t\t\t\t\tcontentModelInput.on( 'change', async function ( value ) {\n\t\t\t\t\t\tif ( !( 'freetext' in Model ) ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar thisInputWidget;\n\t\t\t\t\t\tvar freetextValue = Model.freetext.getValue();\n\n\t\t\t\t\t\tif ( VisualDataFunctions.isPromise( freetextValue ) ) {\n\t\t\t\t\t\t\tfreetextValue = await freetextValue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// @TODO convert from/to html and wikitext\n\t\t\t\t\t\t// value === \"html\" ||\n\t\t\t\t\t\tif ( value === 'wikitext' ) {\n\t\t\t\t\t\t\tthisInputWidget = getFreeTextInput( true, {\n\t\t\t\t\t\t\t\t// @FIXME this could be removed\n\t\t\t\t\t\t\t\tcontentModel: value,\n\t\t\t\t\t\t\t\tvalue: freetextValue\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t// *** this is not caught by the mutation\n\t\t\t\t\t\t\tsetTimeout( function () {\n\t\t\t\t\t\t\t\tshowLazyWidget( 'VisualDataVisualEditor' );\n\t\t\t\t\t\t\t}, 50 );\n\n\t\t\t\t\t\t// @TODO use TinyMCE for html\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthisInputWidget = getFreeTextInput( false, {\n\t\t\t\t\t\t\t\tvalue: freetextValue\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$( `#${ FormID }-model-freetext` ).replaceWith( thisInputWidget.$element );\n\t\t\t\t\t} );\n\n\t\t\t\t\tModel[ 'content-model' ] = contentModelInput;\n\n\t\t\t\t\tcontentModelField = new OO.ui.FieldLayout( contentModelInput, {\n\t\t\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-content-models' ),\n\t\t\t\t\t\talign: data.fieldAlign,\n\t\t\t\t\t\tclasses: [ 'VisualDataItemWidget' ]\n\t\t\t\t\t} );\n\n\t\t\t\t\tcontentModelField.toggle( Form.options[ 'target-slot' ] !== 'main' );\n\n\t\t\t\t\titems.push( contentModelField );\n\t\t\t\t}\n\n\t\t\t\tif ( !items.length ) {\n\t\t\t\t\tthis.isEmpty = true;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tthis.$element.addClass( 'PanelPropertiesStackPanelFieldset' );\n\n\t\t\t\tcontent = new OO.ui.FieldsetLayout( {\n\t\t\t\t\tlabel: '',\n\t\t\t\t\titems: items\n\t\t\t\t} );\n\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\tshowLazyWidget( 'VisualDataVisualEditor' );\n\t\t\t\t}, 50 );\n\t\t}\n\n\t\tthis.isEmpty = false;\n\t\tthis.$element.append( content.$element );\n\t}\n\n\tOO.inheritClass( PanelLayout, OO.ui.PanelLayout );\n\n\tvar OptionsList = function ListWidget( config, schema, model ) {\n\t\tconfig = config || {};\n\t\tvar self = this;\n\n\t\t// Call parent constructor\n\t\tOptionsList.super.call( this, config );\n\n\t\tOO.ui.mixin.GroupWidget.call(\n\t\t\tthis,\n\t\t\t$.extend(\n\t\t\t\t{\n\t\t\t\t\t$group: this.$element\n\t\t\t\t},\n\t\t\t\tconfig\n\t\t\t)\n\t\t);\n\n\t\tthis.schema = schema;\n\t\tthis.model = model;\n\n\t\tthis.recDeleteValue = function ( thisModel ) {\n\t\t\tswitch ( thisModel.schema.type ) {\n\t\t\t\tcase 'object':\n\t\t\t\t\tif ( 'properties' in thisModel ) {\n\t\t\t\t\t\tfor ( var ii in thisModel.properties ) {\n\t\t\t\t\t\t\tself.recDeleteValue( thisModel.properties[ ii ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t// @TODO implement tuple\n\t\t\t\t\tif ( VisualDataFunctions.isObject( schema.items ) ) {\n\t\t\t\t\t\tself.recDeleteValue( thisModel.items );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif ( 'input' in thisModel ) {\n\t\t\t\t\t\tthisModel.input.setValue( !thisModel.multiselect ? '' : [] );\n\t\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tthis.aggregate( {\n\t\t\tdelete: 'itemDelete'\n\t\t} );\n\n\t\tthis.connect( this, {\n\t\t\titemDelete: 'onItemDelete'\n\t\t} );\n\n\t\tthis.connect( this, {\n\t\t\tadd: 'onAddItem'\n\t\t} );\n\t};\n\n\tOO.inheritClass( OptionsList, OO.ui.Widget );\n\tOO.mixinClass( OptionsList, OO.ui.mixin.GroupWidget );\n\n\tOptionsList.prototype.onAddItem = function () {};\n\n\tOptionsList.prototype.onItemDelete = function () {};\n\n\t// OptionsList.prototype.addItems = function (items) {\n\t// \tfor ( var i in items ) {\n\t// \t\tOO.ui.mixin.GroupWidget.prototype.addItem.call(this, items[i], i);\n\t// \t}\n\t// }\n\n\tOptionsList.prototype.addItem = function ( item, i ) {\n\t\tvar self = this;\n\t\titem.data.index = i;\n\n\t\tif ( item.data.schema.wiki.layout === 'section' ) {\n\t\t\tvar deleteButton = new OO.ui.ButtonWidget( {\n\t\t\t\ticon: 'close'\n\t\t\t\t// flags: [\"destructive\"],\n\t\t\t\t// classes: [\"VisualDataOptionsListDeleteButton\"],\n\t\t\t} );\n\n\t\t\tdeleteButton.on( 'click', function () {\n\t\t\t\tself.removeItem( item );\n\t\t\t} );\n\n\t\t\titem.$element.prepend(\n\t\t\t\t$( '<div style=\"text-align:right\">' ).append( deleteButton.$element )\n\t\t\t);\n\t\t}\n\n\t\tOO.ui.mixin.GroupWidget.prototype.addItems.call( this, [ item ] );\n\n\t\tthis.emit( 'add', item );\n\n\t\treturn this;\n\t};\n\n\tOptionsList.prototype.removeItem = function ( item ) {\n\t\tvar self = this;\n\n\t\tif (\n\t\t\t!( 'minItems' in self.schema ) ||\n\t\t\tself.items.length > self.schema.minItems\n\t\t) {\n\t\t\t// *** rather than removing the item\n\t\t\t// from the model, we mark it as removed\n\t\t\t// this ensures consistency of the data\n\t\t\t// structure, the items marked as removed\n\t\t\t// will be removed from submitted data.\n\t\t\t// Both the 2 alternate methods aren't\n\t\t\t// optimal: updatePanels() is too expensive\n\t\t\t// and renaming all the data structure\n\t\t\t// is too tricky and leads to errors\n\t\t\tself.removeItems( [ item ] );\n\t\t\tself.model[ item.data.index ].removed = true;\n\n\t\t} else {\n\t\t\tself.recDeleteValue( self.model[ item.data.index ] );\n\t\t}\n\n\t\treturn this;\n\t};\n\n\tOptionsList.prototype.removeItems = function ( items ) {\n\t\tOO.ui.mixin.GroupWidget.prototype.removeItems.call( this, items );\n\t\tthis.emit( 'remove', items );\n\t\treturn this;\n\t};\n\n\tOptionsList.prototype.clearItems = function () {\n\t\tvar items = this.items.slice();\n\t\tOO.ui.mixin.GroupWidget.prototype.clearItems.call( this );\n\t\tthis.emit( 'remove', items );\n\t\treturn this;\n\t};\n\n\tfunction schemaHasData( schemaName ) {\n\t\treturn VisualDataFunctions.getNestedProp( [ 'schemas', schemaName ], StoredJsonData ) &&\n\t\t\tObject.keys( StoredJsonData.schemas[ schemaName ] ).length;\n\t}\n\n\t// @FIXME store for each separate schema\n\tfunction applyUntransformed( data, i, path ) {\n\t\tif (\n\t\t\t!( 'schemas-data' in Form.jsonData ) ||\n\t\t\t!( 'untransformed' in Form.jsonData[ 'schemas-data' ] ) ||\n\t\t\t!( path in Form.jsonData[ 'schemas-data' ].untransformed )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// *** this ensures subsequent edits are maintained\n\t\tdata[ i ] = Form.jsonData[ 'schemas-data' ].untransformed[ path ];\n\t\tdelete Form.jsonData[ 'schemas-data' ].untransformed[ path ];\n\t}\n\n\tvar OptionsListContainer = function OptionsListContainer(\n\t\tconfig,\n\t\tschema,\n\t\titem,\n\t\tpreviousItem,\n\t\tschemaName,\n\t\tmodel,\n\t\tdata,\n\t\tpath,\n\t\tpathNoIndex,\n\t\tnewItem\n\t) {\n\t\tconfig = config || {};\n\t\tvar self = this;\n\n\t\t// Call parent constructor\n\t\tOptionsListContainer.super.call( this, config );\n\n\t\t// display multiselect\n\t\tif (\n\t\t\titem.type !== 'object' &&\n\t\t\t'preferred-input' in item.wiki &&\n\t\t\tVisualDataFunctions.isMultiselect( item.wiki[ 'preferred-input' ] )\n\t\t) {\n\t\t\tvar widget_ = new GroupWidget( {}, { schema: item, path, model } );\n\t\t\tprocessSchema(\n\t\t\t\twidget_,\n\t\t\t\titem,\n\t\t\t\tpreviousItem,\n\t\t\t\tschemaName,\n\t\t\t\tmodel,\n\t\t\t\tdata,\n\t\t\t\tpath,\n\t\t\t\tpathNoIndex,\n\t\t\t\tnewItem\n\t\t\t);\n\t\t\tthis.$element.append( widget_.$element );\n\t\t\treturn;\n\t\t}\n\n\t\tthis.optionsList = new OptionsList( {}, schema, model );\n\n\t\tvar minItems = 'minItems' in schema ? schema.minItems : 0;\n\t\tvar data;\n\t\tif (\n\t\t\tArray.isArray( item.default ) &&\n\t\t\t( !Array.isArray( data ) || !data.length ) &&\n\t\t\t( isNewSchema( schemaName ) || Form.emptyData )\n\t\t) {\n\t\t\tdata = item.default;\n\t\t}\n\n\t\tif ( Array.isArray( data ) && minItems < data.length ) {\n\t\t\tminItems = data.length;\n\t\t}\n\n\t\t// data is not an object if the type of schema\n\t\t// changed from non object to object, e.g.\n\t\t// an array of text fields vs an array\n\t\t// of subitems, and the name/key was the same\n\t\tif ( data === null || typeof data !== 'object' ) {\n\t\t\tdata = {};\n\t\t}\n\n\t\tvar i = 0;\n\t\twhile ( this.optionsList.items.length < minItems ) {\n\t\t\tvar newItem = false;\n\t\t\tif ( !( i in data ) ) {\n\t\t\t\tdata[ i ] = {};\n\t\t\t\tnewItem = true;\n\t\t\t}\n\t\t\tvar path_ = `${ path }/${ i }`;\n\t\t\tapplyUntransformed( data, i, path_ );\n\t\t\tvar thisModel = ( model[ i ] = {\n\t\t\t\tparent: model,\n\t\t\t\tchildIndex: i,\n\t\t\t\tparentSchema: schema\n\t\t\t} );\n\t\t\tvar widget_ = new GroupWidget( {}, { isObjectList: true, schema: item, path: path_, model: thisModel } );\n\n\t\t\tprocessSchema(\n\t\t\t\twidget_,\n\t\t\t\titem,\n\t\t\t\tpreviousItem,\n\t\t\t\tschemaName,\n\t\t\t\tthisModel,\n\t\t\t\tdata[ i ],\n\t\t\t\tpath_,\n\t\t\t\tpathNoIndex,\n\t\t\t\tnewItem,\n\t\t\t\tthis.optionsList\n\t\t\t);\n\t\t\tthis.optionsList.addItem( widget_, i );\n\t\t\ti++;\n\t\t}\n\n\t\tvar addOption = new OO.ui.ButtonWidget( {\n\t\t\ticon: 'add'\n\t\t} );\n\n\t\taddOption.on( 'click', function () {\n\t\t\tif (\n\t\t\t\t!( 'maxItems' in schema ) ||\n\t\t\t\tself.optionsList.items.length < schema.maxItems\n\t\t\t) {\n\t\t\t\tvar ii = self.optionsList.items.length ?\n\t\t\t\t\tself.optionsList.items[ self.optionsList.items.length - 1 ].data\n\t\t\t\t\t\t.index + 1 :\n\t\t\t\t\t0;\n\t\t\t\tvar modelAddOption = ( model[ ii ] = {\n\t\t\t\t\tparent: model,\n\t\t\t\t\tchildIndex: ii,\n\t\t\t\t\tparentSchema: schema\n\t\t\t\t} );\n\n\t\t\t\tvar widgetAddOption = new GroupWidget( {}, { isObjectList: true, schema: item, path, model: modelAddOption } );\n\n\t\t\t\tvar thisPath_ = `${ path }/${ ii }`;\n\t\t\t\tprocessSchema(\n\t\t\t\t\twidgetAddOption,\n\t\t\t\t\titem,\n\t\t\t\t\tpreviousItem,\n\t\t\t\t\tschemaName,\n\t\t\t\t\tmodelAddOption,\n\t\t\t\t\t( data[ ii ] = {} ),\n\t\t\t\t\tthisPath_,\n\t\t\t\t\tpathNoIndex,\n\t\t\t\t\ttrue,\n\t\t\t\t\tself.optionsList\n\t\t\t\t);\n\n\t\t\t\tself.optionsList.addItem( widgetAddOption, ii );\n\t\t\t}\n\t\t} );\n\n\t\tfunction reorderInputs( inputs, oldIndex, newIndex ) {\n\t\t\tconst entries = VisualDataFunctions.objectEntries( inputs );\n\n\t\t\t// remove the old item and get it\n\t\t\tconst thisItem = entries.splice( oldIndex, 1 )[ 0 ];\n\n\t\t\t// insert item at new position\n\t\t\tentries.splice( newIndex, 0, thisItem );\n\n\t\t\t// clear existing keys\n\t\t\tObject.keys( inputs ).forEach( ( key ) => delete inputs[ key ] );\n\n\t\t\t// Repopulate with new order, keeping same reference\n\t\t\tentries.forEach( ( [ _, value ], index ) => {\n\t\t\t\tinputs[ index ] = value;\n\t\t\t} );\n\t\t}\n\n\t\tSortable.create( this.optionsList.$element.get( 0 ), {\n\t\t\thandle: '.visualdata-input-widget-move',\n\t\t\tdirection: 'vertical',\n\t\t\tonEnd: function ( evt ) {\n\t\t\t\treorderInputs( model, evt.oldIndex, evt.newIndex );\n\t\t\t}\n\t\t} );\n\n\t\tthis.$element.append( this.optionsList.$element );\n\t\tthis.$element.append( addOption.$element );\n\t};\n\n\tOO.inheritClass( OptionsListContainer, OO.ui.Widget );\n\t// OO.mixinClass(OptionsListContainer, OO.ui.mixin.GroupWidget);\n\n\tfunction updateDefaultValue( model ) {\n\t\tif ( !VisualDataFunctions.getNestedProp(\n\t\t\t[ 'schema', 'wiki', 'default' ],\n\t\t\tmodel\n\t\t) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tProcessModel.getValue( model ).then( function ( res ) {\n\t\t\tif ( VisualDataFunctions.isEmpty( res ) &&\n\t\t\t\tmodel.schema.wiki.required &&\n\t\t\t\t!VisualDataFunctions.isEmpty( model.schema.wiki.default )\n\t\t\t) {\n\t\t\t\tmodel.input.setValue( model.schema.wiki.default );\n\t\t\t}\n\t\t} ).catch( ( err ) => {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.error( err );\n\t\t} );\n\t}\n\n\tfunction determineInputValue(\n\t\tschema,\n\t\tpreviousSchema,\n\t\tschemaName,\n\t\tmodel,\n\t\tdata,\n\t\tnewItem\n\t) {\n\t\t// can be an array, in case of multiselect\n\t\tvar ret = VisualDataFunctions.isObject( data ) ? null : data;\n\t\t// remove value-prefix\n\t\t// ***this is not necessary, since is handled\n\t\t// by applyUntransformed\n\t\t// if (defaultValue) {\n\t\t// \tif (\"value-prefix\" in schema.wiki) {\n\t\t// \t\tvar prefixLength = schema.wiki[\"value-prefix\"].length;\n\t\t// \t\tif (Array.isArray(defaultValue)) {\n\t\t// \t\t\tdefaultValue = value.map((x) => x.substr(prefixLength));\n\t\t// \t\t} else {\n\t\t// \t\t\tdefaultValue = defaultValue.substr(prefixLength);\n\t\t// \t\t}\n\t\t// \t}\n\t\t// }\n\n\t\tif ( !( 'default' in schema ) ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\t// @FIXME schema.default may be returned\n\t\t// immediately ?\n\t\tvar requiredDefaultWithEmptyValue = VisualDataFunctions.isEmpty( data ) &&\n\t\t\tschema.wiki.required &&\n\t\t\t!VisualDataFunctions.isEmpty( schema.default );\n\n\t\t// possibly return schema.default (bypass this)\n\t\t// if is a new item, or is a new schema,\n\t\t// or there are not data entered through\n\t\t// the form in the form\n\t\tif (\n\t\t\t!newItem &&\n\t\t\t!isNewSchema( schemaName ) &&\n\t\t\t!Form.emptyData &&\n\t\t\t!requiredDefaultWithEmptyValue\n\t\t) {\n\t\t\treturn ret;\n\t\t}\n\n\t\t// possibly return schema.default (bypass this)\n\t\t// if ret is null or is equal to the default value\n\t\t// of previousSchema\n\t\tif (\n\t\t\tret !== null &&\n\t\t\t( !( 'default' in previousSchema ) || ret !== previousSchema.default )\n\t\t) {\n\t\t\treturn ret;\n\t\t}\n\n\t\t// possibly return schema.default (bypass this)\n\t\t// if the default value is not an array\n\t\t// or the preferred input is not a multiselect\n\t\t// (the respective entries by OptionsListContainer)\n\t\tif (\n\t\t\tArray.isArray( schema.default ) &&\n\t\t\t\t(\n\t\t\t\t\t!( 'preferred-input' in schema.wiki ) ||\n\t\t\t\t\t!VisualDataFunctions.isMultiselect( schema.wiki[ 'preferred-input' ] )\n\t\t\t\t)\n\t\t) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn schema.default;\n\t}\n\n\tfunction processSchema(\n\t\twidget,\n\t\tschema,\n\t\tpreviousSchema,\n\t\tschemaName,\n\t\tmodel,\n\t\tdata,\n\t\tpath,\n\t\tpathNoIndex,\n\t\tnewItem,\n\t\toptionsList\n\t) {\n\t\tif ( typeof optionsList === 'undefined' ) {\n\t\t\toptionsList = null;\n\t\t}\n\n\t\tQueuedWidgets[ schemaName ].push( widget );\n\t\tPendingRecursive++;\n\n\t\tif ( !( 'type' in schema ) ) {\n\t\t\tschema.type = 'default' in schema ? 'string' : 'object';\n\t\t}\n\t\t// model.previousSchema = previousSchema;\n\n\t\tmodel.schema = VisualDataFunctions.deepCopy( schema );\n\t\tmodel.schemaName = schemaName;\n\t\tmodel.path = path;\n\t\tmodel.pathNoIndex = pathNoIndex;\n\t\t// @TODO implement allOf, anyOf, oneOf using addCombinedItem\n\t\t// @TODO implement \"$ref\"\n\n\t\tswitch ( schema.type ) {\n\t\t\tcase 'object':\n\t\t\t\tmodel.properties = {};\n\t\t\t\tif ( 'properties' in schema ) {\n\n\t\t\t\t\t// data is not an object if the type of schema\n\t\t\t\t\t// changed from non object to object, e.g.\n\t\t\t\t\t// an array of text fields vs an array\n\t\t\t\t\t// of subitems, and the name/key was the same\n\t\t\t\t\tif ( !VisualDataFunctions.isObject( data ) ) {\n\t\t\t\t\t\tdata = {};\n\t\t\t\t\t}\n\n\t\t\t\t\tvar items_ = [];\n\t\t\t\t\tfor ( var i in schema.properties ) {\n\t\t\t\t\t\tif ( !( i in data ) ) {\n\t\t\t\t\t\t\tdata[ i ] = {};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar path_ = `${ path }/${ escapeJsonPointer( i ) }`;\n\t\t\t\t\t\tapplyUntransformed( data, i, path_ );\n\t\t\t\t\t\tvar pathNoIndex_ = pathNoIndex ?\n\t\t\t\t\t\t\t`${ pathNoIndex }/${ escapeJsonPointer( i ) }` :\n\t\t\t\t\t\t\tescapeJsonPointer( i );\n\t\t\t\t\t\tvar item = schema.properties[ i ];\n\t\t\t\t\t\tvar previousItem =\n\t\t\t\t\t\t\t'properties' in previousSchema && i in previousSchema.properties ?\n\t\t\t\t\t\t\t\tpreviousSchema.properties[ i ] :\n\t\t\t\t\t\t\t\t{};\n\t\t\t\t\t\tvar thisModel = ( model.properties[ i ] = {\n\t\t\t\t\t\t\tparent: model.properties,\n\t\t\t\t\t\t\tchildIndex: i,\n\t\t\t\t\t\t\tparentSchema: schema\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tvar widget_ = new GroupWidget( {}, { schema: item, path: path_, model: thisModel } );\n\t\t\t\t\t\tprocessSchema(\n\t\t\t\t\t\t\twidget_,\n\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\tpreviousItem,\n\t\t\t\t\t\t\tschemaName,\n\t\t\t\t\t\t\tthisModel,\n\t\t\t\t\t\t\tdata[ i ],\n\t\t\t\t\t\t\tpath_,\n\t\t\t\t\t\t\tpathNoIndex_,\n\t\t\t\t\t\t\tnewItem\n\t\t\t\t\t\t);\n\t\t\t\t\t\titems_.push( widget_ );\n\t\t\t\t\t}\n\t\t\t\t\twidget.addItems( items_ );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'array':\n\t\t\t\tif ( 'items' in schema ) {\n\t\t\t\t\tif ( VisualDataFunctions.isObject( schema.items ) ) {\n\t\t\t\t\t\tvar item = schema.items;\n\t\t\t\t\t\tmodel.items = {};\n\t\t\t\t\t\tif ( item.wiki.type === 'property' ) {\n\t\t\t\t\t\t\titem.wiki.layout = 'table';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar previousItem =\n\t\t\t\t\t\t\t'items' in previousSchema ? previousSchema.items : {};\n\n\t\t\t\t\t\tvar optionsListContainer = new OptionsListContainer(\n\t\t\t\t\t\t\t{},\n\t\t\t\t\t\t\tschema,\n\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\tpreviousItem,\n\t\t\t\t\t\t\tschemaName,\n\t\t\t\t\t\t\tmodel.items,\n\t\t\t\t\t\t\tdata,\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\tpathNoIndex,\n\t\t\t\t\t\t\tnewItem\n\t\t\t\t\t\t);\n\t\t\t\t\t\twidget.addItems( [ optionsListContainer ] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// @TODO\n\t\t\t\t\t\t// implement tuple\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// 'string',\n\t\t\t\t// 'number',\n\t\t\t\t// 'integer',\n\t\t\t\t// 'boolean',\n\t\t\t\t// 'null'\n\t\t\t\t// model.type = \"property\";\n\t\t\t\tif ( !( 'wiki' in schema ) ) {\n\t\t\t\t\tschema.wiki = {};\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t'visibility' in schema.wiki &&\n\t\t\t\t\tschema.wiki.visibility === 'oncreate-only' &&\n\t\t\t\t\tForm.options.action !== 'create'\n\t\t\t\t) {\n\t\t\t\t\tdelete model.parent[ model.childIndex ];\n\n\t\t\t\t} else {\n\t\t\t\t\tvar inputValue = determineInputValue(\n\t\t\t\t\t\tschema,\n\t\t\t\t\t\tpreviousSchema,\n\t\t\t\t\t\tschemaName,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tdata,\n\t\t\t\t\t\tnewItem\n\t\t\t\t\t);\n\n\t\t\t\t\tif ( Array.isArray( inputValue ) ) {\n\t\t\t\t\t\tinputValue = inputValue.filter(\n\t\t\t\t\t\t\t( x ) => !VisualDataFunctions.isObject( x )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// used by getFieldAlign\n\t\t\t\t\t// model.schema.wiki.schema = schemaName;\n\t\t\t\t\tvar item = new ItemWidget( {\n\t\t\t\t\t\tclasses: [ 'VisualDataItemWidget' ],\n\t\t\t\t\t\tmodel: model,\n\t\t\t\t\t\tdata: inputValue,\n\t\t\t\t\t\toptionsList,\n\t\t\t\t\t\twidget\n\t\t\t\t\t} );\n\n\t\t\t\t\twidget.addItems( [ item ] );\n\t\t\t\t}\n\t\t}\n\n\t\t// @TODO implement anyOf, oneOf, allOf\n\t\t// https://json-schema.org/understanding-json-schema/reference/combining.html\n\t\t// var directives = [\"anyOf\", \"oneOf\", \"allOf\"];\n\t\t// for (var directive of directives) {\n\t\t// \tif (directive in schema) {\n\t\t// \t\t// *** this is by default an array,\n\t\t// \t\t// but transformed to an object\n\t\t// \t\tfor (var i in schema[directive]) {\n\t\t// \t\t\tvar item = schema[directive][i];\n\t\t// \t\t\tlet widget_ = new GroupWidget({}, item);\n\t\t// \t\t\tprocessSchema(widget_, item, schemaName, (model[i] = {}));\n\t\t// \t\t\tif ( directive!=='allOf' ) {\n\t\t// \t\t\t\twidget.addCombinedItem(widget_, item.title || i, directive);\n\t\t// \t\t\t} else {\n\t\t// \t\t\t\twidget.addItems([widget_]);\n\t\t// \t\t\t}\n\t\t// \t\t}\n\t\t// \t}\n\t\t// }\n\n\t\t// inform the root widget that the rendering of the form is complete\n\t\tif ( --PendingRecursive === 0 ) {\n\t\t\t// @see https://www.mediawiki.org/wiki/OOjs/Events\n\t\t\tif ( QueuedWidgets[ schemaName ].length ) {\n\t\t\t\tQueuedWidgets[ schemaName ][ 0 ].emit( 'formLoaded' );\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction getSchemasPanelLayout() {\n\t\tFields = {};\n\t\tModelSchemas = {};\n\t\tModelFlatten = [];\n\t\tInputWidgets = {};\n\n\t\t// @TODO implement a better interface between\n\t\t// VisualData instance and this constructor\n\t\tProcessModel = new VisualDataProcessModel(\n\t\t\tcallbackShowError,\n\t\t\tForm,\n\t\t\tSchemas,\n\t\t\tInitialSchemas,\n\t\t\tModel,\n\t\t\tModelSchemas,\n\t\t\tmakeElementId\n\t\t);\n\n\t\treturn new PanelLayout( {\n\t\t\texpanded: true,\n\t\t\tpadded: false,\n\t\t\tframed: false,\n\t\t\t// classes: [\"PanelProperties-panel-section\"],\n\t\t\tdata: {\n\t\t\t\tname: 'schemas',\n\t\t\t\tschemas: Form.schemas\n\t\t\t}\n\t\t} );\n\t}\n\n\tfunction getArticlePanelLayout() {\n\t\tvar userDefined = Config.isNewPage && Form.options[ 'edit-page' ] === '';\n\n\t\tvar editFreeText = Config.isNewPage && Config.context === 'EditData';\n\t\tvar editContentModel = Config.context === 'EditData';\n\t\tvar editCategories = Config.context === 'EditData';\n\t\tvar editTargetSlot = Config.context === 'EditData';\n\n\t\tvar categories = [];\n\n\t\tvar contentModel = ( Form.options.action === 'create' && ( 'default-content-model' in Form.options ) ?\n\t\t\tForm.options[ 'default-content-model' ] : Config.contentModel );\n\n\t\tif ( 'edit-content-model' in Form.options ) {\n\t\t\teditContentModel = Form.options[ 'edit-content-model' ];\n\t\t}\n\n\t\tif ( 'edit-categories' in Form.options ) {\n\t\t\teditCategories = Form.options[ 'edit-categories' ]; // !Form.schemas.length || !Config.isNewPage;\n\t\t}\n\n\t\tif ( 'edit-freetext' in Form.options ) {\n\t\t\teditFreeText = Form.options[ 'edit-freetext' ];\n\t\t}\n\n\t\tif ( 'edit-target-slot' in Form.options ) {\n\t\t\teditTargetSlot = Form.options[ 'edit-target-slot' ];\n\t\t}\n\n\t\tif ( editTargetSlot === false &&\n\t\t\t'target-slot' in Form.options &&\n\t\t\tForm.options[ 'target-slot' ] === 'main'\n\t\t) {\n\t\t\teditFreeText = false;\n\t\t\teditContentModel = false;\n\t\t}\n\n\t\tvar fieldAlign = 'top';\n\n\t\tif (\n\t\t\tForm.options.action === 'create' &&\n\t\t\tForm.options[ 'pagename-formula' ] === ''\n\t\t) {\n\t\t\tuserDefined = true;\n\t\t}\n\n\t\t// this will set the fieldAlign of the wiki\n\t\t// section as the fieldAlign of last form\n\t\tif ( 'layout-align' in Form.options ) {\n\t\t\tfieldAlign = Form.options[ 'layout-align' ];\n\t\t}\n\n\t\t// if (Form.options[\"default-categories\"]) {\n\t\t// \tcategories = Form.options[\"default-categories\"].split(/\\s*,\\s*/)\n\t\t// \t\t.filter( x => x.trim() !== '' );\n\t\t// }\n\t\tvar categories = (\n\t\t\t'default-categories' in Form.options ?\n\t\t\t\tForm.options[ 'default-categories' ] :\n\t\t\t\t[]\n\t\t).concat( Form.categories );\n\n\t\t// for some reason appending the method\n\t\t// halts the execution combined with mw.loader\n\t\tcategories = categories.filter( function onlyUnique( value, index, self ) {\n\t\t\treturn self.indexOf( value ) === index;\n\t\t} );\n\n\t\t// create title and free text input\n\t\tif ( !userDefined && !editFreeText && !editCategories && !editContentModel ) {\n\t\t\treturn { isEmpty: true };\n\t\t}\n\n\t\treturn new PanelLayout( {\n\t\t\texpanded: false,\n\t\t\tpadded: true,\n\t\t\tframed: false,\n\t\t\t// classes: [\"PanelProperties-panel-section\"],\n\t\t\tdata: {\n\t\t\t\tname: 'article',\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-wiki' ),\n\t\t\t\tuserDefined,\n\t\t\t\teditFreeText,\n\t\t\t\teditCategories,\n\t\t\t\teditContentModel,\n\t\t\t\teditTargetSlot,\n\t\t\t\tcontentModel,\n\t\t\t\tcategories,\n\t\t\t\tfieldAlign\n\t\t\t}\n\t\t} );\n\t}\n\n\tfunction removeSchemasPanel() {\n\t\tvar panels = PropertiesStack.getItems();\n\t\tfor ( var panel of panels ) {\n\t\t\tif ( panel.getData().name === 'schemas' ) {\n\t\t\t\tPropertiesStack.removeItems( [ panel ] );\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction updatePanels() {\n\t\tProcessModel.getModel( 'fetch' ).then( function ( res ) {\n\t\t\tForm.jsonData.schemas = $.extend( Form.jsonData.schemas, res );\n\n\t\t\tremoveSchemasPanel();\n\n\t\t\tvar schemasPanelLayout = getSchemasPanelLayout();\n\t\t\tif ( !schemasPanelLayout.isEmpty ) {\n\t\t\t\tPropertiesStack.addItems( [ schemasPanelLayout ], 0 );\n\t\t\t}\n\n\t\t\tvar panels = PropertiesStack.getItems();\n\n\t\t\tPropertiesStack.setItem( panels[ 0 ] );\n\n\t\t\tselectSchema( SelectedSchema, true );\n\n\t\t\tPropertiesStack.$element.removeClass( [\n\t\t\t\t'PanelPropertiesStack',\n\t\t\t\t'PanelPropertiesStack-empty'\n\t\t\t] );\n\n\t\t\tswitch ( panels.length ) {\n\t\t\t\tcase 0:\n\t\t\t\t\tPropertiesStack.$element.addClass( 'PanelPropertiesStack-empty' );\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tPropertiesStack.$element.addClass( 'PanelPropertiesStack' );\n\t\t\t}\n\n\t\t\tupdateButtons( panels );\n\t\t} );\n\t}\n\n\tfunction updateButtons( panels ) {\n\t\tif ( TargetSlotField ) {\n\t\t\tTargetSlotField.toggle( hasMultiplePanels() ||\n\t\t\t\t( 'target-slot' in Model && Model[ 'target-slot' ].getValue() === 'main' ) );\n\t\t}\n\n\t\tif ( Form.options.view === 'popup' || Form.options.view === 'button' ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( hasMultiplePanels() ) {\n\t\t\tValidateButton.toggle( panels.length !== 0 );\n\t\t\t// DeleteButton.toggle( hasStoredJsonData() );\n\t\t\tGoBackButton.toggle( false );\n\t\t\tSubmitButton.toggle( false );\n\t\t} else {\n\t\t\tSubmitButton.toggle( panels.length !== 0 );\n\t\t\t// DeleteButton.toggle( hasStoredJsonData() );\n\t\t\tGoBackButton.toggle( false );\n\t\t\tValidateButton.toggle( false );\n\t\t}\n\t}\n\n\tfunction updateSchemas( previousSchemas, schemas, data ) {\n\t\tPreviousSchemas = previousSchemas;\n\t\tSchemas = schemas;\t// VisualDataFunctions.deepCopy( schemas );\n\n\t\tif ( data && data[ 'result-action' ] === 'rename' ) {\n\t\t\t// *** do not compare Schemas with Form.schemas,\n\t\t\t// since a rename could match an existing entry\n\t\t\t// in Schemas\n\t\t\t// for ( var schemaName in Schemas ) {\n\t\t\t// \tif ( Form.schemas.indexOf( schemaName ) === -1 ) {\n\t\t\t// \t\tSelectedSchema = schemaName;\n\t\t\t// \t\tbreak;\n\t\t\t// \t}\n\t\t\t// }\n\t\t\tSelectedSchema = data.label;\n\n\t\t\tfor ( var i in Form.schemas ) {\n\t\t\t\tvar schemaName = Form.schemas[ i ];\n\t\t\t\tif ( !( schemaName in Schemas ) ) {\n\t\t\t\t\tForm.schemas.splice( i, 1, SelectedSchema );\n\t\t\t\t\tif ( !( SelectedSchema in Form.jsonData.schemas ) ) {\n\t\t\t\t\t\tForm.jsonData.schemas[ SelectedSchema ] = Form.jsonData.schemas[ schemaName ];\n\t\t\t\t\t}\n\t\t\t\t\tdelete Form.jsonData.schemas[ schemaName ];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// uninitialized\n\t\tif ( !( 'getModel' in ProcessModel ) ) {\n\t\t\treturn;\n\t\t}\n\t\tupdatePanels();\n\t}\n\n\tasync function onSubmit( e ) {\n\t\te.preventDefault();\n\n\t\tvar action;\n\t\tvar formEl = $( this ); // .closest(\".VisualDataForm\");\n\n\t\tif ( formEl.data( 'delete' ) === true ) {\n\t\t\taction = 'delete';\n\t\t} else {\n\t\t\taction = !hasMultiplePanels() ? 'validate&submit' : 'submit';\n\t\t}\n\n\t\tProcessModel.getModel( action ).then( async function ( res ) {\n\t\t\tif ( typeof res === 'boolean' && res === false ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( res.form[ 'target-slot' ] === 'main' && !res.schemas.length &&\n\t\t\t\t!InitialSchemas.length ) {\n\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\talert( mw.msg( 'visualdata-jsmodule-forms-submit-no-schemas' ) );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( 'callback' in Form.options && Form.options.callback !== '' ) {\n\t\t\t\tVisualDataFunctions.executeFunctionByName( Form.options.callback, window, [ res ] );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t$( '<input>' )\n\t\t\t\t.attr( {\n\t\t\t\t\ttype: 'hidden',\n\t\t\t\t\tname: 'data',\n\t\t\t\t\tvalue: JSON.stringify( getFormAttributes( res ) )\n\t\t\t\t} )\n\t\t\t\t.appendTo( formEl );\n\n\t\t\tformEl.unbind( 'submit' ).submit();\n\t\t} );\n\t}\n\n\tfunction ProcessDialog( config ) {\n\t\tProcessDialog.super.call( this, config );\n\t}\n\tOO.inheritClass( ProcessDialog, OO.ui.ProcessDialog );\n\n\tProcessDialog.static.name = DialogName;\n\t// ProcessDialog.static.title = mw.msg(\n\t// \t\"visualdata-jsmodule-forms-defineform\"\n\t// );\n\tProcessDialog.static.actions = [\n\t\t{\n\t\t\taction: 'delete',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-delete' ),\n\t\t\tflags: 'destructive',\n\t\t\tmodes: [ 'validate-delete', 'submit-single-delete' ]\n\t\t},\n\t\t{\n\t\t\taction: 'validate',\n\t\t\tmodes: [ 'validate', 'validate-delete' ],\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-validate' ),\n\t\t\tflags: [ 'primary', 'progressive' ]\n\t\t},\n\t\t{\n\t\t\taction: 'back',\n\t\t\tlabel: OO.ui.deferMsg( 'visualdata-jsmodule-dialog-goback' ),\n\t\t\tflags: [ 'safe', 'back' ],\n\t\t\tmodes: [ 'submit', 'submit-delete' ]\n\t\t},\n\t\t{\n\t\t\taction: 'submit',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-submit' ),\n\t\t\tflags: [ 'primary', 'progressive' ],\n\t\t\tmodes: [ 'submit', 'submit-delete' ]\n\t\t},\n\t\t{\n\t\t\taction: 'validate&submit',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-submit' ),\n\t\t\tflags: [ 'primary', 'progressive' ],\n\t\t\tmodes: [ 'submit-single', 'submit-single-delete' ]\n\t\t},\n\t\t{\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-close' ),\n\t\t\tflags: [ 'safe', 'close' ],\n\t\t\tmodes: [\n\t\t\t\t'validate',\n\t\t\t\t'submit-single',\n\t\t\t\t'validate-delete',\n\t\t\t\t'submit-single-delete'\n\t\t\t]\n\t\t}\n\t];\n\n\tProcessDialog.prototype.getSetupProcess = function ( data ) {\n\t\t// data = data || {};\n\t\t// @see https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n\t\treturn ProcessDialog.super.prototype.getSetupProcess\n\t\t\t.call( this, data )\n\t\t\t.next( function () {\n\t\t\t\t// @see resources/lib/ooui/oojs-ui-windows.js\n\t\t\t\tthis.actions.setMode(\n\t\t\t\t\t( hasMultiplePanels() ?\n\t\t\t\t\t\t'validate' :\n\t\t\t\t\t\t'submit-single' ) + ( !hasStoredJsonData() ? '' : '-delete' )\n\t\t\t\t);\n\n\t\t\t\tthis.$body.append( data.PropertiesStack.$element );\n\t\t\t}, this );\n\t};\n\n\tProcessDialog.prototype.initialize = function () {\n\t\tProcessDialog.super.prototype.initialize.apply( this, arguments );\n\t\t// this.$body.append( this.data.OuterStack.$element );\n\t};\n\n\tProcessDialog.prototype.getActionProcess = function ( action ) {\n\t\tif (\n\t\t\t!action ||\n\t\t\t( action === 'delete' &&\n\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\t!confirm(\n\t\t\t\t\tmw.msg( 'visualdata-jsmodule-forms-delete-data-confirm' )\n\t\t\t\t) )\n\t\t) {\n\t\t\treturn ProcessDialog.super.prototype.getActionProcess.call( this, action );\n\t\t}\n\t\tvar self = this;\n\t\treturn ProcessDialog.super.prototype.getActionProcess\n\t\t\t.call( this, action )\n\t\t\t.next( function () {\n\t\t\t\tswitch ( action ) {\n\t\t\t\t\tcase 'back':\n\t\t\t\t\t\tvar panels = PropertiesStack.getItems();\n\t\t\t\t\t\tPropertiesStack.setItem( panels[ 0 ] );\n\t\t\t\t\t\tself.setSize(\n\t\t\t\t\t\t\t!( 'popup-size' in Form.options ) ||\n\t\t\t\t\t\t\t\tForm.options[ 'popup-size' ] === '' ?\n\t\t\t\t\t\t\t\t'medium' :\n\t\t\t\t\t\t\t\tForm.options[ 'popup-size' ]\n\t\t\t\t\t\t);\n\t\t\t\t\t\tself.actions.setMode(\n\t\t\t\t\t\t\t'validate' + ( !hasStoredJsonData() ? '' : '-delete' )\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'validate':\n\t\t\t\t\t\tProcessModel.getModel( 'validate' ).then( function ( res ) {\n\t\t\t\t\t\t\tif ( typeof res === 'boolean' ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar thisPanels = PropertiesStack.getItems();\n\t\t\t\t\t\t\tPropertiesStack.setItem( thisPanels[ thisPanels.length - 1 ] );\n\t\t\t\t\t\t\tself.setSize( 'medium' );\n\t\t\t\t\t\t\tself.actions.setMode(\n\t\t\t\t\t\t\t\t'submit' + ( !hasStoredJsonData() ? '' : '-delete' )\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'validate&submit':\n\t\t\t\t\tcase 'submit':\n\t\t\t\t\tcase 'delete':\n\t\t\t\t\t\treturn ProcessModel.getModel( action ).then( function ( res ) {\n\t\t\t\t\t\t\tif ( action.indexOf( 'submit' ) !== 1 && typeof res === 'boolean' ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar payload = {\n\t\t\t\t\t\t\t\tdata: JSON.stringify( getFormAttributes( res ) ),\n\t\t\t\t\t\t\t\taction: 'visualdata-submit-form'\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\t\t\t\t\t\tnew mw.Api()\n\t\t\t\t\t\t\t\t\t.postWithToken( 'csrf', payload )\n\t\t\t\t\t\t\t\t\t.done( function ( thisRes ) {\n\t\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t\t\tif ( payload.action in thisRes ) {\n\t\t\t\t\t\t\t\t\t\t\tvar data = JSON.parse( thisRes[ payload.action ].result );\n\t\t\t\t\t\t\t\t\t\t\tif ( !data.errors.length ) {\n\t\t\t\t\t\t\t\t\t\t\t\tWindowManager.closeActiveWindow();\n\t\t\t\t\t\t\t\t\t\t\t\t// @FIXME reload only if the changes affect\n\t\t\t\t\t\t\t\t\t\t\t\t// the current page\n\t\t\t\t\t\t\t\t\t\t\t\tif ( data[ 'target-url' ] === window.location.href ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\twindow.location.reload();\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\twindow.location.href = data[ 'target-url' ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\tVisualDataFunctions.OOUIAlert(\n\t\t\t\t\t\t\t\t\t\t\t\t\tnew OO.ui.HtmlSnippet( data.errors.join( '<br />' ) ),\n\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsize: 'medium'\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t);\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} )\n\t\t\t\t\t\t\t\t\t.fail( function ( thisRes ) {\n\t\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\t\t\t\t\tconsole.error( 'visualdata-submit-form', thisRes );\n\t\t\t\t\t\t\t\t\t\treject( thisRes );\n\t\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} ).catch( ( err ) => {\n\t\t\t\t\t\t\tVisualDataFunctions.OOUIAlert( `error: ${ err }`, { size: 'medium' } );\n\t\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t// return new OO.ui.Process(function () {\n\t\t// \tdialog.close({ action: action });\n\t\t// });\n\n\t\t// return ProcessDialog.super.prototype.getActionProcess.call(this, action);\n\t};\n\n\tProcessDialog.prototype.getTeardownProcess = function ( data ) {\n\t\treturn ProcessDialog.super.prototype.getTeardownProcess\n\t\t\t.call( this, data )\n\t\t\t.first( function () {\n\t\t\t\tWindowManager.removeActiveWindow();\n\t\t\t}, this );\n\t};\n\n\t/**\n\t * Override getBodyHeight to create a tall dialog relative to the screen.\n\t *\n\t * @return {number} Body height\n\t */\n\tProcessDialog.prototype.getBodyHeight = function () {\n\t\t// see here https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n\t\t// this.page1.content.$element.outerHeight( true );\n\t\treturn window.innerHeight - 100;\n\t};\n\n\tfunction getFormAttributes( jsondata ) {\n\t\treturn $.extend(\n\t\t\t{\n\t\t\t\tformIndex: FormIndex,\n\t\t\t\tconfig: Config\n\t\t\t},\n\t\t\tjsondata\n\t\t);\n\t}\n\n\tfunction initializePropertiesStack() {\n\t\tvar panels = [ getSchemasPanelLayout(), getArticlePanelLayout() ].filter(\n\t\t\t( x ) => !x.isEmpty\n\t\t);\n\n\t\tvar classes = [];\n\n\t\tswitch ( panels.length ) {\n\t\t\tcase 0:\n\t\t\t\tclasses.push( 'PanelPropertiesStack-empty' );\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tclasses.push( 'PanelPropertiesStack' );\n\t\t}\n\n\t\tPropertiesStack = new OO.ui.StackLayout( {\n\t\t\titems: panels,\n\t\t\tcontinuous: false, // !hasMultiplePanels(),\n\t\t\texpanded: true,\n\t\t\tpadded: false,\n\t\t\t// The following classes are used here:\n\t\t\t// * PanelPropertiesStack\n\t\t\t// * PanelPropertiesStack-empty\n\t\t\tclasses: classes\n\t\t} );\n\n\t\tPropertiesStack.on( 'change', onChangePropertiesStack );\n\t\tPropertiesStack.on( 'set', onSetPropertiesStack );\n\t\treturn panels;\n\t}\n\n\tfunction hasMultiplePanels() {\n\t\treturn PropertiesStack && PropertiesStack.getItems().length > 1;\n\t}\n\n\tfunction hasStoredJsonData() {\n\t\tif ( Config.context !== 'EditData' && Form.options.action !== 'edit' ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !( 'schemas' in StoredJsonData ) ) {\n\t\t\treturn false;\n\t\t}\n\t\tfor ( var i in StoredJsonData.schemas ) {\n\t\t\tif (\n\t\t\t\tVisualDataFunctions.isObject( StoredJsonData.schemas[ i ] ) &&\n\t\t\t\tObject.keys( StoredJsonData.schemas[ i ] ).length\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tfunction isVisible() {\n\t\treturn $( El ).is( ':visible' );\n\t}\n\n\tfunction setMutation( schemaName, rootEl ) {\n\t\tif ( schemaName in MutationObservers ) {\n\t\t\tMutationObservers[ schemaName ].disconnect();\n\t\t}\n\n\t\t// the root element may not have been yet\n\t\t// appended when the form is loaded\n\t\tif ( rootEl ) {\n\t\t\tvar el = rootEl;\n\t\t} else {\n\t\t\tvar escapedSchemaName = escapeJsonPointer( schemaName );\n\t\t\tvar el = window.document.querySelector( '#' +\n\t\t\t\tjQuery.escapeSelector( makeElementId( escapedSchemaName ) ) );\n\t\t}\n\n\t\tif ( !el ) {\n\t\t\t// console.log( 'element not found ' + makeElementId( escapedSchemaName ) );\n\t\t\treturn;\n\t\t}\n\n\t\tvar MutationObserver = window.MutationObserver || window.WebKitMutationObserver;\n\n\t\tif ( MutationObserver ) {\n\t\t\tvar observer = new MutationObserver( function ( mutations, thisObserver ) {\n\t\t\t\tvar matchedClasses = [];\n\t\t\t\tfor ( var mutation of mutations ) {\n\t\t\t\t\tif ( mutation.type === 'attributes' && mutation.attributeName === 'class' ) {\n\t\t\t\t\t\tmatchedClasses.concat( mutation.target.classList );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tonMutationChange( schemaName, el, matchedClasses );\n\t\t\t} );\n\n\t\t\t// observe only current tab/schema\n\t\t\tobserver.observe( el, {\n\t\t\t\tsubtree: true,\n\t\t\t\tchildList: true,\n\t\t\t\tattributes: true\n\t\t\t} );\n\n\t\t\tMutationObservers[ schemaName ] = observer;\n\t\t}\n\t}\n\n\tfunction onMutationChange( schemaName, rootEl, matchedClasses ) {\n\t\t// *** this unfortunately does not solve the issue\n\t\t// so we pause the observer with disconnect\n\t\t// var VisualEditorIgnoreClasses = [ 've-for-all-waiting-for-update' ];\n\t\t// if ( Array.isArray( matchedClasses ) &&\n\t\t// \tVisualDataFunctions.arrayIntersect( matchedClasses, VisualEditorIgnoreClasses ).length\n\t\t// ) {\n\t\t// \treturn;\n\t\t// }\n\t\tif ( schemaName in MutationObservers ) {\n\t\t\tMutationObservers[ schemaName ].disconnect();\n\t\t}\n\n\t\tvar promises = [ loadMaps() ]\n\t\t\t.concat( showLazyWidget( 'VisualDataVisualEditor' ) )\n\t\t\t.concat( showLazyWidget( 'VisualDataTinyMCE' ) );\n\n\t\t// *** MutationObservers[ sourceModel.schemaName ].disconnect()\n\t\t// could be called here and resumed on completion\n\t\t// of the loop and the updateFieldsVisibility (asynch) function\n\t\t// however updateFieldsVisibility is also called on inputs\n\t\t// change\n\t\tvar models = ModelFlatten.filter( ( x ) => x.schemaName === schemaName );\n\t\tfor ( var i in models ) {\n\t\t\tpromises.push( updateFieldsVisibility( models[ i ] ) );\n\t\t}\n\n\t\tVisualDataFunctions.promisesAllSettled( promises ).then( ( res ) => {\n\t\t\tsetMutation( schemaName, rootEl );\n\t\t} ).catch( ( err ) => {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log( err );\n\t\t} );\n\t}\n\n\tfunction initialize() {\n\t\t// if not visible, wait for a new\n\t\t// mutation\n\t\tif ( !isVisible() ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( Initialized ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tFormID = El.id = VisualDataFunctions.uniqueID();\n\n\t\tInitialized = true;\n\n\t\tif ( Form.options.view === 'button' ) {\n\t\t\tvar button = new OO.ui.ButtonWidget( {\n\t\t\t\ticon: Form.options.icon,\n\t\t\t\tflags: [ 'primary', 'progressive' ],\n\t\t\t\tlabel: Form.options.label\n\t\t\t} );\n\t\t\tvar widget;\n\n\t\t\tif ( Form.options[ 'edit-page' ] !== '' ) {\n\t\t\t\tvar editButton = new OO.ui.ButtonWidget( {\n\t\t\t\t\ticon: 'edit',\n\t\t\t\t\tflags: [ 'primary', 'progressive' ]\n\t\t\t\t} );\n\n\t\t\t\teditButton.on( 'click', function () {\n\t\t\t\t\tinitializePropertiesStack();\n\n\t\t\t\t\tvar thisClasses = [];\n\t\t\t\t\tif ( 'css-class' in Form.options && Form.options[ 'css-class' ] !== '' ) {\n\t\t\t\t\t\tthisClasses.push( Form.options[ 'css-class' ] );\n\t\t\t\t\t}\n\n\t\t\t\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\t\t\t\tvar processDialog = new ProcessDialog( {\n\t\t\t\t\t\tsize:\n\t\t\t\t\t\t\t!( 'popup-size' in Form.options ) || Form.options[ 'popup-size' ] === '' ?\n\t\t\t\t\t\t\t\t'medium' :\n\t\t\t\t\t\t\t\tForm.options[ 'popup-size' ],\n\t\t\t\t\t\tid: 'visualdataform-wrapper-dialog-' + FormID,\n\t\t\t\t\t\tclasses: thisClasses\n\t\t\t\t\t} );\n\n\t\t\t\t\tWindowManager.newWindow( processDialog, {\n\t\t\t\t\t\ttitle: Form.options.title,\n\t\t\t\t\t\tPropertiesStack: PropertiesStack\n\t\t\t\t\t} );\n\t\t\t\t} );\n\n\t\t\t\twidget = new OO.ui.ActionFieldLayout( button, editButton, {\n\t\t\t\t\tlabel: '',\n\t\t\t\t\talign: 'top',\n\t\t\t\t\tclasses: [ 'VisualDataPageButtonsActionField' ]\n\t\t\t\t} );\n\n\t\t\t} else {\n\t\t\t\twidget = button;\n\t\t\t}\n\n\t\t\tbutton.on( 'click', function () {\n\t\t\t\tvar args = [ Form.options.value ];\n\n\t\t\t\tif ( Form.options.schema !== '' && schemaHasData( Form.options.schema ) ) {\n\t\t\t\t\t// initializePropertiesStack();\n\t\t\t\t\t// ProcessModel.getModel( 'schema', Form.options.schema ).then( async function ( res ) {\n\t\t\t\t\t// \tif ( typeof res === 'boolean' && res === false ) {\n\t\t\t\t\t// \t\treturn;\n\t\t\t\t\t// \t}\n\t\t\t\t\t// \targs.push( res.data );\n\t\t\t\t\t// \tVisualDataFunctions.executeFunctionByName( Form.options.callback, window, args );\n\t\t\t\t\t// } );\n\t\t\t\t\targs.push( StoredJsonData.schemas[ Form.options.schema ] );\n\t\t\t\t}\n\t\t\t\tVisualDataFunctions.executeFunctionByName( Form.options.callback, window, args );\n\t\t\t} );\n\n\t\t\t$( El ).html( widget.$element );\n\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( Form.options.view === 'popup' ) {\n\t\t\tvar popupButton = new OO.ui.ButtonWidget( {\n\t\t\t\ticon: 'edit',\n\t\t\t\tlabel: Form.options.title\n\t\t\t} );\n\n\t\t\tpopupButton.on( 'click', function () {\n\t\t\t\tinitializePropertiesStack();\n\n\t\t\t\tvar thisClasses = [];\n\t\t\t\tif ( 'css-class' in Form.options && Form.options[ 'css-class' ] !== '' ) {\n\t\t\t\t\tthisClasses.push( Form.options[ 'css-class' ] );\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\t\t\tvar processDialog = new ProcessDialog( {\n\t\t\t\t\tsize:\n\t\t\t\t\t\t!( 'popup-size' in Form.options ) || Form.options[ 'popup-size' ] === '' ?\n\t\t\t\t\t\t\t'medium' :\n\t\t\t\t\t\t\tForm.options[ 'popup-size' ],\n\t\t\t\t\tid: 'visualdataform-wrapper-dialog-' + FormID,\n\t\t\t\t\tclasses: thisClasses\n\t\t\t\t} );\n\n\t\t\t\tWindowManager.newWindow( processDialog, {\n\t\t\t\t\ttitle: Form.options.title,\n\t\t\t\t\tPropertiesStack: PropertiesStack\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\t$( El ).html( popupButton.$element );\n\n\t\t\treturn true;\n\t\t}\n\n\t\tvar formContent = [];\n\t\tif ( Form.errors.length ) {\n\t\t\tvar messageWidget = new OO.ui.MessageWidget( {\n\t\t\t\ttype: 'error',\n\t\t\t\tlabel: new OO.ui.HtmlSnippet( Form.errors.join( '<br /> ' ) )\n\t\t\t} );\n\n\t\t\tformContent.push( messageWidget.$element );\n\t\t\tformContent.push( $( '<br>' ) );\n\t\t}\n\n\t\tvar panels = initializePropertiesStack();\n\n\t\tSubmitButton = new OO.ui.ButtonInputWidget( {\n\t\t\tlabel:\n\t\t\t\t!( 'submit-button-text' in Form.options ) ||\n\t\t\t\tForm.options[ 'submit-button-text' ] === '' ?\n\t\t\t\t\tmw.msg( 'visualdata-jsmodule-forms-submit' ) :\n\t\t\t\t\tForm.options[ 'submit-button-text' ],\n\n\t\t\tflags: [ 'primary', 'progressive' ],\n\t\t\tclasses: [ 'VisualDataFormSubmitButton' ],\n\t\t\ttype: 'submit'\n\t\t} );\n\n\t\tformContent.push( PropertiesStack.$element );\n\t\tformContent.push( SubmitButton.$element );\n\n\t\tValidateButton = new OO.ui.ButtonInputWidget( {\n\t\t\tlabel:\n\t\t\t\t!( 'validate-button-text' in Form.options ) ||\n\t\t\t\tForm.options[ 'validate-button-text' ] === '' ?\n\t\t\t\t\tmw.msg( 'visualdata-jsmodule-forms-validate' ) :\n\t\t\t\t\tForm.options[ 'validate-button-text' ],\n\t\t\tclasses: [ 'VisualDataFormSubmitButton' ],\n\t\t\tflags: [ 'primary', 'progressive' ]\n\t\t\t// type: \"submit\",\n\t\t} );\n\n\t\tValidateButton.on( 'click', function () {\n\t\t\tProcessModel.getModel( 'validate' ).then( function ( res ) {\n\t\t\t\tif ( typeof res === 'boolean' && res === false ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar thisPanels = PropertiesStack.getItems();\n\t\t\t\tPropertiesStack.setItem( thisPanels[ thisPanels.length - 1 ] );\n\n\t\t\t\tValidateButton.toggle( false );\n\t\t\t\tSubmitButton.toggle( true );\n\t\t\t\tGoBackButton.toggle( true );\n\t\t\t\t// DeleteButton.toggle( false );\n\n\t\t\t\t$( El ).get( 0 ).scrollIntoView( { behavior: 'smooth' } );\n\t\t\t} );\n\t\t} );\n\n\t\tformContent.push( ValidateButton.$element );\n\n\t\t// var printDeleteButton = hasStoredJsonData();\n\n\t\t// DeleteButton = new OO.ui.ButtonInputWidget( {\n\t\t// \tlabel: mw.msg( 'visualdata-jsmodule-forms-delete' ),\n\t\t// \tclasses: [ 'VisualDataFormSubmitButton' ],\n\t\t// \tflags: [ 'destructive' ],\n\t\t// \ttype: 'submit'\n\t\t// } );\n\n\t\t// formContent.push( DeleteButton.$element );\n\n\t\tGoBackButton = new OO.ui.ButtonInputWidget( {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-forms-goback' ),\n\t\t\tclasses: [ 'VisualDataFormSubmitButton' ],\n\t\t\tflags: [ 'progressive' ],\n\t\t\ticon: 'arrowPrevious'\n\t\t} );\n\n\t\tGoBackButton.on( 'click', function () {\n\t\t\tvar thisPanels = PropertiesStack.getItems();\n\t\t\tPropertiesStack.setItem( thisPanels[ 0 ] );\n\n\t\t\tValidateButton.toggle( true );\n\t\t\tSubmitButton.toggle( false );\n\t\t\tGoBackButton.toggle( false );\n\t\t\t// DeleteButton.toggle( hasStoredJsonData() );\n\n\t\t\t$( El ).get( 0 ).scrollIntoView( { behavior: 'smooth' } );\n\t\t} );\n\n\t\tformContent.push( GoBackButton.$element );\n\n\t\tupdateButtons( panels );\n\n\t\tvar classes = [\n\t\t\t'VisualDataForm',\n\t\t\t'VisualDataFormContext-' + Config.context\n\t\t];\n\n\t\tif ( 'css-class' in Form.options && Form.options[ 'css-class' ] !== '' ) {\n\t\t\tclasses.push( Form.options[ 'css-class' ] );\n\t\t}\n\n\t\t// eslint-disable-next-line mediawiki/class-doc\n\t\tvar form = new OO.ui.FormLayout( {\n\t\t\taction: Config.actionUrl,\n\t\t\tmethod: 'post',\n\t\t\tenctype: 'multipart/form-data',\n\t\t\t$content: formContent,\n\t\t\tclasses: classes,\n\t\t\tdata: { name: 'visualdata' }\n\t\t} );\n\n\t\t// DeleteButton.on( 'click', function () {\n\t\t// \tif (\n\t\t// \t\t// eslint-disable-next-line no-alert\n\t\t// \t\tconfirm(\n\t\t// \t\t\tmw.msg( 'visualdata-jsmodule-forms-delete-data-confirm' )\n\t\t// \t\t)\n\t\t// \t) {\n\t\t// \t\tform.$element.data( { delete: true } );\n\t\t// \t\tform.$element.trigger( 'submit' );\n\t\t// \t}\n\n\t\t// VisualDataFunctions.OOUIAlert(\n\t\t// \tnew OO.ui.HtmlSnippet(\n\t\t// \t\tmw.msg(\"visualdata-jsmodule-visualdata-delete-data-confirm\")\n\t\t// \t),\n\t\t// \t{ size: \"medium\" },\n\t\t// \tfunction () {\n\t\t// \t\tform.$element.data({ delete: true });\n\t\t// \t\tform.$element.submit();\n\t\t// \t}\n\t\t// );\n\t\t// } );\n\n\t\tform.$element.on( 'submit', onSubmit );\n\n\t\tvar editToolbar = Config.canmanageschemas || Config.caneditdata;\n\n\t\tif ( Config.context === 'parserfunction' || !editToolbar ) {\n\t\t\t$( El ).html( form.$element );\n\n\t\t\t// eslint-disable-next-line no-jquery/no-global-selector\n\t\t\t$( '#mw-rcfilters-spinner-wrapper' ).remove();\n\n\t\t\treturn true;\n\t\t}\n\n\t\tvar items = [];\n\t\tToolbarMain = createToolbar( Config.context === 'EditData' );\n\n\t\tvar frameA = new OO.ui.PanelLayout( {\n\t\t\t$content: [ ToolbarMain.$element, form.$element ],\n\t\t\texpanded: false,\n\t\t\tframed: false,\n\t\t\tpadded: false,\n\t\t\tdata: { name: 'visualdata' }\n\t\t} );\n\n\t\titems.push( frameA );\n\n\t\tif ( Config.canmanageschemas ) {\n\t\t\tActionToolbarMain = createActionToolbar( Config.context === 'EditData' );\n\t\t\tToolbarMain.$actions.append( ActionToolbarMain.$element );\n\n\t\t\t// https://gerrit.wikimedia.org/r/plugins/gitiles/oojs/ui/+/c2805c7e9e83e2f3a857451d46c80231d1658a0f/demos/pages/layouts.js\n\t\t\tvar toolbarSchemas = VisualDataSchemas.createToolbarA();\n\t\t\tvar contentSchemas = new OO.ui.PanelLayout( {\n\t\t\t\t$content: $(\n\t\t\t\t\t'<table id=\"visualdata-schemas-datatable\" class=\"visualdata-datatable display\" width=\"100%\"></table>'\n\t\t\t\t),\n\t\t\t\texpanded: false,\n\t\t\t\tframed: true,\n\t\t\t\tpadded: true,\n\t\t\t\tclasses: [ 'VisualDataEditDataOuterStackPanel' ]\n\t\t\t} );\n\n\t\t\tvar frameSchemas = new OO.ui.PanelLayout( {\n\t\t\t\t$content: [ toolbarSchemas.$element, contentSchemas.$element ],\n\t\t\t\texpanded: false,\n\t\t\t\tframed: false,\n\t\t\t\tpadded: false,\n\t\t\t\tdata: { name: 'manage-schemas' }\n\t\t\t} );\n\n\t\t\titems.push( frameSchemas );\n\t\t}\n\n\t\t// if (Config.canmanageforms) {\n\t\t// \tvar toolbarForms = VisualDataForms.createToolbarA();\n\t\t// \tvar contentForms = new OO.ui.PanelLayout({\n\t\t// \t\t$content: $(\n\t\t// \t\t\t'<table id=\"visualdata-forms-datatable\" class=\"visualdata-datatable display\" width=\"100%\"></table>'\n\t\t// \t\t),\n\t\t// \t\texpanded: false,\n\t\t// \t\tpadded: true,\n\t\t// \t});\n\t\t//\n\t\t// \tvar frameForms = new OO.ui.PanelLayout({\n\t\t// \t\t$content: [toolbarForms.$element, contentForms.$element],\n\t\t// \t\texpanded: false,\n\t\t// \t\tframed: true,\n\t\t// \t\tdata: { name: \"manage-forms\" },\n\t\t// \t});\n\t\t//\n\t\t// \titems.push(frameForms);\n\t\t// }\n\n\t\tOuterStack = new OO.ui.StackLayout( {\n\t\t\titems: items,\n\t\t\texpanded: false,\n\t\t\tcontinuous: false\n\t\t\t// classes: [\"visualdataform-wrapper\"],\n\t\t} );\n\n\t\tif ( Config.canmanageschemas ) {\n\t\t\tvar actionToolbarSchemas = createActionToolbar(\n\t\t\t\tConfig.context === 'EditData'\n\t\t\t);\n\t\t\ttoolbarSchemas.$actions.append( actionToolbarSchemas.$element );\n\t\t}\n\n\t\t// if (Config.canmanageforms) {\n\t\t// \tvar actionToolbarForms = createActionToolbar();\n\t\t// \ttoolbarForms.$actions.append(actionToolbarForms.$element);\n\t\t// }\n\n\t\t$( El ).html( OuterStack.$element );\n\n\t\tToolbarMain.initialize();\n\n\t\tif ( Config.canmanageschemas ) {\n\t\t\ttoolbarSchemas.initialize();\n\t\t}\n\n\t\t// if (Config.canmanageforms) {\n\t\t// \ttoolbarForms.initialize();\n\t\t// }\n\n\t\t$( '#mw-rcfilters-spinner-wrapper' ).remove();\n\n\t\treturn true;\n\t}\n\n\tfunction getFormID() {\n\t\treturn FormID;\n\t}\n\n\treturn {\n\t\tinitialize,\n\t\tgetCategories,\n\t\t// updateForms,\n\t\tupdateSchemas,\n\t\tupdatePanels,\n\t\tgetFormID\n\t};\n};\n\n$( function () {\n\tvar schemas = JSON.parse( mw.config.get( 'visualdata-schemas' ) );\n\t// console.log(\"schemas\", schemas);\n\n\tvar submissionData = JSON.parse(\n\t\tmw.config.get( 'visualdata-submissiondata' )\n\t);\n\t// console.log(\"submissionData\", submissionData);\n\n\tvar config = JSON.parse( mw.config.get( 'visualdata-config' ) );\n\t// console.log(\"config\", config);\n\n\tvar windowManager = new VisualDataWindowManager();\n\n\tif ( !submissionData ) {\n\t\tsubmissionData = {};\n\t}\n\n\tvar instances = {};\n\tvar nested = 0;\n\n\t// *** this is called on each DOM mutation and\n\t// on formLoaded\n\tfunction initForms( onPageLoad ) {\n\n\t\t$( '.VisualDataFormItem' ).each( function ( index, el ) {\n\n\t\t\t// same value as old wgMaxTemplateDepth/wgMaxPPExpandDepth\n\t\t\t// infinite nested form\n\t\t\tif ( nested > 40 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( el.id ) {\n\t\t\t\tinstances[ el.id ].initialize();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !onPageLoad ) {\n\t\t\t\tnested++;\n\t\t\t}\n\n\t\t\tvar formData = $( el ).data().formData;\n\n\t\t\tvar form = $.extend(\n\t\t\t\t{\n\t\t\t\t\tfreetext: '',\n\t\t\t\t\tjsonData: {},\n\t\t\t\t\tcategories: [],\n\t\t\t\t\terrors: [],\n\t\t\t\t\tschemas: [],\n\t\t\t\t\toptions: {}\n\t\t\t\t},\n\t\t\t\tformData\n\t\t\t);\n\n\t\t\tif ( !config.caneditdata ) {\n\t\t\t\t$( el ).addClass( 'visualdata-form-wrapper-cannot-edit' );\n\t\t\t\t$( el ).html( mw.msg( 'visualdata-jsmodule-forms-cannot-edit-form' ) );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( onPageLoad && ( index in submissionData ) ) {\n\t\t\t\tform = $.extend(\n\t\t\t\t\tform,\n\t\t\t\t\tsubmissionData[ index ]\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tvar visualDataForm = new VisualDataForms(\n\t\t\t\tel,\n\t\t\t\tconfig,\n\t\t\t\tform,\n\t\t\t\tindex,\n\t\t\t\tschemas,\n\t\t\t\twindowManager,\n\t\t\t\tinitForms\n\t\t\t);\n\n\t\t\tvisualDataForm.initialize();\n\n\t\t\tif ( onPageLoad &&\n\t\t\t\t( index in submissionData ) &&\n\t\t\t\tconfig.context === 'parserfunction' &&\n\t\t\t\tform.errors.length\n\t\t\t) {\n\t\t\t\t$( el ).get( 0 ).scrollIntoView();\n\t\t\t}\n\n\t\t\tinstances[ visualDataForm.getFormID() ] = visualDataForm;\n\t\t} );\n\n\t\tif ( !onPageLoad ) {\n\t\t\tVisualData.setForms( instances );\n\t\t}\n\t}\n\n\tfunction init() {\n\t\tinitForms( true );\n\n\t\t// the following is used to manage initialization\n\t\t// of forms within other forms (as popup buttons)\n\t\t// initialize them as they appear in the DOM\n\t\tvar MutationObserver = window.MutationObserver || window.WebKitMutationObserver;\n\n\t\tif ( MutationObserver ) {\n\t\t\tvar observer = new MutationObserver( function ( mutations, thisObserver ) {\n\t\t\t\tinitForms( false );\n\t\t\t} );\n\n\t\t\tobserver.observe( document.body, {\n\t\t\t\tsubtree: true,\n\t\t\t\tchildList: true,\n\t\t\t\tattributes: false\n\t\t\t} );\n\n\t\t}\n\t}\n\n\tif ( !config.canmanageschemas ) {\n\t\tVisualData.setVars( config, schemas );\n\t\tinit();\n\n\t} else {\n\t\tvar modules = [ 'ext.VisualData.ManageSchemas' ];\n\n\t\t// *** this prevents errors if 'ext.VisualData.Datatables'\n\t\t// was already loaded through DatatableResultPrinter\n\t\t// @TODO the best solution is to use scoped versions\n\t\tif ( !$.fn.DataTable ) {\n\t\t\tmodules.unshift( 'ext.VisualData.DatatablesLite' );\n\t\t}\n\t\tmw.loader.using( modules, function () {\n\t\t\tVisualData.setVars( config, schemas );\n\t\t\tVisualDataSchemas.setVars(\n\t\t\t\tconfig,\n\t\t\t\twindowManager,\n\t\t\t\tschemas\n\t\t\t);\n\t\t\tinit();\n\t\t} );\n\t}\n\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":"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/VisualDataFunctions.js","messages":[],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":25,"column":1,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":1058,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":80,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":80,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":81,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":81,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":82,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":82,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":83,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":83,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":84,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":84,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":97,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":97,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-useless-escape","severity":2,"message":"Unnecessary escape character: \\(.","line":127,"column":52,"nodeType":"Literal","messageId":"unnecessaryEscape","endLine":127,"endColumn":53,"suggestions":[{"messageId":"removeEscape","fix":{"range":[3659,3660],"text":""},"desc":"Remove the `\\`. This maintains the current functionality."},{"messageId":"escapeBackslash","fix":{"range":[3659,3659],"text":"\\"},"desc":"Replace the `\\` with `\\\\` to include the actual backslash character."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-useless-escape","severity":2,"message":"Unnecessary escape character: \\).","line":127,"column":54,"nodeType":"Literal","messageId":"unnecessaryEscape","endLine":127,"endColumn":55,"suggestions":[{"messageId":"removeEscape","fix":{"range":[3661,3662],"text":""},"desc":"Remove the `\\`. This maintains the current functionality."},{"messageId":"escapeBackslash","fix":{"range":[3661,3661],"text":"\\"},"desc":"Replace the `\\` with `\\\\` to include the actual backslash character."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":283,"column":3,"nodeType":"MemberExpression","messageId":"unexpected","endLine":283,"endColumn":14,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"log"},"fix":{"range":[7621,7639],"text":""},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":528,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":528,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":529,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":529,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":530,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":530,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":531,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":531,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":532,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":532,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":533,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":533,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-sequences","severity":2,"message":"Unexpected use of comma operator.","line":703,"column":59,"nodeType":"SequenceExpression","messageId":"unexpectedCommaExpression","endLine":703,"endColumn":60,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":826,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":826,"endColumn":17,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[21914,21988],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'e' is defined but never used.","line":837,"column":47,"nodeType":"Identifier","messageId":"unusedVar","endLine":837,"endColumn":48,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-self-compare","severity":2,"message":"Comparing to itself is potentially pointless.","line":852,"column":39,"nodeType":"BinaryExpression","messageId":"comparingToSelf","endLine":852,"endColumn":54,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":940,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":940,"endColumn":18,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[24457,24509],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":994,"column":10,"nodeType":"Program","messageId":"unexpectedTab","endLine":994,"endColumn":11,"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":"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/VisualDataGeolocation.js","messages":[],"suppressedMessages":[{"ruleId":"no-unused-vars","severity":2,"message":"'VisualDataGeolocation' is assigned a value but never used.","line":24,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":24,"endColumn":28,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'Config' is assigned a value but never used.","line":26,"column":6,"nodeType":"Identifier","messageId":"unusedVar","endLine":26,"endColumn":12,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 158. Maximum allowed is 100.","line":65,"column":1,"nodeType":"Program","messageId":"max","endLine":65,"endColumn":144,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 161. Maximum allowed is 100.","line":70,"column":1,"nodeType":"Program","messageId":"max","endLine":70,"endColumn":147,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 116. Maximum allowed is 100.","line":86,"column":1,"nodeType":"Program","messageId":"max","endLine":86,"endColumn":102,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 147. Maximum allowed is 100.","line":108,"column":1,"nodeType":"Program","messageId":"max","endLine":108,"endColumn":133,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 356. Maximum allowed is 100.","line":112,"column":1,"nodeType":"Program","messageId":"max","endLine":112,"endColumn":342,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 273. Maximum allowed is 100.","line":116,"column":1,"nodeType":"Program","messageId":"max","endLine":116,"endColumn":259,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 102. Maximum allowed is 100.","line":123,"column":1,"nodeType":"Program","messageId":"max","endLine":123,"endColumn":88,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 250. Maximum allowed is 100.","line":124,"column":1,"nodeType":"Program","messageId":"max","endLine":124,"endColumn":236,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 204. Maximum allowed is 100.","line":126,"column":1,"nodeType":"Program","messageId":"max","endLine":126,"endColumn":190,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 186. Maximum allowed is 100.","line":132,"column":1,"nodeType":"Program","messageId":"max","endLine":132,"endColumn":172,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 237. Maximum allowed is 100.","line":141,"column":1,"nodeType":"Program","messageId":"max","endLine":141,"endColumn":223,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 118. Maximum allowed is 100.","line":157,"column":1,"nodeType":"Program","messageId":"max","endLine":157,"endColumn":104,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'data' is assigned a value but never used.","line":183,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":183,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"max-len","severity":1,"message":"This line has a length of 108. Maximum allowed is 100.","line":317,"column":1,"nodeType":"Program","messageId":"max","endLine":317,"endColumn":100,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-inner-declarations","severity":2,"message":"Move function declaration to function body root.","line":438,"column":4,"nodeType":"FunctionDeclaration","messageId":"moveDeclToRoot","endLine":443,"endColumn":5,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-inner-declarations","severity":2,"message":"Move function declaration to function body root.","line":448,"column":4,"nodeType":"FunctionDeclaration","messageId":"moveDeclToRoot","endLine":453,"endColumn":5,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-inner-declarations","severity":2,"message":"Move function declaration to function body root.","line":456,"column":4,"nodeType":"FunctionDeclaration","messageId":"moveDeclToRoot","endLine":461,"endColumn":5,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'property' is defined but never used.","line":474,"column":45,"nodeType":"Identifier","messageId":"unusedVar","endLine":474,"endColumn":53,"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":"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/VisualDataInputConfig.js","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 110. Maximum allowed is 100.","line":840,"column":1,"nodeType":"Program","messageId":"max","endLine":840,"endColumn":96}],"suppressedMessages":[{"ruleId":"no-unused-vars","severity":2,"message":"'VisualDataInputConfig' is assigned a value but never used.","line":26,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":26,"endColumn":28,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'Config' is assigned a value but never used.","line":28,"column":6,"nodeType":"Identifier","messageId":"unusedVar","endLine":28,"endColumn":12,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":295,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":295,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":296,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":296,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":305,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":305,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":306,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":306,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":427,"column":11,"nodeType":"Program","messageId":"unexpectedTab","endLine":427,"endColumn":12,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":428,"column":11,"nodeType":"Program","messageId":"unexpectedTab","endLine":428,"endColumn":12,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":487,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":487,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":488,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":488,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":496,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":496,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":497,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":497,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":651,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":651,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":652,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":652,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":680,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":680,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":681,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":681,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":717,"column":11,"nodeType":"Program","messageId":"unexpectedTab","endLine":717,"endColumn":12,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":718,"column":11,"nodeType":"Program","messageId":"unexpectedTab","endLine":718,"endColumn":12,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":776,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":776,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":777,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":777,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":834,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":834,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":835,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":835,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":839,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":839,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":840,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":840,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":856,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":856,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":857,"column":9,"nodeType":"Program","messageId":"unexpectedTab","endLine":857,"endColumn":10,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'data' is assigned a value but never used.","line":1090,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":1090,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'property' is defined but never used.","line":1161,"column":45,"nodeType":"Identifier","messageId":"unusedVar","endLine":1161,"endColumn":53,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright ©2023, https://wikisphere.org\n */\n\n/* eslint-disable no-tabs */\n\n// @see https://doc.wikimedia.org/oojs-ui/master/js/\n// eslint-disable-next-line no-unused-vars\nconst VisualDataInputConfig = function ( phpConfig, windowManager ) {\n\t// eslint-disable-next-line no-unused-vars\n\tvar Config = phpConfig;\n\tvar WindowManager = windowManager;\n\tvar ProcessDialog;\n\tvar DialogSearchName = 'dialogSearch';\n\tvar processDialogSearch;\n\tvar Model;\n\tvar InputName;\n\tvar CustomInputConfig;\n\tvar Callback;\n\tvar panelLayout;\n\tvar SelectedItems = {};\n\tvar HelpUrl;\n\n\tfunction inArray( val, arr ) {\n\t\treturn arr.includes( val );\n\t}\n\n\t// @TODO add default for each of them\n\tfunction getInputConfig( inputName ) {\n\t\tswitch ( inputName ) {\n\t\t\tcase 'mw.widgets.UserInputWidget':\n\t\t\tcase 'mw.widgets.TitleInputWidget':\n\t\t\tcase 'mw.widgets.DateInputWidget':\n\t\t\tcase 'OO.ui.TextInputWidget':\n\t\t\tcase 'LookupElement':\n\t\t\t\tvar ret = {\n\t\t\t\t\taccessKey: [ 'string', 'The access key' ],\n\t\t\t\t\tautocomplete: [\n\t\t\t\t\t\t'boolean', // 'boolean|string',\n\t\t\t\t\t\t'Should the browser support autocomplete for this field?'\n\t\t\t\t\t],\n\t\t\t\t\tautofocus: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Use an HTML autofocus attribute to instruct the browser to focus this widget.'\n\t\t\t\t\t],\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdir: [ 'string', 'The directionality of the input (ltr/rtl).' ],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tflags: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The name or names of the flags (e.g., 'progressive' or 'primary') to apply.\"\n\t\t\t\t\t],\n\t\t\t\t\ticon: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names.'\n\t\t\t\t\t],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\tindicator: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Symbolic name of the indicator (e.g. ‘required’ or ‘down’).'\n\t\t\t\t\t],\n\t\t\t\t\tinputFilter: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The name of an input filter function. Input filters modify the value of an input before it is accepted'\n\t\t\t\t\t],\n\t\t\t\t\tinputId: [ 'string', 'The value of the input’s HTML id attribute.' ],\n\t\t\t\t\tinvisibleLabel: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Whether the label should be visually hidden (but still accessible to screen-readers).'\n\t\t\t\t\t],\n\t\t\t\t\tlabel: [ 'string', 'The label text' ],\n\t\t\t\t\tlabelPosition: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The position of the inline label relative to that of the value or placeholder text: 'before' or 'after'\"\n\t\t\t\t\t],\n\t\t\t\t\tmaxLength: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Maximum number of characters allowed in the input.'\n\t\t\t\t\t],\n\t\t\t\t\tminLength: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Minimum number of characters allowed in the input.'\n\t\t\t\t\t],\n\t\t\t\t\tname: [ 'string', 'The value of the input’s HTML name attribute.' ],\n\t\t\t\t\tplaceholder: [ 'string', 'Placeholder text' ],\n\t\t\t\t\treadOnly: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Prevent changes to the value of the text input.'\n\t\t\t\t\t],\n\t\t\t\t\tspellcheck: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Should the browser support spellcheck for this field (undefined means leaving it up to the browser).'\n\t\t\t\t\t],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ],\n\t\t\t\t\ttype: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The value of the HTML type attribute: 'text', 'password', 'email', 'url' or 'number'.\"\n\t\t\t\t\t],\n\t\t\t\t\tvalidate: [\n\t\t\t\t\t\t'string', // regex\n\t\t\t\t\t\t'A regular expression that must match the value for it to be considered valid. See <a target=\"_blank\" href=\"https://json-schema.org/understanding-json-schema/reference/regular_expressions\">Regular Expressions</a>'\n\t\t\t\t\t]\n\t\t\t\t\t// value: [\"string\", \"The value of the input.\"],\n\t\t\t\t};\n\n\t\t\t\tswitch ( inputName ) {\n\t\t\t\t\tcase 'mw.widgets.DateInputWidget':\n\t\t\t\t\t\treturn jQuery.extend( ret, {\n\t\t\t\t\t\t\tprecision: [ 'string', \"Date precision to use, 'day' or 'month'\" ],\n\t\t\t\t\t\t\tinputFormat: [\n\t\t\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\t\t'Date format string to use for the textual input field'\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdisplayFormat: [\n\t\t\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\t\t'Date format string to use for the clickable label'\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tlongDisplayFormat: [\n\t\t\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t\t\t'If a custom displayFormat is not specified, use unabbreviated day of the week and month names in the default language-specific displayFormat'\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tplaceholderLabel: [\n\t\t\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\t\t'Placeholder text shown when the widget is not'\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tplaceholderDateFormat: [\n\t\t\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\t\t\"User-visible date format string displayed in the textual input field when it's empty\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tmustBeAfter: [ 'date', 'Validates the date to be after this' ],\n\t\t\t\t\t\t\tmustBeBefore: [ 'date', 'Validates the date to be before this' ]\n\t\t\t\t\t\t} );\n\n\t\t\t\t\tcase 'mw.widgets.TitleInputWidget':\n\t\t\t\t\t\treturn jQuery.extend( ret, {\n\t\t\t\t\t\t\tlimit: [ 'integer', 'Number of results to show' ],\n\t\t\t\t\t\t\tnamespace: [ 'integer', 'Namespace to prepend to queries' ],\n\t\t\t\t\t\t\tmaxLength: [ 'integer', 'Maximum query length' ],\n\t\t\t\t\t\t\trelative: [\n\t\t\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t\t\t'If a namespace is set, display titles relative to it'\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tsuggestions: [ 'boolean', 'Display search suggestions' ],\n\t\t\t\t\t\t\tshowRedirectTargets: [ 'boolean', 'Show the targets of redirects' ],\n\t\t\t\t\t\t\tshowImages: [ 'boolean', 'Show page images' ],\n\t\t\t\t\t\t\tshowDescriptions: [ 'boolean', 'Show page descriptions' ],\n\t\t\t\t\t\t\tshowDisambigsLast: [\n\t\t\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t\t\t'Show disambiguation pages as the last results'\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tshowMissing: [ 'boolean', 'Show missing pages' ],\n\t\t\t\t\t\t\tshowInterwikis: [\n\t\t\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t\t\t'Show pages with a valid interwiki prefix'\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\taddQueryInput: [ 'boolean', \"Add exact user's input query to results\" ],\n\t\t\t\t\t\t\texcludeCurrentPage: [\n\t\t\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t\t\t'Exclude the current page from suggestions'\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\texcludeDynamicNamespaces: [\n\t\t\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t\t\t'Exclude pages whose namespace is negative'\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tvalidateTitle: [ 'boolean', 'Whether the input must be a valid title' ],\n\t\t\t\t\t\t\trequired: [ 'boolean', 'Whether the input must not be empty' ],\n\t\t\t\t\t\t\thighlightSearchQuery: [\n\t\t\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t\t\t'Highlight the partial query the user used for this title'\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t} );\n\n\t\t\t\t\tcase 'mw.widgets.UserInputWidget':\n\t\t\t\t\t\treturn jQuery.extend( ret, {\n\t\t\t\t\t\t\tlimit: [ 'integer', 'Number of results to show' ]\n\t\t\t\t\t\t} );\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\tcase 'OO.ui.ToggleSwitchWidget':\n\t\t\t\treturn {\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ]\n\t\t\t\t\t// value: [\"string\", \"The value of the input.\"],\n\t\t\t\t};\n\n\t\t\tcase 'OO.ui.RadioSelectInputWidget':\n\t\t\t\treturn {\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdir: [ 'string', 'The directionality of the input (ltr/rtl).' ],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\tinputFilter: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The name of an input filter function. Input filters modify the value of an input before it is accepted'\n\t\t\t\t\t],\n\t\t\t\t\tinputId: [ 'string', 'The value of the input’s HTML id attribute.' ],\n\t\t\t\t\tname: [ 'string', 'The value of the input’s HTML name attribute.' ],\n\t\t\t\t\t// options: [\"array\", \"Array of menu options\"],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text' ]\n\t\t\t\t};\n\n\t\t\tcase 'OO.ui.NumberInputWidget':\n\t\t\t\treturn {\n\t\t\t\t\taccessKey: [ 'string', 'The access key' ],\n\t\t\t\t\tautocomplete: [\n\t\t\t\t\t\t'boolean', // 'boolean|string',\n\t\t\t\t\t\t'Should the browser support autocomplete for this field?'\n\t\t\t\t\t],\n\t\t\t\t\tautofocus: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Use an HTML autofocus attribute to instruct the browser to focus this widget.'\n\t\t\t\t\t],\n\t\t\t\t\tbuttonStep: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Delta when using the buttons or Up/Down arrow keys'\n\t\t\t\t\t],\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdir: [ 'string', 'The directionality of the input (ltr/rtl).' ],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tflags: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The name or names of the flags (e.g., 'progressive' or 'primary') to apply.\"\n\t\t\t\t\t],\n\t\t\t\t\ticon: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names.'\n\t\t\t\t\t],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\tindicator: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Symbolic name of the indicator (e.g. ‘required’ or ‘down’).'\n\t\t\t\t\t],\n\t\t\t\t\tinputFilter: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The name of an input filter function. Input filters modify the value of an input before it is accepted'\n\t\t\t\t\t],\n\t\t\t\t\tinputId: [ 'string', 'The value of the input’s HTML id attribute.' ],\n\t\t\t\t\tinvisibleLabel: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Whether the label should be visually hidden (but still accessible to screen-readers).'\n\t\t\t\t\t],\n\t\t\t\t\tlabel: [ 'string', 'The label text' ],\n\t\t\t\t\tlabelPosition: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The position of the inline label relative to that of the value or placeholder text: 'before' or 'after'\"\n\t\t\t\t\t],\n\t\t\t\t\tmax: [ 'number', 'Maximum allowed value' ],\n\t\t\t\t\tmaxLength: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Maximum number of characters allowed in the input.'\n\t\t\t\t\t],\n\t\t\t\t\tmin: [ 'number', 'Minimum allowed value' ],\n\t\t\t\t\tminLength: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Minimum number of characters allowed in the input.'\n\t\t\t\t\t],\n\t\t\t\t\t// minusButton: [\n\t\t\t\t\t// \t'object',\n\t\t\t\t\t// \t'Configuration options to pass to the decrementing button widget'\n\t\t\t\t\t// ],\n\t\t\t\t\tname: [ 'string', 'The value of the input’s HTML name attribute.' ],\n\t\t\t\t\tpageStep: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Delta when using the Page-up/Page-down keys. Defaults to 10 times buttonStep'\n\t\t\t\t\t],\n\t\t\t\t\tplaceholder: [ 'string', 'Placeholder text' ],\n\t\t\t\t\t// plusButton: [\n\t\t\t\t\t// \t'object',\n\t\t\t\t\t// \t'Configuration options to pass to the incrementing button widget.'\n\t\t\t\t\t// ],\n\t\t\t\t\treadOnly: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Prevent changes to the value of the text input.'\n\t\t\t\t\t],\n\t\t\t\t\tshowButtons: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Whether to show the plus and minus buttons.'\n\t\t\t\t\t],\n\t\t\t\t\tspellcheck: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Should the browser support spellcheck for this field (undefined means leaving it up to the browser).'\n\t\t\t\t\t],\n\t\t\t\t\tstep: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'If specified, the field only accepts values that are multiples of this.'\n\t\t\t\t\t],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ],\n\t\t\t\t\ttype: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The value of the HTML type attribute: 'text', 'password', 'email', 'url' or 'number'.\"\n\t\t\t\t\t],\n\t\t\t\t\tvalidate: [\n\t\t\t\t\t\t'string', // regex\n\t\t\t\t\t\t'A regular expression that must match the value for it to be considered valid'\n\t\t\t\t\t]\n\t\t\t\t\t// value: [\"string\", \"The value of the input.\"],\n\t\t\t\t};\n\n\t\t\tcase 'mw.widgets.UsersMultiselectWidget':\n\t\t\tcase 'mw.widgets.TitlesMultiselectWidget':\n\t\t\tcase 'mw.widgets.CategoryMultiselectWidget':\n\t\t\tcase 'OO.ui.TagMultiselectWidget':\n\t\t\tcase 'OO.ui.MenuTagMultiselectWidget':\n\t\t\tcase 'MenuTagSearchMultiselect':\n\t\t\t\tvar ret = {\n\t\t\t\t\tallowArbitrary: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Allow data items to be added even if not present in the menu.'\n\t\t\t\t\t],\n\t\t\t\t\tallowDisplayInvalidTags: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Allow the display of invalid tags.'\n\t\t\t\t\t],\n\t\t\t\t\tallowDuplicates: [ 'boolean', 'Allow duplicate items to be added' ],\n\t\t\t\t\tallowEditTags: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Allow editing of the tags by clicking them'\n\t\t\t\t\t],\n\t\t\t\t\tallowReordering: [ 'boolean', 'Allow reordering of the items' ],\n\t\t\t\t\tallowedValues: [\n\t\t\t\t\t\t'array',\n\t\t\t\t\t\t'An array representing the allowed items by their datas'\n\t\t\t\t\t],\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tdraggable: [ 'boolean', 'The items are draggable.' ],\n\t\t\t\t\tflags: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The name or names of the flags (e.g., 'progressive' or 'primary') to apply.\"\n\t\t\t\t\t],\n\t\t\t\t\ticon: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names.'\n\t\t\t\t\t],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\tindicator: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Symbolic name of the indicator (e.g. ‘required’ or ‘down’).'\n\t\t\t\t\t],\n\t\t\t\t\t// input: [ 'object', 'Configuration options for the input widget' ],\n\n\t\t\t\t\tinputPosition: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Position of the input. Options are: - inline: The input is invisible, but exists inside the tag list, so the user types into the tag groups to add tags. - outline: The input is underneath the tag area. - none: No input supplied'\n\t\t\t\t\t],\n\t\t\t\t\t// items: [\"array\", \"\"],\n\t\t\t\t\t// menu: [ 'object', 'Configuration object for the menu widget' ],\n\n\t\t\t\t\t// options: [\"array\", \"Array of menu options\"],\n\t\t\t\t\torientation: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"Item orientation: 'horizontal' or 'vertical'.\"\n\t\t\t\t\t],\n\t\t\t\t\tplaceholder: [ 'string', 'Placeholder text' ],\n\t\t\t\t\t// selected: [\"array\", \"A set of selected tags\"],\n\t\t\t\t\ttagLimit: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'An optional limit on the number of selected options'\n\t\t\t\t\t],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text' ]\n\t\t\t\t};\n\t\t\t\tswitch ( inputName ) {\n\t\t\t\t\tcase 'OO.ui.MenuTagMultiselectWidget':\n\t\t\t\t\t\treturn jQuery.extend( ret, {\n\t\t\t\t\t\t\tclearInputOnChoose: [\n\t\t\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t\t\t'Clear the text input value when a menu option is chosen'\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t} );\n\t\t\t\t\tcase 'mw.widgets.CategoryMultiselectWidget':\n\t\t\t\t\t\treturn jQuery.extend( ret, {\n\t\t\t\t\t\t\tlimit: [ 'integer', 'Maximum number of results to load' ]\n\t\t\t\t\t\t} );\n\t\t\t\t\tcase 'mw.widgets.TitlesMultiselectWidget':\n\t\t\t\t\t\treturn jQuery.extend( ret, {\n\t\t\t\t\t\t\tclearInputOnChoose: [ 'boolean', 'clear input on choose' ],\n\t\t\t\t\t\t\tinputPosition: [ 'string', 'input position' ],\n\n\t\t\t\t\t\t\tallowEditTags: [ 'boolean', 'clear input on choose' ]\n\t\t\t\t\t\t} );\n\t\t\t\t\tcase 'mw.widgets.UsersMultiselectWidget':\n\t\t\t\t\t\treturn jQuery.extend( ret, {\n\t\t\t\t\t\t\tlimit: [ 'integer', 'Number of results to show' ],\n\t\t\t\t\t\t\t// name: [\n\t\t\t\t\t\t\t// \t'string',\n\t\t\t\t\t\t\t// \t'Name of input to submit results (when used in HTML forms)'\n\t\t\t\t\t\t\t// ],\n\t\t\t\t\t\t\tipAllowed: [ 'boolean', 'Show IP addresses in autocomplete menu' ],\n\t\t\t\t\t\t\t'ipRangeLimits.IPv4': [ 'integer', ' Maximum allowed IPv4 range' ],\n\t\t\t\t\t\t\t'ipRangeLimits.IPv6': [ 'integer', ' Maximum allowed IPv6 range' ]\n\t\t\t\t\t\t} );\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\tcase 'OO.ui.ComboBoxInputWidget':\n\t\t\t\treturn {\n\t\t\t\t\taccessKey: [ 'string', 'The access key' ],\n\t\t\t\t\tautocomplete: [\n\t\t\t\t\t\t'boolean', // |string\n\t\t\t\t\t\t'Should the browser support autocomplete for this field?'\n\t\t\t\t\t],\n\t\t\t\t\tautofocus: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Use an HTML autofocus attribute to instruct the browser to focus this widget.'\n\t\t\t\t\t],\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdir: [ 'string', 'The directionality of the input (ltr/rtl).' ],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tflags: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The name or names of the flags (e.g., 'progressive' or 'primary') to apply.\"\n\t\t\t\t\t],\n\t\t\t\t\ticon: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names.'\n\t\t\t\t\t],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\tindicator: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Symbolic name of the indicator (e.g. ‘required’ or ‘down’).'\n\t\t\t\t\t],\n\t\t\t\t\tinputFilter: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The name of an input filter function. Input filters modify the value of an input before it is accepted'\n\t\t\t\t\t],\n\t\t\t\t\tinputId: [ 'string', 'The value of the input’s HTML id attribute.' ],\n\t\t\t\t\tinvisibleLabel: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Whether the label should be visually hidden (but still accessible to screen-readers).'\n\t\t\t\t\t],\n\t\t\t\t\tlabel: [ 'string', 'The label text' ],\n\t\t\t\t\tlabelPosition: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The position of the inline label relative to that of the value or placeholder text: 'before' or 'after'\"\n\t\t\t\t\t],\n\t\t\t\t\tmaxLength: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Maximum number of characters allowed in the input.'\n\t\t\t\t\t],\n\t\t\t\t\t// menu: [\n\t\t\t\t\t// \t'object',\n\t\t\t\t\t// \t'configuration options to pass to the menu select widget'\n\t\t\t\t\t// ],\n\t\t\t\t\tminLength: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Minimum number of characters allowed in the input.'\n\t\t\t\t\t],\n\t\t\t\t\tname: [ 'string', 'The value of the input’s HTML name attribute.' ],\n\t\t\t\t\t// options: [\n\t\t\t\t\t// \t\"object\",\n\t\t\t\t\t// \t\"onfiguration options to pass to the menu select widget\",\n\t\t\t\t\t// ],\n\t\t\t\t\tplaceholder: [ 'string', 'Placeholder text' ],\n\t\t\t\t\treadOnly: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Prevent changes to the value of the text input.'\n\t\t\t\t\t],\n\t\t\t\t\tspellcheck: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Should the browser support spellcheck for this field (undefined means leaving it up to the browser).'\n\t\t\t\t\t],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ],\n\t\t\t\t\ttype: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The value of the HTML type attribute: 'text', 'password', 'email', 'url' or 'number'.\"\n\t\t\t\t\t],\n\t\t\t\t\tvalidate: [\n\t\t\t\t\t\t'string', // regex\n\t\t\t\t\t\t'A regular expression that must match the value for it to be considered valid'\n\t\t\t\t\t]\n\t\t\t\t\t// value: [\"string\", \"The value of the input.\"],\n\t\t\t\t};\n\n\t\t\tcase 'OO.ui.MultilineTextInputWidget':\n\t\t\t\treturn {\n\t\t\t\t\taccessKey: [ 'string', 'The access key' ],\n\t\t\t\t\tautocomplete: [\n\t\t\t\t\t\t'boolean', // 'boolean|string',\n\t\t\t\t\t\t'Should the browser support autocomplete for this field?'\n\t\t\t\t\t],\n\t\t\t\t\tautofocus: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Use an HTML autofocus attribute to instruct the browser to focus this widget.'\n\t\t\t\t\t],\n\t\t\t\t\tautosize: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Automatically resize the text input to fit its content'\n\t\t\t\t\t],\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdir: [ 'string', 'The directionality of the input (ltr/rtl).' ],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tflags: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The name or names of the flags (e.g., 'progressive' or 'primary') to apply.\"\n\t\t\t\t\t],\n\t\t\t\t\ticon: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names.'\n\t\t\t\t\t],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\tindicator: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Symbolic name of the indicator (e.g. ‘required’ or ‘down’).'\n\t\t\t\t\t],\n\t\t\t\t\tinputFilter: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The name of an input filter function. Input filters modify the value of an input before it is accepted'\n\t\t\t\t\t],\n\t\t\t\t\tinputId: [ 'string', 'The value of the input’s HTML id attribute.' ],\n\t\t\t\t\tinvisibleLabel: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Whether the label should be visually hidden (but still accessible to screen-readers).'\n\t\t\t\t\t],\n\t\t\t\t\tlabel: [ 'string', 'The label text' ],\n\t\t\t\t\tlabelPosition: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The position of the inline label relative to that of the value or placeholder text: 'before' or 'after'\"\n\t\t\t\t\t],\n\t\t\t\t\tmaxLength: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Maximum number of characters allowed in the input.'\n\t\t\t\t\t],\n\t\t\t\t\tmaxRows: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Maximum number of rows to display when autosize is set to true'\n\t\t\t\t\t],\n\t\t\t\t\tminLength: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Minimum number of characters allowed in the input.'\n\t\t\t\t\t],\n\t\t\t\t\tname: [ 'string', 'The value of the input’s HTML name attribute.' ],\n\t\t\t\t\tplaceholder: [ 'string', 'Placeholder text' ],\n\t\t\t\t\treadOnly: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Prevent changes to the value of the text input.'\n\t\t\t\t\t],\n\t\t\t\t\trows: [\n\t\t\t\t\t\t'integer',\n\t\t\t\t\t\t'Number of visible lines in textarea. If used with autosize, specifies minimum number of rows to display.'\n\t\t\t\t\t],\n\t\t\t\t\tspellcheck: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Should the browser support spellcheck for this field (undefined means leaving it up to the browser).'\n\t\t\t\t\t],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ],\n\t\t\t\t\ttype: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"The value of the HTML type attribute: 'text', 'password', 'email', 'url' or 'number'.\"\n\t\t\t\t\t],\n\t\t\t\t\tvalidate: [\n\t\t\t\t\t\t'string', // regex\n\t\t\t\t\t\t'A regular expression that must match the value for it to be considered valid'\n\t\t\t\t\t]\n\t\t\t\t\t// value: [\"string\", \"The value of the input.\"],\n\t\t\t\t};\n\n\t\t\tcase 'OO.ui.MultiselectWidget':\n\t\t\t\treturn {\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\t// items: ['array', 'An array of options to add to the multiselect'],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ]\n\t\t\t\t};\n\n\t\t\tcase 'OO.ui.ButtonSelectWidget':\n\t\t\t\treturn {\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\titems: [ 'array', 'An array of options to add to the multiselect' ],\n\t\t\t\t\tmultiselect: [ 'boolean', 'Allow for multiple selections' ],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ]\n\t\t\t\t};\n\n\t\t\tcase 'OO.ui.CheckboxMultiselectInputWidget':\n\t\t\t\treturn {\n\t\t\t\t\taccessKey: [ 'string', 'The access key' ],\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdir: [ 'string', 'The directionality of the input (ltr/rtl).' ],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\tinputFilter: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The name of an input filter function. Input filters modify the value of an input before it is accepted'\n\t\t\t\t\t],\n\t\t\t\t\tinputId: [ 'string', 'The value of the input’s HTML id attribute.' ],\n\t\t\t\t\tname: [ 'string', 'The value of the input’s HTML name attribute.' ],\n\t\t\t\t\t// options: [\n\t\t\t\t\t// \t'array',\n\t\t\t\t\t// \t'Array of menu options in the format described above.'\n\t\t\t\t\t// ],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ]\n\t\t\t\t};\n\n\t\t\tcase 'OO.ui.DropdownInputWidget':\n\t\t\t\treturn {\n\t\t\t\t\taccessKey: [ 'string', 'The access key' ],\n\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdir: [ 'string', 'The directionality of the input (ltr/rtl).' ],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\t// dropdown: [ 'object', 'Configuration options for DropdownWidget' ],\n\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\n\t\t\t\t\tinputFilter: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The name of an input filter function. Input filters modify the value of an input before it is accepted'\n\t\t\t\t\t],\n\t\t\t\t\tinputId: [ 'string', 'The value of the input’s HTML id attribute.' ],\n\n\t\t\t\t\tname: [ 'string', 'The value of the input’s HTML name attribute.' ],\n\t\t\t\t\t// options: [\n\t\t\t\t\t// \t'array',\n\t\t\t\t\t// \t'Array of menu options in the format described above.'\n\t\t\t\t\t// ],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ]\n\t\t\t\t\t// value: [\"string\", \"The value of the input.\"],\n\t\t\t\t};\n\n\t\t\tcase 'OO.ui.InputWidget':\n\t\t\tcase 'mw.widgets.datetime.DateTimeInputWidget':\n\t\t\t\tvar ret = {\n\t\t\t\t\taccessKey: [ 'string', 'The access key' ],\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdir: [ 'string', 'The directionality of the input (ltr/rtl).' ],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\tinputFilter: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The name of an input filter function. Input filters modify the value of an input before it is accepted'\n\t\t\t\t\t],\n\t\t\t\t\tinputId: [ 'string', 'The value of the input’s HTML id attribute.' ],\n\t\t\t\t\tname: [ 'string', 'The value of the input’s HTML name attribute.' ],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ]\n\t\t\t\t\t// value: [\"string\", \"The value of the input.\"],\n\t\t\t\t};\n\n\t\t\t\tswitch ( inputName ) {\n\t\t\t\t\tcase 'mw.widgets.datetime.DateTimeInputWidget':\n\t\t\t\t\t\treturn jQuery.extend( ret, {\n\t\t\t\t\t\t\ttype: [ 'string', \"Whether to act like a 'date'\" ],\n\t\t\t\t\t\t\trequired: [ 'boolean', 'Whether a value is required' ],\n\t\t\t\t\t\t\tclearable: [ 'boolean', 'Whether to provide for blanking the value.' ],\n\t\t\t\t\t\t\t// value: [\n\t\t\t\t\t\t\t// \t'boolean',\n\t\t\t\t\t\t\t// \t'Default value for the widget'\n\t\t\t\t\t\t\t// ],\n\t\t\t\t\t\t\tmin: [ 'string', ' Minimum allowed date' ],\n\t\t\t\t\t\t\tmax: [ 'string', 'Maximum allowed date' ]\n\t\t\t\t\t\t} );\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\tcase 'ButtonMultiselectWidget':\n\t\t\t\treturn {\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ]\n\t\t\t\t};\n\n\t\t\tcase 'intl-tel-input':\n\t\t\t\t// @see https://github.com/jackocnr/intl-tel-input\n\t\t\t\treturn {\n\t\t\t\t\tallowDropdown: [ 'boolean', 'Whether or not to allow the dropdown' ],\n\t\t\t\t\tautoInsertDialCode: [\n\t\t\t\t\t\t'Boolean',\n\t\t\t\t\t\t'When enabled (requires nationalMode to be disabled), the international dial code will be automatically inserted into the input'\n\t\t\t\t\t],\n\t\t\t\t\tautoPlaceholder: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t\"Set the input's placeholder to an example number for the selected country, and update it if the country changes\"\n\t\t\t\t\t],\n\t\t\t\t\tcustomContainer: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Additional classes to add to the parent div.'\n\t\t\t\t\t],\n\t\t\t\t\tcustomPlaceholder: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Change the placeholder generated by autoPlaceholder. Must return a string'\n\t\t\t\t\t],\n\t\t\t\t\texcludeCountries: [\n\t\t\t\t\t\t'array',\n\t\t\t\t\t\t'In the dropdown, display all countries except the ones you specify here.'\n\t\t\t\t\t],\n\t\t\t\t\tformatOnDisplay: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Format the input value (according to the nationalMode option) during initialisation, and on setNumber. Requires the utilsScript option'\n\t\t\t\t\t],\n\t\t\t\t\tgeoIpLookup: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'When setting initialCountry to \"auto\", you must use this option to specify a custom function that looks up the user\\'s location, and then calls the success callback with the relevant country code'\n\t\t\t\t\t],\n\t\t\t\t\thiddenInput: [ 'string', 'Add a hidden input with the given name.' ],\n\t\t\t\t\tinitialCountry: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Set the initial country selection by specifying its country code'\n\t\t\t\t\t],\n\t\t\t\t\t// 'localizedCountries': [\n\t\t\t\t\t// \t'object',\n\t\t\t\t\t// \t'Allow localisation of country names'\n\t\t\t\t\t// ],\n\t\t\t\t\tnationalMode: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Format numbers in the national format, rather than the international format.'\n\t\t\t\t\t],\n\t\t\t\t\tonlyCountries: [\n\t\t\t\t\t\t'array',\n\t\t\t\t\t\t'In the dropdown, display only the countries you specify'\n\t\t\t\t\t],\n\t\t\t\t\tplaceholderNumberType: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Specify one of the keys from the global enum intlTelInputUtils.numberType'\n\t\t\t\t\t],\n\t\t\t\t\tpreferredCountries: [\n\t\t\t\t\t\t'array',\n\t\t\t\t\t\t'Specify the countries to appear at the top of the list'\n\t\t\t\t\t],\n\t\t\t\t\tseparateDialCode: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Display the country dial code next to the selected flag'\n\t\t\t\t\t],\n\t\t\t\t\tshowFlags: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Set this to false to hide the flags e.g. for political reasons'\n\t\t\t\t\t],\n\t\t\t\t\tutilsScript: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Enable formatting/validation etc. by specifying the URL of the included utils.js script (or alternatively just point it to the file on cdnjs.com)'\n\t\t\t\t\t]\n\t\t\t\t};\n\n\t\t\tcase 'RatingWidget':\n\t\t\t\treturn {\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ]\n\t\t\t\t};\n\n\t\t\tcase 'VisualEditor':\n\t\t\t\treturn {\n\t\t\t\t\tclasses: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The names of the CSS classes to apply to the element.'\n\t\t\t\t\t]\n\t\t\t\t\t// contentModel: [ 'string', 'Output (wikitext or html)' ],\n\t\t\t\t};\n\n\t\t\tcase 'OO.ui.SelectFileWidget':\n\t\t\t\treturn {\n\t\t\t\t\taccept: [ 'array', 'MIME types to accept.' ],\n\t\t\t\t\taccessKey: [ 'string', 'The access key' ],\n\t\t\t\t\t// button: [\n\t\t\t\t\t// \t'object',\n\t\t\t\t\t// \t'Config to pass to select file button.'\n\t\t\t\t\t// ],\n\t\t\t\t\t// @TODO uncomment ...\n\t\t\t\t\t// buttonOnly: [\n\t\t\t\t\t// \t'boolean',\n\t\t\t\t\t// \t'Show only the select file button, no info field. Requires showDropTarget to be false'\n\t\t\t\t\t// ],\n\t\t\t\t\tdir: [ 'string', 'The directionality of the input (ltr/rtl).' ],\n\t\t\t\t\tdisabled: [ 'boolean', 'Disable the widget.' ],\n\t\t\t\t\tdroppable: [ 'boolean', 'Whether to accept files by drag and drop' ],\n\t\t\t\t\ticon: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The symbolic name of the icon (e.g., ‘remove’ or ‘menu’), or a map of symbolic names.'\n\t\t\t\t\t],\n\t\t\t\t\tid: [ 'string', 'The HTML id attribute used in the rendered tag.' ],\n\t\t\t\t\tinputFilter: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'The name of an input filter function. Input filters modify the value of an input before it is accepted'\n\t\t\t\t\t],\n\t\t\t\t\tinputId: [ 'string', 'The value of the input’s HTML id attribute.' ],\n\t\t\t\t\t// multiple: [\n\t\t\t\t\t// \t'boolean',\n\t\t\t\t\t// \t'Allow multiple files to be selected'\n\t\t\t\t\t// ],\n\t\t\t\t\tinvisibleLabel: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Whether the label should be visually hidden (but still accessible to screen-readers).'\n\t\t\t\t\t],\n\t\t\t\t\tname: [ 'string', 'The value of the input’s HTML name attribute.' ],\n\t\t\t\t\tnotsupported: [\n\t\t\t\t\t\t'string',\n\t\t\t\t\t\t'Text to display when file support is missing in the browser.'\n\t\t\t\t\t],\n\t\t\t\t\tplaceholder: [ 'string', 'Placeholder text' ],\n\t\t\t\t\tshowDropTarget: [\n\t\t\t\t\t\t'boolean',\n\t\t\t\t\t\t'Whether to show a drop target. Requires droppable to be true.'\n\t\t\t\t\t],\n\t\t\t\t\ttext: [ 'string', 'Text to insert' ],\n\t\t\t\t\tthumbnailSizeLimit: [\n\t\t\t\t\t\t'number',\n\t\t\t\t\t\t'File size limit in MiB above which to not try and show a preview (for performance)'\n\t\t\t\t\t],\n\t\t\t\t\ttitle: [ 'string', 'The title text.' ]\n\t\t\t\t\t// value: [\"string\", \"The value of the input.\"],\n\t\t\t\t};\n\t\t}\n\t}\n\n\tfunction createToolbarB() {\n\t\tvar toolFactory = new OO.ui.ToolFactory();\n\t\tvar toolGroupFactory = new OO.ui.ToolGroupFactory();\n\n\t\tvar toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory, {\n\t\t\tactions: true\n\t\t} );\n\n\t\tvar onSelect = function () {\n\t\t\tvar toolName = this.getName();\n\n\t\t\tswitch ( toolName ) {\n\t\t\t\tcase 'addfield':\n\t\t\t\t\topenSearchDialog();\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis.setActive( false );\n\t\t};\n\n\t\tvar toolGroup = [\n\t\t\t{\n\t\t\t\tname: 'addfield',\n\t\t\t\ticon: 'add',\n\t\t\t\ttitle: mw.msg( 'visualdata-jsmodule-inputconfig-addremoveoptions' ),\n\t\t\t\tonSelect: onSelect\n\t\t\t}\n\t\t];\n\t\tVisualDataFunctions.createToolGroup( toolFactory, 'group', toolGroup );\n\n\t\ttoolbar.setup( [\n\t\t\t{\n\t\t\t\tname: 'my-group',\n\t\t\t\t// type: \"bar\",\n\t\t\t\t// label: \"Create property\",\n\t\t\t\tinclude: [ { group: 'group' } ]\n\t\t\t}\n\t\t] );\n\n\t\treturn toolbar;\n\t}\n\n\t// @see https://gerrit.wikimedia.org/r/plugins/gitiles/oojs/ui/+/c2805c7e9e83e2f3a857451d46c80231d1658a0f/demos/classes/SearchWidgetDialog.js\n\tfunction ProcessDialogSearch( config ) {\n\t\tProcessDialogSearch.super.call( this, config );\n\t}\n\tOO.inheritClass( ProcessDialogSearch, OO.ui.ProcessDialog );\n\tProcessDialogSearch.static.name = DialogSearchName;\n\tProcessDialogSearch.static.title = mw.msg(\n\t\t'visualdata-jsmodule-inputconfig-selectfield'\n\t);\n\tProcessDialogSearch.prototype.initialize = function () {\n\t\tProcessDialogSearch.super.prototype.initialize.apply( this, arguments );\n\t\tvar self = this;\n\t\tthis.selectedItems = Object.keys( SelectedItems );\n\n\t\tvar obj = ( !CustomInputConfig ? getInputConfig( InputName ) :\n\t\t\tCustomInputConfig( InputName ) );\n\n\t\tfunction getItems( value ) {\n\t\t\tvar values = Object.keys( obj );\n\t\t\tif ( value ) {\n\t\t\t\tvar valueLowerCase = value.toLowerCase();\n\t\t\t\tvalues = values.filter(\n\t\t\t\t\t( x ) => x.toLowerCase().includes( valueLowerCase )\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn VisualDataFunctions.sort( values ).map( ( x ) => {\n\t\t\t\tvar menuOptionWidget = new OO.ui.MenuOptionWidget( {\n\t\t\t\t\tdata: x,\n\t\t\t\t\tlabel: x,\n\t\t\t\t\tselected: inArray( x, self.selectedItems )\n\t\t\t\t} );\n\n\t\t\t\treturn menuOptionWidget;\n\t\t\t} );\n\t\t}\n\n\t\tvar searchWidget = new OO.ui.SearchWidget( {\n\t\t\t// id: 'visualdata-import-search-widget'\n\t\t} );\n\n\t\tsearchWidget.results.addItems( getItems() );\n\n\t\t// searchWidget.getResults() is a SelectWidget\n\t\t// https://doc.wikimedia.org/oojs-ui/master/js/#!/api/OO.ui.SelectWidget\n\t\tvar searchWidgetResults = searchWidget.getResults();\n\t\tsearchWidgetResults.multiselect = true;\n\n\t\t// this.searchWidgetResults = searchWidgetResults;\n\n\t\t// we don't rely anymore on searchWidgetResults.findSelectedItems()\n\t\t// to handle non-visible highlighted items\n\t\tsearchWidgetResults.on( 'press', function ( value ) {\n\t\t\tif ( value === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( inArray( value.data, self.selectedItems ) ) {\n\t\t\t\tself.selectedItems.splice( self.selectedItems.indexOf( value.data ), 1 );\n\t\t\t} else {\n\t\t\t\tself.selectedItems.push( value.data );\n\t\t\t}\n\t\t} );\n\n\t\tsearchWidget.onQueryChange = function ( value ) {\n\t\t\tsearchWidget.results.clearItems();\n\t\t\tsearchWidget.results.addItems( getItems( value ) );\n\t\t};\n\n\t\tthis.$body.append( [ searchWidget.$element ] );\n\t};\n\n\tProcessDialogSearch.prototype.getBodyHeight = function () {\n\t\treturn 300;\n\t};\n\n\tProcessDialogSearch.static.actions = [\n\t\t{\n\t\t\taction: 'save',\n\t\t\tmodes: 'edit',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-done' ),\n\t\t\tflags: [ 'primary', 'progressive' ]\n\t\t},\n\t\t{\n\t\t\t// modes: \"edit\",\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-cancel' ),\n\t\t\tflags: [ 'safe', 'close' ]\n\t\t}\n\t];\n\tProcessDialogSearch.prototype.getActionProcess = function ( action ) {\n\t\tvar dialog = this;\n\n\t\tif ( action === 'save' ) {\n\t\t\t// var items = dialog.searchWidgetResults.findSelectedItems();\n\t\t\t// var selectedItems = items.map( ( x ) => x.data );\n\n\t\t\t// remove unselected properties\n\t\t\tfor ( var key in SelectedItems ) {\n\t\t\t\tif ( !inArray( key, dialog.selectedItems ) ) {\n\t\t\t\t\tdelete SelectedItems[ key ];\n\t\t\t\t\tdelete Model[ key ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// add new properties\n\t\t\tfor ( var key of dialog.selectedItems ) {\n\t\t\t\tif ( !( key in SelectedItems ) ) {\n\t\t\t\t\tSelectedItems[ key ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpanelLayout.populateFieldset();\n\t\t}\n\n\t\treturn new OO.ui.Process( function () {\n\t\t\tdialog.close( { action: action } );\n\t\t} );\n\n\t\t// return ProcessDialog.super.prototype.getActionProcess.call( this, action );\n\t};\n\tProcessDialogSearch.prototype.getTeardownProcess = function ( data ) {\n\t\treturn ProcessDialogSearch.super.prototype.getTeardownProcess\n\t\t\t.call( this, data )\n\t\t\t.first( function () {\n\t\t\t\tWindowManager.removeActiveWindow();\n\t\t\t}, this );\n\t};\n\n\tfunction openSearchDialog() {\n\t\tprocessDialogSearch = new ProcessDialogSearch( {\n\t\t\tsize: 'medium',\n\t\t\tclasses: [ 'visualdata-search-dialog' ]\n\t\t\t// data: { label: label }\n\t\t} );\n\n\t\tWindowManager.newWindow( processDialogSearch );\n\t}\n\n\tfunction PanelLayout( config ) {\n\t\tPanelLayout.super.call( this, config );\n\n\t\t/*\n\t\tthis.messageWidget = new OO.ui.MessageWidget({\n\t\t\ttype: \"notice\",\n\t\t\tlabel: new OO.ui.HtmlSnippet(\n\t\t\t\tmw.msg(\"visualdata-jsmodule-visualdata-no-properties\")\n\t\t\t),\n\t\t});\n*/\n\n\t\tthis.fieldset = new OO.ui.FieldsetLayout( {\n\t\t\tlabel: ''\n\t\t} );\n\n\t\tthis.populateFieldset();\n\n\t\tthis.$element.append( this.fieldset.$element );\n\t\t// this.$element.append(this.messageWidget.$element);\n\t}\n\n\tOO.inheritClass( PanelLayout, OO.ui.PanelLayout );\n\tPanelLayout.prototype.populateFieldset = function () {\n\t\tthis.fieldset.clearItems();\n\n\t\t// eslint-disable-next-line no-unused-vars\n\t\tvar data = this.data;\n\t\tvar items = [];\n\t\tvar obj = ( !CustomInputConfig ? getInputConfig( InputName ) :\n\t\t\tCustomInputConfig( InputName ) );\n\n\t\tfor ( var i in obj ) {\n\t\t\tif ( !( i in SelectedItems ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tvar inputName;\n\t\t\tvar config = {};\n\t\t\tvar type = obj[ i ][ 0 ];\n\t\t\tswitch ( type ) {\n\t\t\t\tcase 'boolean':\n\t\t\t\t\tinputName = 'OO.ui.ToggleSwitchWidget';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'string':\n\t\t\t\t\tinputName = 'OO.ui.TextInputWidget';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'number':\n\t\t\t\tcase 'integer':\n\t\t\t\t\tinputName = 'OO.ui.NumberInputWidget';\n\t\t\t\t\tconfig.type = 'number';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'date':\n\t\t\t\t\tinputName = 'mw.widgets.DateInputWidget';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\tinputName = 'OO.ui.TagMultiselectWidget';\n\t\t\t\t\tbreak;\n\n\t\t\t\t// not implemented\n\t\t\t\tcase 'object':\n\t\t\t\t\tcontinue;\n\n\t\t\t\tdefault:\n\t\t\t\t\tinputName = 'OO.ui.TextInputWidget';\n\t\t\t}\n\n\t\t\tif ( typeof SelectedItems[ i ] !== 'undefined' ) {\n\t\t\t\tconfig.value = SelectedItems[ i ];\n\t\t\t}\n\n\t\t\tvar inputWidget = VisualDataFunctions.inputInstanceFromName(\n\t\t\t\tinputName,\n\t\t\t\tconfig\n\t\t\t);\n\t\t\tModel[ i ] = { input: inputWidget, type: type };\n\n\t\t\titems.push(\n\t\t\t\tnew OO.ui.FieldLayout( inputWidget, {\n\t\t\t\t\tlabel: i,\n\t\t\t\t\talign: 'top',\n\t\t\t\t\thelp: new OO.ui.HtmlSnippet( obj[ i ][ 1 ] ),\n\t\t\t\t\thelpInline: true,\n\t\t\t\t\tclasses: []\n\t\t\t\t} )\n\t\t\t);\n\t\t}\n\n\t\titems = items.filter( function ( x ) {\n\t\t\treturn !( 'items' in x ) || x.items.length;\n\t\t} );\n\n\t\tthis.isEmpty = !items.length;\n\n\t\tthis.fieldset.addItems( items );\n\t};\n\n\t// eslint-disable-next-line no-unused-vars\n\tPanelLayout.prototype.addItem = function ( property ) {\n\t\tthis.populateFieldset();\n\t};\n\n\tfunction ProcessDialog( config ) {\n\t\tProcessDialog.super.call( this, config );\n\t}\n\tOO.inheritClass( ProcessDialog, OO.ui.ProcessDialog );\n\n\tProcessDialog.static.name = 'myDialog';\n\t// ProcessDialog.static.title = mw.msg(\n\t// \"visualdata-jsmodule-manageproperties-define-property\"\n\t// );\n\tProcessDialog.static.actions = [\n\t\t{\n\t\t\taction: 'save',\n\t\t\tmodes: 'edit',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-save' ),\n\t\t\tflags: [ 'primary', 'progressive' ]\n\t\t},\n\t\t{\n\t\t\tmodes: 'edit',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-cancel' ),\n\t\t\tflags: [ 'safe', 'close' ]\n\t\t}\n\t];\n\n\tfunction createActionToolbar() {\n\t\t// see https://gerrit.wikimedia.org/r/plugins/gitiles/oojs/ui/+/refs/tags/v0.40.4/demos/pages/toolbars.js\n\t\tvar toolFactory = new OO.ui.ToolFactory();\n\t\tvar toolGroupFactory = new OO.ui.ToolGroupFactory();\n\n\t\tvar toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory, {\n\t\t\tactions: false\n\t\t} );\n\n\t\tvar onSelect = function () {\n\t\t\twindow.open( HelpUrl, '_blank' ).focus();\n\t\t\tthis.setActive( false );\n\t\t};\n\n\t\tvar toolGroup = [\n\t\t\t{\n\t\t\t\tname: 'help-button',\n\t\t\t\ticon: 'helpNotice',\n\t\t\t\t// title: mw.msg( 'visualdata-jsmodule-forms-toolbars-help-button' ),\n\t\t\t\tonSelect: onSelect\n\t\t\t}\n\t\t];\n\n\t\t// @see https://www.mediawiki.org/wiki/OOUI/Toolbars\n\t\ttoolbar.setup( [\n\t\t\t{\n\t\t\t\ttype: 'bar',\n\t\t\t\tinclude: [ 'help-button' ]\n\t\t\t}\n\t\t] );\n\n\t\tVisualDataFunctions.createToolGroup(\n\t\t\ttoolFactory,\n\t\t\t'selectSwitch',\n\t\t\ttoolGroup\n\t\t);\n\n\t\treturn toolbar;\n\t}\n\n\tProcessDialog.prototype.initialize = function () {\n\t\tProcessDialog.super.prototype.initialize.apply( this, arguments );\n\t\tvar toolbar = createToolbarB();\n\n\t\tif ( HelpUrl ) {\n\t\t\tvar actionToolbar = createActionToolbar();\n\t\t\ttoolbar.$actions.append( actionToolbar.$element );\n\t\t}\n\n\t\tpanelLayout = new PanelLayout( {\n\t\t\texpanded: false,\n\t\t\tpadded: true,\n\t\t\tclasses: [ 'visualdata-forms-fields-contentframe' ],\n\t\t\tdata: {}\n\t\t} );\n\n\t\tvar frameA = new OO.ui.PanelLayout( {\n\t\t\t$content: [ toolbar.$element, panelLayout.$element ],\n\t\t\texpanded: false,\n\t\t\t// framed: false,\n\t\t\tpadded: false,\n\t\t\tdata: { name: 'manageforms' }\n\t\t} );\n\n\t\tthis.$body.append( frameA.$element );\n\t};\n\n\tProcessDialog.prototype.getActionProcess = function ( action ) {\n\t\tvar dialog = this;\n\n\t\tswitch ( action ) {\n\t\t\tcase 'save':\n\t\t\t\tvar obj = {};\n\t\t\t\tfor ( var i in Model ) {\n\t\t\t\t\tobj[ i ] = VisualDataFunctions.castType(\n\t\t\t\t\t\tModel[ i ].input.getValue(),\n\t\t\t\t\t\tModel[ i ].type\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tCallback.setValue( obj );\n\t\t\t\treturn new OO.ui.Process( function () {\n\t\t\t\t\tdialog.close( { action: action } );\n\t\t\t\t} );\n\t\t}\n\n\t\treturn ProcessDialog.super.prototype.getActionProcess.call( this, action );\n\t};\n\n\tProcessDialog.prototype.getTeardownProcess = function ( data ) {\n\t\treturn ProcessDialog.super.prototype.getTeardownProcess\n\t\t\t.call( this, data )\n\t\t\t.first( function () {\n\t\t\t\tWindowManager.removeActiveWindow();\n\t\t\t}, this );\n\t};\n\n\t/**\n\t * Override getBodyHeight to create a tall dialog relative to the screen.\n\t *\n\t * @return {number} Body height\n\t */\n\tProcessDialog.prototype.getBodyHeight = function () {\n\t\t// see here https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n\t\t// this.page1.content.$element.outerHeight( true );\n\t\treturn window.innerHeight - 100;\n\t};\n\n\tfunction openDialog( callback, inputName, helpUrl, customInputConfig ) {\n\t\tModel = {};\n\t\tCallback = callback;\n\t\tSelectedItems = callback.getValue();\n\t\tHelpUrl = helpUrl;\n\n\t\t// @TODO update once a form key -> value is used\n\t\t// for the options widget of available inputs dropdown\n\t\tInputName = inputName.split( / / )[ 0 ];\n\t\tCustomInputConfig = customInputConfig;\n\n\t\tvar processDialog = new ProcessDialog( {\n\t\t\tsize: 'large'\n\t\t} );\n\n\t\tWindowManager.newWindow( processDialog, {\n\t\t\ttitle:\n\t\t\t\tmw.msg(\n\t\t\t\t\t// The following messages are used here:\n\t\t\t\t\t// * visualdata-jsmodule-manageproperties-define-property\n\t\t\t\t\t// * visualdata-jsmodule-manageproperties-define-property - [name]\n\t\t\t\t\t'visualdata-jsmodule-inputconfig-dialog-label'\n\t\t\t\t) + ( inputName ? ' - ' + inputName : '' )\n\t\t} );\n\t}\n\n\treturn {\n\t\topenDialog\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":"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/VisualDataMaps.js","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 108. Maximum allowed is 100.","line":35,"column":1,"nodeType":"Program","messageId":"max","endLine":35,"endColumn":103},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":119,"column":2,"nodeType":"CallExpression","endLine":119,"endColumn":24}],"suppressedMessages":[{"ruleId":"no-unused-vars","severity":2,"message":"'el' is defined but never used.","line":24,"column":35,"nodeType":"Identifier","messageId":"unusedVar","endLine":24,"endColumn":37,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'tiles' is assigned a value but never used.","line":60,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":60,"endColumn":12,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in '_popup'.","line":94,"column":38,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":94,"endColumn":50,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in '_popup'.","line":97,"column":44,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":97,"endColumn":56,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2025, https://wikisphere.org\n */\n\n/* eslint-disable no-unused-vars */\n\nconst VisualDataMaps = function ( el ) {\n\n\tvar getFilteredMarkers = function ( markersArr ) {\n\t\tvar latLngs = markersArr.map( ( marker ) => marker.getLatLng() );\n\n\t\tvar center = L.latLng(\n\t\t\tlatLngs.reduce( ( sum, latLng ) => sum + latLng.lat, 0 ) / latLngs.length,\n\t\t\tlatLngs.reduce( ( sum, latLng ) => sum + latLng.lng, 0 ) / latLngs.length\n\t\t);\n\n\t\tvar distances = latLngs.map( ( latLng ) => center.distanceTo( latLng ) );\n\t\tvar averageDistance = distances.reduce( ( sum, distance ) => sum + distance, 0 ) / distances.length;\n\n\t\treturn markersArr.filter( ( marker ) =>\n\t\t\tcenter.distanceTo( marker.getLatLng() ) <= averageDistance\n\t\t);\n\t};\n\n\treturn {\n\t\tgetFilteredMarkers\n\t};\n};\n\n$( function () {\n\t// @see https://leafletjs.com/reference.html#popup-option\n\t// @see view-source:https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.10000.html\n\n\tfunction init( $el ) {\n\t\tvar visualDataMaps = new VisualDataMaps( $el );\n\n\t\tvar data = $el.data();\n\t\tvar params = data.params;\n\t\tvar json = data.json;\n\n\t\tvar map = L.map( $el.get( 0 ), params.map );\n\n\t\tvar tiles = L.tileLayer(\n\t\t\t'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n\t\t\tparams.tileLayer\n\t\t).addTo( map );\n\n\t\tvar markers = ( !params.markerCluster ?\n\t\t\tL.layerGroup() :\n\t\t\tL.markerClusterGroup( params.markerClusterGroup ) );\n\n\t\t// for some reason the images aren't loaded\n\t\t// relatively from leaflet.js\n\t\tvar mw_extensionAssetsPath = mw.config.get( 'wgExtensionAssetsPath' );\n\t\tvar basePath = mw_extensionAssetsPath + '/VisualData/resources/Leaflet/images/';\n\n\t\tfor ( var key of [ 'iconUrl', 'iconRetinaUrl', 'shadowUrl' ] ) {\n\t\t\tparams.icon[ key ] = basePath + params.icon[ key ];\n\t\t}\n\n\t\tvar markersArr = [ ];\n\t\tfor ( var value of json ) {\n\t\t\tvar markerOptions = params.marker;\n\n\t\t\tmarkerOptions.icon = L.icon( params.icon );\n\n\t\t\tif ( params.markerTooltip && value.name ) {\n\t\t\t\tmarkerOptions.title = value.name;\n\t\t\t}\n\n\t\t\tvar marker = L.marker(\n\t\t\t\tL.latLng( value.latitude, value.longitude ),\n\t\t\t\tmarkerOptions\n\t\t\t);\n\n\t\t\t// eslint-disable-next-line no-underscore-dangle\n\t\t\tif ( value.name || value.popup || value._popup ) {\n\t\t\t\tvar customPopup = L.popup( params.popup );\n\t\t\t\t// eslint-disable-next-line no-underscore-dangle\n\t\t\t\tcustomPopup.setContent( value.popup || value._popup || value.name );\n\t\t\t\tmarker.bindPopup( customPopup );\n\t\t\t}\n\n\t\t\tmarkers.addLayer( marker );\n\t\t\tmarkersArr.push( marker );\n\t\t}\n\n\t\tmap.addLayer( markers );\n\n\t\tvar filteredMarkers = visualDataMaps.getFilteredMarkers( markersArr );\n\t\tif ( filteredMarkers.length > 1 ) {\n\t\t\tvar featureGroup = L.featureGroup( filteredMarkers );\n\t\t\tmap.fitBounds( featureGroup.getBounds(), params.map.fitBounds );\n\n\t\t} else if ( markersArr.length === 1 ) {\n\t\t\tmap.setView( L.latLng( json[ 0 ].latitude, json[ 0 ].longitude ),\n\t\t\t\tparams.map.zoom\n\t\t\t);\n\t\t}\n\t}\n\n\t$( '.visualdata-map' ).each( function () {\n\t\tinit( $( this ) );\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":"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/VisualDataPrintouts.js","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 107. Maximum allowed is 100.","line":43,"column":1,"nodeType":"Program","messageId":"max","endLine":43,"endColumn":99},{"ruleId":"max-len","severity":1,"message":"This line has a length of 144. Maximum allowed is 100.","line":56,"column":1,"nodeType":"Program","messageId":"max","endLine":56,"endColumn":130},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":71,"column":2,"nodeType":"CallExpression","endLine":71,"endColumn":30},{"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":33}],"suppressedMessages":[{"ruleId":"no-unused-vars","severity":2,"message":"'elIndex' is defined but never used.","line":28,"column":32,"nodeType":"Identifier","messageId":"unusedVar","endLine":28,"endColumn":39,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'elIndex' is defined but never used.","line":34,"column":29,"nodeType":"Identifier","messageId":"unusedVar","endLine":34,"endColumn":36,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright ©2025, https://wikisphere.org\n */\n\n/* eslint-disable no-unused-vars */\n\nconst VisualDataPrintouts = function () {\n\tdayjs.extend( window.dayjs_plugin_utc );\n\tdayjs.extend( window.dayjs_plugin_timezone );\n\n\tfunction handleTimeLinks( el, elIndex ) {\n\t\tvar $el = $( el );\n\t\tvar data = $el.data();\n\t\t$el.text( VisualDataFunctions.dateToLocal( data.datetime, data.format ) );\n\t}\n\n\tfunction handleTables( el, elIndex ) {\n\t\tvar $el = $( el );\n\t\tvar data = $el.data();\n\n\t\tvar headers = $el.find( 'th' ).map( function () {\n\t\t\treturn $( this ).text().trim();\n\t\t} ).get();\n\n\t\tvar reversePrintouts = VisualDataFunctions.objectEntries(\n\t\t\tVisualDataFunctions.objectEntries( data.printouts ).map( ( [ key, value ] ) => [ value, key ] )\n\t\t);\n\n\t\t$( el ).find( 'tr' ).each( function () {\n\t\t\t$( this ).find( 'td' ).each( function ( i ) {\n\t\t\t\tvar header = headers[ i ];\n\t\t\t\tvar printout = reversePrintouts[ header ];\n\t\t\t\tif ( !printout ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar format = data.mapPathSchema[ printout ].format;\n\t\t\t\tif ( VisualDataFunctions.inArray( format, [ 'time', 'date', 'datetime', 'datetime-local' ] ) ) {\n\t\t\t\t\tvar $cell = $( this );\n\t\t\t\t\t$( this ).text( VisualDataFunctions.dateToLocalPrintout( $cell.text().trim(), format, data.printoutsOptions[ printout ] ) );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn {\n\t\thandleTables,\n\t\thandleTimeLinks\n\t};\n};\n\n$( function () {\n\tvar visualDataPrintouts = new VisualDataPrintouts();\n\n\t$( '.visualdata.wikitable' ).each( function ( index ) {\n\t\tvisualDataPrintouts.handleTables( this, index );\n\t} );\n\n\t$( '.visualdata-time-element' ).each( function ( index ) {\n\t\tvisualDataPrintouts.handleTimeLinks( this, index );\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":"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/VisualDataProcessModel.js","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 116. Maximum allowed is 100.","line":222,"column":1,"nodeType":"Program","messageId":"max","endLine":222,"endColumn":105},{"ruleId":"no-jquery/no-sizzle","severity":1,"message":"Selector extensions are not allowed","line":226,"column":11,"nodeType":"CallExpression","endLine":226,"endColumn":85}],"suppressedMessages":[{"ruleId":"no-unused-vars","severity":2,"message":"'VisualDataProcessModel' is assigned a value but never used.","line":25,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":25,"endColumn":29,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":87,"column":7,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":87,"endColumn":58,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":91,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":91,"endColumn":17,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[2420,2473],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":111,"column":5,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":111,"endColumn":20,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":121,"column":3,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":121,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":129,"column":4,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":129,"endColumn":20,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"new-cap","severity":2,"message":"A constructor name should not start with a lowercase letter.","line":139,"column":26,"nodeType":"NewExpression","messageId":"lower","endLine":139,"endColumn":30,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":157,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":157,"endColumn":17,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[3983,4014],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":195,"column":10,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":195,"endColumn":62,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":198,"column":26,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":198,"endColumn":42,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":199,"column":7,"nodeType":"MemberExpression","messageId":"unexpectedUnderscore","endLine":199,"endColumn":23,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":205,"column":15,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":205,"endColumn":20,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":214,"column":5,"nodeType":"MemberExpression","messageId":"unexpected","endLine":214,"endColumn":18,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[5965,5988],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":258,"column":11,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":258,"endColumn":37,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'path_'.","line":286,"column":10,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":286,"endColumn":78,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":345,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":345,"endColumn":19,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[9120,9151],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2023, https://wikisphere.org\n */\n\n/* eslint-disable no-unused-vars */\n/* eslint-disable no-underscore-dangle */\n\nconst VisualDataProcessModel = function (\n\tcallbackShowError,\n\tForm,\n\tSchemas,\n\tInitialSchemas,\n\tModel,\n\tModelSchemas,\n\tmakeElementId\n) {\n\tvar Flatten;\n\tvar Action;\n\tvar Removed;\n\tvar Errors;\n\n\tasync function getValue( model ) {\n\t\tvar value = 'getValue' in model.input ? model.input.getValue() : '';\n\n\t\tif ( VisualDataFunctions.isPromise( value ) ) {\n\t\t\tvalue = await value;\n\t\t}\n\n\t\tif ( 'validateFunc' in model.input ) {\n\t\t\tvar errorMsg = model.input.validateFunc();\n\t\t\tif ( VisualDataFunctions.isPromise( errorMsg ) ) {\n\t\t\t\terrorMsg = await errorMsg;\n\t\t\t}\n\t\t\tif ( typeof errorMsg === 'string' ) {\n\t\t\t\tthrow new Error( errorMsg );\n\t\t\t}\n\t\t}\n\n\t\tif ( Array.isArray( value ) ) {\n\t\t\tvalue = value.map( ( x ) => castType( x, model ) );\n\t\t} else {\n\t\t\tvalue = castType( value, model );\n\t\t}\n\n\t\treturn value;\n\t}\n\n\tfunction castType( value, model ) {\n\t\t// *** this is an hack to prevent\n\t\t// empty string, alternatively\n\t\t// use required native validation\n\t\t// or \"minLength\": 1\n\n\t\tif ( model.schema.wiki.required ) {\n\t\t\tswitch ( model.schema.type ) {\n\t\t\t\tcase 'number':\n\t\t\t\tcase 'string':\n\t\t\t\t\t// value can be undefined for OO.ui.SelectFileWidget\n\t\t\t\t\tif ( !value || ( typeof value === 'string' && value.trim() === '' ) ) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn VisualDataFunctions.castType( value, model.schema.type );\n\t}\n\n\tasync function formatValue( path, model ) {\n\t\tvar path_ = ( Action === 'submit' ? path : model.path );\n\n\t\tif ( !( 'input' in model ) ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.error( 'input does not exist', path, model );\n\t\t\treturn;\n\t\t}\n\n\t\tvar value = 'getValue' in model.input ? model.input.getValue() : '';\n\n\t\tif ( model.removed ) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( VisualDataFunctions.isPromise( value ) ) {\n\t\t\tvalue = await value;\n\t\t}\n\n\t\tif ( 'validateFunc' in model.input ) {\n\t\t\tvar errorMsg = model.input.validateFunc();\n\t\t\tif ( VisualDataFunctions.isPromise( errorMsg ) ) {\n\t\t\t\terrorMsg = await errorMsg;\n\t\t\t}\n\t\t\tif ( typeof errorMsg === 'string' ) {\n\t\t\t\tErrors[ path_ ] = errorMsg;\n\t\t\t}\n\t\t}\n\n\t\tif ( Array.isArray( value ) ) {\n\t\t\tvalue = value.map( ( x ) => castType( x, model ) );\n\t\t} else {\n\t\t\tvalue = castType( value, model );\n\t\t}\n\n\t\tFlatten[ path_ ] = {\n\t\t\tpathNoIndex: model.pathNoIndex,\n\t\t\tvalue: value,\n\t\t\tmultiselect: model.multiselect,\n\t\t\tschema: model.schema\n\t\t};\n\n\t\tif ( model.isFile ) {\n\t\t\tFlatten[ path_ ].filekey = model.filekey;\n\t\t\t// Flatten[model.path].previousFilaneme = model.previousFilaneme;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\tfunction validate( schemaName, data, schema ) {\n\t\tvar errors = Errors;\n\t\t// eslint-disable-next-line new-cap\n\t\tconst ajv = new window.ajv7( { strict: false, allErrors: true } );\n\n\t\tajv.addFormat( 'email', {\n\t\t\ttype: 'string',\n\t\t\tvalidate: ( value ) => ( !value || /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test( value ) )\n\t\t} );\n\n\t\tajv.addFormat( 'url', {\n\t\t\ttype: 'string',\n\t\t\tvalidate: ( value ) => ( !value || /^(https?:\\/\\/[^\\s/$.?#][^\\s]*)$/.test( value ) )\n\t\t} );\n\n\t\tvar validateAjv;\n\t\ttry {\n\t\t\tvalidateAjv = ajv.compile( schema );\n\n\t\t} catch ( e ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.error( 'validate', e );\n\t\t\tcallbackShowError( schemaName, e.message );\n\n\t\t\t// @MAYBETODO\n\t\t\t// add: \"please report the issue in the talk page\n\t\t\t// of the extension\"\n\t\t\treturn false;\n\t\t}\n\t\tif ( validateAjv( data ) && !Object.keys( errors ).length ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tvar hiddenErrors = {};\n\t\tif ( 'errors' in validateAjv && Array.isArray( validateAjv.errors ) ) {\n\t\t\tvar AjvErrors = [];\n\n\t\t\t// pre-process errors\n\t\t\t// @see https://ajv.js.org/api.html\n\t\t\tfor ( var error of validateAjv.errors ) {\n\t\t\t\tswitch ( error.keyword ) {\n\t\t\t\t\tcase 'uniqueItems':\n\t\t\t\t\t\tif ( !Removed.includes( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.j }` ) ) {\n\t\t\t\t\t\t\tAjvErrors.push( $.extend( VisualDataFunctions.deepCopy( error ), { instancePath: `${ error.instancePath }/${ error.params.i }` } ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( !Removed.includes( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.i }` ) ) {\n\t\t\t\t\t\t\tAjvErrors.push( $.extend( VisualDataFunctions.deepCopy( error ), { instancePath: `${ error.instancePath }/${ error.params.j }` } ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tAjvErrors.push( error );\n\t\t\t\t}\n\t\t\t}\n\t\t\tloopA: for ( var error of AjvErrors ) {\n\t\t\t\tvar path = `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }`;\n\n\t\t\t\t// check if multiselect\n\t\t\t\t// @FIXME add specific reference to arrays\n\t\t\t\tif ( !( path in Flatten ) && /\\/\\d+$/.test( path ) ) {\n\t\t\t\t\tvar path_ = path.split( '/' ).slice( 0, -1 ).join( '/' );\n\n\t\t\t\t\tif ( ( path_ in Flatten ) &&\n\t\t\t\t\t\t( 'multiselect' in Flatten[ path_ ] ) &&\n\t\t\t\t\t\tFlatten[ path_ ].multiselect === true\n\t\t\t\t\t) {\n\t\t\t\t\t\tpath = path_;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor ( var path_ of Removed ) {\n\t\t\t\t\tif ( path === path_ ||\n\t\t\t\t\t\t// @FIXME add specific reference to arrays\n\t\t\t\t\t\t( /\\/\\d+$/.test( path_ ) && path.indexOf( path_ ) === 0 ) ) {\n\t\t\t\t\t\tcontinue loopA;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.error( error );\n\n\t\t\t\tif ( !( path in Flatten ) ) {\n\t\t\t\t\thiddenErrors[ path ] = `${ error.instancePath.slice( 1 ) } ${ error.message }`;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// ignore NaN values if the field is not required\n\t\t\t\tif ( VisualDataFunctions.isNaN( Flatten[ path ].value ) && !Flatten[ path ].schema.wiki.required ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( !$( '#' + jQuery.escapeSelector( makeElementId( path ) ) ).is( ':visible' ) ) {\n\t\t\t\t\thiddenErrors[ path ] = `${ Flatten[ path ].schema.wiki.name } ${ error.message }`;\n\t\t\t\t}\n\n\t\t\t\terrors[ path ] = error.message;\n\t\t\t}\n\t\t}\n\n\t\tif ( !Object.keys( errors ).length && !Object.keys( hiddenErrors ).length ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tcallbackShowError( schemaName, null, errors, hiddenErrors );\n\t\treturn false;\n\t}\n\n\tasync function getValuesRec( path, model ) {\n\t\tswitch ( model.schema.type ) {\n\t\t\tcase 'array':\n\t\t\t\t// @TODO handle tuple\n\t\t\t\tif ( !VisualDataFunctions.isObject( model.items ) ) {\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\t\t\t\tvar items = [];\n\n\t\t\t\t// multiselect\n\t\t\t\tif ( 'schema' in model.items ) {\n\t\t\t\t\titems = await formatValue( path, model.items );\n\n\t\t\t\t} else {\n\t\t\t\t\tvar n = 0;\n\t\t\t\t\tfor ( var ii in model.items ) {\n\t\t\t\t\t\tvar path_ = `${ path }/${ n }`;\n\t\t\t\t\t\tif ( model.items[ ii ].removed ) {\n\t\t\t\t\t\t\tif ( Action !== 'validate' ) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tRemoved.push( path_ );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\titems.push( await getValuesRec( path_, model.items[ ii ] ) );\n\t\t\t\t\t\tn++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t/* set to null only required items */\n\t\t\t\tfor ( var ii in items ) {\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof items[ ii ] === 'string' &&\n\t\t\t\t\t\titems[ ii ].trim() === '' &&\n\t\t\t\t\t\t'minItems' in model.schema &&\n\t\t\t\t\t\tii <= model.schema.minItems\n\t\t\t\t\t) {\n\t\t\t\t\t\titems[ ii ] = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn items;\n\n\t\t\tcase 'object':\n\t\t\t\tvar items = {};\n\t\t\t\tfor ( var ii in model.properties ) {\n\t\t\t\t\tvar path_ = `${ path }/${ VisualDataFunctions.escapeJsonPointer( ii ) }`;\n\n\t\t\t\t\tif ( model.properties[ ii ].removed ) {\n\t\t\t\t\t\tif ( Action !== 'validate' ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tRemoved.push( path_ );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\titems[ ii ] = await getValuesRec( path_, model.properties[ ii ] );\n\t\t\t\t}\n\t\t\t\treturn items;\n\n\t\t\tdefault:\n\t\t\t\treturn await formatValue( path, model );\n\t\t}\n\t}\n\n\tasync function getFormModel() {\n\t\tvar ret = {};\n\t\tfor ( var i in Model ) {\n\t\t\tret[ i ] = Model[ i ].getValue();\n\n\t\t\tif ( VisualDataFunctions.isPromise( ret[ i ] ) ) {\n\t\t\t\tret[ i ] = await ret[ i ];\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t}\n\n\tasync function getModel( action, schemaName ) {\n\t\tAction = action;\n\t\tFlatten = {};\n\t\tRemoved = [];\n\t\tErrors = {};\n\n\t\tvar ret = {};\n\t\tswitch ( action ) {\n\t\t\tcase 'validate':\n\t\t\t\tcallbackShowError( null );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( var schemaName in ModelSchemas ) {\n\t\t\t\t\t\tif ( !Form.schemas.includes( schemaName ) ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tret[ schemaName ] = await getValuesRec(\n\t\t\t\t\t\t\tVisualDataFunctions.escapeJsonPointer( schemaName ),\n\t\t\t\t\t\t\tModelSchemas[ schemaName ]\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// removeNulls(ret);\n\n\t\t\t\t\t\tif ( !validate( schemaName, ret[ schemaName ], Schemas[ schemaName ] ) ) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.error( 'validate', e );\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn ret;\n\n\t\t\tcase 'fetch':\n\t\t\t\tfor ( var schemaName in ModelSchemas ) {\n\t\t\t\t\tret[ schemaName ] = await getValuesRec(\n\t\t\t\t\t\tVisualDataFunctions.escapeJsonPointer( schemaName ),\n\t\t\t\t\t\tModelSchemas[ schemaName ]\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn ret;\n\n\t\t\tcase 'submit':\n\t\t\t\tfor ( var schemaName in ModelSchemas ) {\n\t\t\t\t\tif ( !Form.schemas.includes( schemaName ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tret[ schemaName ] = await getValuesRec(\n\t\t\t\t\t\tVisualDataFunctions.escapeJsonPointer( schemaName ),\n\t\t\t\t\t\tModelSchemas[ schemaName ]\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tvar formModel = await getFormModel();\n\n\t\t\t\treturn {\n\t\t\t\t\tdata: ret,\n\t\t\t\t\tflatten: Flatten,\n\t\t\t\t\tform: formModel,\n\t\t\t\t\tschemas: Form.schemas,\n\t\t\t\t\t// @FIXME or retrieve it server side\n\t\t\t\t\toptions: Form.options,\n\t\t\t\t\tinitialSchemas: InitialSchemas\n\t\t\t\t};\n\n\t\t\tcase 'validate&submit':\n\t\t\t\tAction = 'validate';\n\n\t\t\t\tif ( !( await getModel( 'validate' ) ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tAction = 'submit';\n\t\t\t\treturn await getModel( 'submit' );\n\n\t\t\tcase 'delete':\n\t\t\t\tvar formModel = await getFormModel();\n\t\t\t\tForm.options.action = 'delete';\n\t\t\t\treturn {\n\t\t\t\t\tform: formModel,\n\t\t\t\t\toptions: Form.options,\n\t\t\t\t\tschemas: InitialSchemas // Object.keys(ModelSchemas),\n\t\t\t\t};\n\n\t\t\tcase 'schema':\n\t\t\t\tif ( !( schemaName in ModelSchemas ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tvar ret = await getValuesRec(\n\t\t\t\t\tVisualDataFunctions.escapeJsonPointer( schemaName ),\n\t\t\t\t\tModelSchemas[ schemaName ]\n\t\t\t\t);\n\t\t\t\treturn {\n\t\t\t\t\tdata: ret,\n\t\t\t\t\tflatten: Flatten\n\t\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\tgetModel,\n\t\tgetValue\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":"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/VisualDataSchemas.js","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 103. Maximum allowed is 100.","line":325,"column":1,"nodeType":"Program","messageId":"max","endLine":325,"endColumn":95},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":640,"column":8,"nodeType":"CallExpression","endLine":697,"endColumn":12},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":640,"column":8,"nodeType":"CallExpression","endLine":702,"endColumn":12},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":1608,"column":15,"nodeType":"CallExpression","endLine":1608,"endColumn":51},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":1785,"column":4,"nodeType":"CallExpression","endLine":1785,"endColumn":27},{"ruleId":"no-jquery/no-parse-html-literal","severity":1,"message":"Prefer DOM building to parsing HTML literals","line":1788,"column":15,"nodeType":"CallExpression","endLine":1790,"endColumn":6},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":1804,"column":4,"nodeType":"CallExpression","endLine":1804,"endColumn":27}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":26,"column":1,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":1846,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":94,"column":4,"nodeType":"MemberExpression","messageId":"unexpected","endLine":94,"endColumn":17,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[2366,2404],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"array-callback-return","severity":2,"message":"Array.prototype.every() expects a return value from function.","line":128,"column":27,"nodeType":"FunctionExpression","messageId":"expectedInside","endLine":128,"endColumn":36,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'tableLoop' is defined but never used.","line":128,"column":46,"nodeType":"Identifier","messageId":"unusedVar","endLine":128,"endColumn":55,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'rowLoop' is defined but never used.","line":128,"column":57,"nodeType":"Identifier","messageId":"unusedVar","endLine":128,"endColumn":64,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'meta' is defined but never used.","line":288,"column":47,"nodeType":"Identifier","messageId":"unusedVar","endLine":288,"endColumn":51,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'thisIsArray' is assigned a value but never used.","line":325,"column":37,"nodeType":"Identifier","messageId":"unusedVar","endLine":325,"endColumn":48,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":443,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":443,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":485,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":485,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-alert","severity":2,"message":"Unexpected confirm.","line":554,"column":6,"nodeType":"CallExpression","messageId":"unexpected","endLine":554,"endColumn":78,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-fallthrough","severity":1,"message":"Expected a 'break' statement before 'case'.","line":634,"column":6,"nodeType":"SwitchCase","messageId":"case","endLine":711,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":700,"column":10,"nodeType":"MemberExpression","messageId":"unexpected","endLine":700,"endColumn":23,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[18861,18908],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unreachable","severity":2,"message":"Unreachable code.","line":716,"column":3,"nodeType":"ReturnStatement","messageId":"unreachableCode","endLine":716,"endColumn":78,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":788,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":788,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-alert","severity":2,"message":"Unexpected confirm.","line":878,"column":6,"nodeType":"CallExpression","messageId":"unexpected","endLine":878,"endColumn":78,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":880,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":880,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-underscore-dangle","severity":2,"message":"Unexpected dangling '_' in 'target_'.","line":972,"column":9,"nodeType":"VariableDeclarator","messageId":"unexpectedUnderscore","endLine":974,"endColumn":25,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1083,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1083,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1084,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1084,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1085,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1085,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1086,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1086,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1090,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1090,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1091,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1091,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1092,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1092,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1093,"column":7,"nodeType":"Program","messageId":"unexpectedTab","endLine":1093,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1306,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":1306,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1314,"column":8,"nodeType":"Program","messageId":"unexpectedTab","endLine":1314,"endColumn":9,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1584,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":1584,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1585,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":1585,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1586,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":1586,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1587,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":1587,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1588,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":1588,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":1589,"column":5,"nodeType":"Program","messageId":"unexpectedTab","endLine":1589,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":2,"fatalErrorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright ©2023-2024, https://wikisphere.org\n */\n\n/* eslint-disable no-tabs */\n/* eslint-disable no-underscore-dangle */\n\n// eslint-disable-next-line no-implicit-globals\nVisualDataSchemas = ( function () {\n\tvar Models = [];\n\tvar SelectedItems = [];\n\tvar DataTable;\n\tvar DialogName = 'dialogSchemas';\n\tvar Config;\n\tvar WindowManager;\n\tvar Schemas = {};\n\tvar VisualDataFormFieldInst;\n\tvar VisualDataContentBlockInst;\n\tvar VisualDataGeolocationInst;\n\n\tfunction getModel() {\n\t\treturn Models[ Models.length - 1 ];\n\t}\n\n\tfunction getWidgetValue( obj ) {\n\t\tvar ret = '';\n\t\tif ( 'getValue' in obj ) {\n\t\t\tret = obj.getValue();\n\t\t\tif ( typeof ret === 'string' ) {\n\t\t\t\treturn ret.trim();\n\t\t\t} else if ( Array.isArray( ret ) ) {\n\t\t\t\treturn ret.map( ( x ) => x.trim() );\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t\treturn Object.keys( obj )\n\t\t\t.map( ( i ) => {\n\t\t\t\treturn obj[ i ];\n\t\t\t} )\n\t\t\t.map( ( x ) => x.getValue() );\n\t}\n\n\tfunction getPropertyValue( property, propName, self ) {\n\t\tif ( !self ) {\n\t\t\tvar self = VisualDataSchemas;\n\t\t}\n\t\tvar model = self.getModel();\n\n\t\tif ( propName ) {\n\t\t\tmodel = model[ propName ];\n\t\t}\n\t\tif ( property in model ) {\n\t\t\treturn getWidgetValue( model[ property ] );\n\t\t}\n\n\t\tvar currentItem = self.getCurrentItem();\n\n\t\tif ( !currentItem ) {\n\t\t\treturn '';\n\t\t}\n\n\t\t// new item\n\t\tif ( propName && currentItem.type !== 'array' ) {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (\n\t\t\t!propName &&\n\t\t\tcurrentItem.type === 'array' &&\n\t\t\tVisualDataFunctions.isObject( currentItem.items )\n\t\t) {\n\t\t\tcurrentItem = currentItem.items;\n\t\t}\n\n\t\tif ( !( 'wiki' in currentItem ) ) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.error( 'missing \"wiki\" key' );\n\t\t\treturn '';\n\t\t}\n\n\t\tif ( property in currentItem.wiki ) {\n\t\t\treturn currentItem.wiki[ property ];\n\t\t}\n\t\treturn '';\n\t}\n\n\tfunction getDatatableId( panel ) {\n\t\treturn `visualdata-schemas-datatable-dialog-${ SelectedItems.length }-${ panel }`;\n\t}\n\n\tfunction getCurrentItem() {\n\t\tif ( !SelectedItems.length ) {\n\t\t\treturn null;\n\t\t}\n\t\tvar ret = SelectedItems[ SelectedItems.length - 1 ];\n\n\t\tif ( ret.type === 'array' && !ret.items ) {\n\t\t\tret.items = { wiki: {}, properties: {} };\n\t\t}\n\n\t\treturn ret;\n\t}\n\n\tfunction orderFields( fields, panel ) {\n\t\tif ( !$.fn.DataTable.isDataTable( '#' + getDatatableId( panel ) ) ) {\n\t\t\treturn fields;\n\t\t}\n\t\tvar datatable = $( '#' + getDatatableId( panel ) ).DataTable();\n\t\tvar ret = {};\n\t\t// eslint-disable-next-line no-unused-vars, array-callback-return\n\t\tdatatable.rows().every( function ( rowIdx, tableLoop, rowLoop ) {\n\t\t\tvar key = Object.keys( fields )[ rowIdx ];\n\t\t\tif ( key in fields ) {\n\t\t\t\tret[ key ] = fields[ key ];\n\t\t\t}\n\t\t} );\n\t\tvar newItems = {};\n\t\tfor ( var i in fields ) {\n\t\t\tif ( !( i in ret ) ) {\n\t\t\t\tnewItems[ i ] = fields[ i ];\n\t\t\t}\n\t\t\tdelete fields[ i ];\n\t\t}\n\t\tfor ( var i in ret ) {\n\t\t\tfields[ i ] = ret[ i ];\n\t\t}\n\t\tfor ( var i in newItems ) {\n\t\t\tfields[ i ] = newItems[ i ];\n\t\t}\n\t}\n\n\tfunction initializeNestedDataTable( panel ) {\n\t\tvar currentItem = getCurrentItem();\n\n\t\t// array items can share the same schema for\n\t\t// all items, or to contain a tuple (to be an\n\t\t// array of items of fixed length)\n\t\t// in the first case, we consider the schema\n\t\t// being the child schema,\n\t\t// in the second case being the parent schema\n\t\t// (in the first case, we will provide an\n\t\t// editable panel with the properties of the\n\t\t// parent schema)\n\t\tif (\n\t\t\tcurrentItem.type === 'array' &&\n\t\t\tVisualDataFunctions.isObject( currentItem.items )\n\t\t) {\n\t\t\tcurrentItem = currentItem.items;\n\t\t}\n\n\t\torderFields( currentItem[ panel ], panel );\n\n\t\tVisualDataFunctions.destroyDataTable( getDatatableId( panel ) );\n\n\t\tfunction getType( thisItem ) {\n\t\t\tvar ret;\n\t\t\tswitch ( thisItem.wiki.type ) {\n\t\t\t\tcase 'schema':\n\t\t\t\t\tret = mw.msg( 'visualdata-jsmodule-schemas-subitem' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'property':\n\t\t\t\t\tret = thisItem.wiki[ 'jsonSchema-type' ] +\n\t\t\t\t\t\t( thisItem.wiki[ 'jsonSchema-type' ] !== 'string' ?\n\t\t\t\t\t\t\t'' :\n\t\t\t\t\t\t\t' (' + thisItem.wiki[ 'jsonSchema-format' ] + ')' );\n\n\t\t\t\t\tif ( !( 'preferred-input' in thisItem.wiki ) ) {\n\t\t\t\t\t\tthisItem.wiki[ 'preferred-input' ] =\n\t\t\t\t\t\t\tVisualDataFunctions.getPreferredInput( thisItem.wiki );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'content-block':\n\t\t\t\t\tret = mw.msg( 'visualdata-jsmodule-schemas-content-block' );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'geolocation':\n\t\t\t\t\tret = mw.msg( 'visualdata-jsmodule-schemas-geolocation' );\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\t// this returns a modified item, the object schema\n\t\t// or the array schema \"subject\" in case of\n\t\t// array, with name of parent schema\n\t\tfunction getItem( thisItem ) {\n\t\t\tvar thisItem = VisualDataFunctions.deepCopy( thisItem );\n\t\t\tif ( !( 'wiki' in thisItem ) ) {\n\t\t\t\tthisItem.wiki = { name: '' };\n\t\t\t}\n\n\t\t\t// handle from property panel\n\t\t\t// @TODO handle tuple\n\t\t\tif (\n\t\t\t\tthisItem.type === 'array' &&\n\t\t\t\tVisualDataFunctions.isObject( thisItem.items ) &&\n\t\t\t\tthisItem.items.type !== 'array'\n\t\t\t) {\n\t\t\t\tvar ret = thisItem.items;\n\t\t\t\tret.wiki.name = thisItem.wiki.name;\n\t\t\t\treturn { item: ret, isArray: true };\n\t\t\t}\n\t\t\treturn { item: thisItem, isArray: false };\n\t\t}\n\n\t\tvar n = 0;\n\t\tvar data = [];\n\t\tvar propName = panel;\n\n\t\tfor ( var i in currentItem[ propName ] ) {\n\t\t\tvar { item, isArray } = getItem( currentItem[ propName ][ i ] );\n\t\t\tvar required = '';\n\t\t\t// var input = '';\n\t\t\tvar multiple = '';\n\t\t\tif ( item.wiki.type === 'property' ) {\n\t\t\t\t// input = item.wiki[ 'preferred-input' ];\n\t\t\t\trequired = item.wiki.required ?\n\t\t\t\t\tmw.msg( 'visualdata-jsmodule-formfield-required' ) :\n\t\t\t\t\tmw.msg( 'visualdata-jsmodule-formfield-not-required' );\n\t\t\t} else {\n\t\t\t\trequired = mw.msg( 'visualdata-jsmodule-formfield-n/a' );\n\t\t\t\t// input = mw.msg( 'visualdata-jsmodule-formfield-n/a' );\n\t\t\t}\n\t\t\tif ( isArray ) {\n\t\t\t\tmultiple = mw.msg( 'visualdata-jsmodule-schemas-multiple' );\n\t\t\t}\n\t\t\tvar type = getType( item );\n\t\t\tdata.push( [\n\t\t\t\tn,\n\t\t\t\titem.wiki.name,\n\t\t\t\ttype,\n\t\t\t\t// input\n\t\t\t\tmultiple,\n\t\t\t\trequired,\n\t\t\t\t''\n\t\t\t] );\n\n\t\t\tn++;\n\t\t}\n\n\t\tif ( !data.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\t$( '#' + getDatatableId( panel ) ).DataTable( {\n\t\t\t// order: 1,\n\t\t\t// pageLength: 20,\n\t\t\t// https://datatables.net/reference/option/dom\n\t\t\tdom: '<\"visualdata-datatable-left\"f><\"visualdata-datatable-right\"l>rtip',\n\n\t\t\t// @ATTENTION! this conflicts with \"rowReorder\"\n\t\t\t// use instead an hidden column and set orderable to false\n\t\t\t// for all visible columns\n\t\t\t// ordering: false,\n\n\t\t\tiDisplayLength: 100,\n\t\t\tsearching: false,\n\t\t\tpaging: false,\n\t\t\tinfo: false,\n\t\t\trowReorder: {\n\t\t\t\t// update: false,\n\t\t\t\t// dataSrc: 0,\n\t\t\t\tselector: 'td:not(:last-child)'\n\t\t\t},\n\t\t\tscrollX: true,\n\t\t\tcolumnDefs: [\n\t\t\t\t{ targets: 0, orderable: true, visible: false },\n\t\t\t\t{ orderable: false, targets: '_all' },\n\t\t\t\t{\n\t\t\t\t\ttargets: 5,\n\t\t\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\t\t\trender: function ( data_, thisType, row, meta ) {\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t'<span class=\"buttons-wrapper\" style=\"white-space:nowrap\" data-row=\"' +\n\t\t\t\t\t\t\trow[ 0 ] +\n\t\t\t\t\t\t\t'\"></span>'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t],\n\n\t\t\t// lengthMenu: [ 10, 20, 50, 100, 200 ],\n\t\t\t// lengthChange: false,\n\t\t\tdata: data,\n\t\t\t// stateSave: true,\n\t\t\tcolumns: [ '' ].concat(\n\t\t\t\tmw.msg( 'visualdata-jsmodule-schemas-properties-columns' )\n\t\t\t\t\t.split( /\\s*,\\s*/ )\n\t\t\t\t\t.map( function ( x ) {\n\t\t\t\t\t\treturn { title: x };\n\t\t\t\t\t} )\n\t\t\t)\n\t\t} );\n\n\t\t$( '#' + getDatatableId( panel ) + ' .buttons-wrapper' ).each( function () {\n\t\t\tvar buttonWidgetEdit = new OO.ui.ButtonWidget( {\n\t\t\t\ticon: 'edit'\n\t\t\t\t// flags: [\"progressive\"],\n\t\t\t} );\n\n\t\t\tvar row = $( this ).data().row;\n\t\t\tvar key = Object.keys( currentItem[ propName ] )[ row ];\n\n\t\t\t// this is the modified item, the object schema\n\t\t\t// or the array schema \"subject\" in case of\n\t\t\t// array, with name of parent schema\n\n\t\t\t// eslint-disable-next-line no-unused-vars\n\t\t\tconst { item: thisItem, isArray: thisIsArray } = getItem( currentItem[ propName ][ key ] );\n\n\t\t\tif ( !( 'type' in thisItem.wiki ) ) {\n\t\t\t\tthisItem.wiki.type = 'property';\n\t\t\t}\n\n\t\t\tvar targetItem =\n\t\t\t\tcurrentItem.type !== 'array' ?\n\t\t\t\t\tcurrentItem[ propName ] :\n\t\t\t\t\tcurrentItem.items[ propName ];\n\n\t\t\tvar callback = function () {\n\t\t\t\tinitializeNestedDataTable( panel );\n\t\t\t};\n\n\t\t\tbuttonWidgetEdit.on( 'click', function () {\n\t\t\t\t// switch by subschema type (if array)\n\t\t\t\tswitch ( thisItem.wiki.type ) {\n\t\t\t\t\tcase 'property':\n\t\t\t\t\t\tVisualDataFormFieldInst.openDialog( callback, targetItem, key );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'content-block':\n\t\t\t\t\t\tVisualDataContentBlockInst.openDialog(\n\t\t\t\t\t\t\tcallback,\n\t\t\t\t\t\t\ttargetItem,\n\t\t\t\t\t\t\tkey\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'geolocation':\n\t\t\t\t\t\tVisualDataGeolocationInst.openDialog(\n\t\t\t\t\t\t\tcallback,\n\t\t\t\t\t\t\ttargetItem,\n\t\t\t\t\t\t\tkey\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'schema':\n\t\t\t\t\t\t// pass the child schema, we don't pass the target\n\t\t\t\t\t\t// item since the dialog must handle the parent schema\n\t\t\t\t\t\t// as well (in case of array)\n\t\t\t\t\t\topenDialog( currentItem[ propName ][ key ], propName );\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tvar buttonWidgetDelete = new OO.ui.ButtonWidget( {\n\t\t\t\ticon: 'close',\n\t\t\t\tflags: [ 'destructive' ]\n\t\t\t} );\n\n\t\t\tbuttonWidgetDelete.on( 'click', function () {\n\t\t\t\tVisualDataFunctions.OOUIAlert(\n\t\t\t\t\tnew OO.ui.HtmlSnippet(\n\t\t\t\t\t\tmw.msg( 'visualdata-jsmodule-schemas-delete-confirm' )\n\t\t\t\t\t),\n\t\t\t\t\t{ size: 'medium' },\n\t\t\t\t\tfunction () {\n\t\t\t\t\t\tdelete currentItem[ propName ][ key ];\n\t\t\t\t\t\t// *** or delete the row manually\n\t\t\t\t\t\tinitializeNestedDataTable( panel );\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t} );\n\t\t\t$( this ).append( [ buttonWidgetEdit.$element, buttonWidgetDelete.$element ] );\n\t\t} );\n\n\t\t// DataTables[DataTables.length - 1].draw();\n\t}\n\n\tfunction PageTwoLayout( name, config ) {\n\t\tPageTwoLayout.super.call( this, name, config );\n\n\t\tthis.name = name;\n\n\t\tvar toolbar = createToolbarB( name );\n\n\t\tvar contentFrame = new OO.ui.PanelLayout( {\n\t\t\t$content: $(\n\t\t\t\t// display\n\t\t\t\t'<table id=\"' +\n\t\t\t\t\tgetDatatableId( name ) +\n\t\t\t\t\t'\" class=\"visualdata-datatable\" width=\"100%\"></table>'\n\t\t\t), // this.fieldset.$element,\n\t\t\texpanded: false,\n\t\t\tpadded: false,\n\t\t\tclasses: [ 'visualdata-schemas-properties-contentframe' ]\n\t\t} );\n\n\t\tvar frameA = new OO.ui.PanelLayout( {\n\t\t\t$content: [ toolbar.$element, contentFrame.$element ],\n\t\t\texpanded: false,\n\t\t\t// framed: false,\n\t\t\tpadded: false,\n\t\t\tdata: { name: 'manage-schemas' }\n\t\t} );\n\n\t\tthis.$element.append( frameA.$element );\n\t}\n\n\tOO.inheritClass( PageTwoLayout, OO.ui.PageLayout );\n\tPageTwoLayout.prototype.setupOutlineItem = function () {\n\t\tthis.outlineItem.setLabel(\n\t\t\t// Messages that can be used here:\n\t\t\t// * visualdata-jsmodule-schemas-panel-properties\n\t\t\t// * visualdata-jsmodule-schemas-panel-oneOf\n\t\t\tmw.msg( 'visualdata-jsmodule-schemas-panel-' + this.name )\n\t\t);\n\t};\n\n\tfunction ProcessDialog( config ) {\n\t\tProcessDialog.super.call( this, config );\n\t}\n\tOO.inheritClass( ProcessDialog, OO.ui.ProcessDialog );\n\n\tProcessDialog.static.name = DialogName;\n\t// ProcessDialog.static.title = mw.msg(\n\t// \t\"visualdata-jsmodule-forms-defineform\"\n\t// );\n\tProcessDialog.static.actions = [\n\t\t{\n\t\t\taction: 'delete',\n\t\t\tmodes: 'main',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-delete' ),\n\t\t\tflags: 'destructive'\n\t\t},\n\t\t{\n\t\t\taction: 'save',\n\t\t\tmodes: [ 'main', 'properties' ],\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-save' ),\n\t\t\tflags: [ 'primary', 'progressive' ]\n\t\t},\n\t\t{\n\t\t\tmodes: [ 'main', 'properties' ],\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-cancel' ),\n\t\t\tflags: [ 'safe', 'close' ]\n\t\t}\n\t];\n\n\tfunction DialogContent() {\n\t\tvar page1 = new PageOneLayout( 'main', {} );\n\n\t\tvar page2 = new PageTwoLayout( 'properties', {\n\t\t\tclasses: [ 'visualdata-schemas-panel-properties' ]\n\t\t} );\n\n\t\t// *** the following requires more brainstorming\n\t\t// specifically, anyOf and oneOf are expected to\n\t\t// be objects, not properties in the same schema\n\t\t// so addField should be disabled in this case\n\t\t// or should inherit the current schema ...\n\t\t/*\n\t\tthis.page3 = new PageTwoLayout(\"anyOf\", {\n\t\t\tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t});\n\t\tthis.page4 = new PageTwoLayout(\"oneOf\", {\n\t\t\tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t});\n\t\t// this.page5 = new PageTwoLayout(\"prefixItems\", {\n\t\t// \tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t// });\n\t\tthis.page5 = new PageTwoLayout(\"allOf\", {\n\t\t\tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t});\n\t\tthis.page6 = new PageTwoLayout(\"additionalProperties\", {\n\t\t\tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t});\n\t\t*/\n\n\t\tvar booklet = new OO.ui.BookletLayout( {\n\t\t\toutlined: true,\n\t\t\texpanded: true,\n\t\t\tpadded: false\n\t\t} );\n\n\t\tbooklet.addPages( [\n\t\t\tpage1,\n\t\t\tpage2\n\t\t\t// this.page3,\n\t\t\t// this.page4,\n\t\t\t// this.page5,\n\t\t\t// this.page6,\n\t\t] );\n\n\t\treturn booklet;\n\t}\n\n\tProcessDialog.prototype.getSetupProcess = function ( data ) {\n\t\tvar initPropertiesTab = function ( tabName ) {\n\t\t\tif (\n\t\t\t\ttabName !== 'page1' &&\n\t\t\t\t!$.fn.DataTable.isDataTable( '#' + getDatatableId( tabName ) )\n\t\t\t) {\n\t\t\t\t// $('#visualdata-forms-datatable-dialog').DataTable().clear().draw();\n\t\t\t\tinitializeNestedDataTable( tabName );\n\t\t\t}\n\t\t};\n\n\t\treturn ProcessDialog.super.prototype.getSetupProcess.call( this, data )\n\t\t\t.next( function () {\n\t\t\t\tthis.actions.setMode( data.initialTab );\n\t\t\t\tvar booklet = DialogContent();\n\t\t\t\tthis.$body.append( booklet.$element );\n\t\t\t\tbooklet.setPage( data.initialTab );\n\n\t\t\t\tbooklet.on( 'set', function ( value ) {\n\t\t\t\t\tinitPropertiesTab( value.name );\n\t\t\t\t} );\n\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\tinitPropertiesTab( data.initialTab );\n\t\t\t\t\tVisualDataFunctions.removeNbspFromLayoutHeader(\n\t\t\t\t\t\t'#visualdata-ProcessDialogEditData'\n\t\t\t\t\t);\n\t\t\t\t}, 30 );\n\n\t\t\t}, this );\n\t};\n\n\tProcessDialog.prototype.initialize = function () {\n\t\tProcessDialog.super.prototype.initialize.apply( this, arguments );\n\t};\n\n\tProcessDialog.prototype.getActionProcess = function ( action ) {\n\t\tif (\n\t\t\t!action ||\n\t\t\t( action === 'delete' &&\n\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\t!confirm( mw.msg( 'visualdata-jsmodule-schemas-delete-schema-confirm' ) ) )\n\t\t) {\n\t\t\treturn ProcessDialog.super.prototype.getActionProcess.call( this, action );\n\t\t}\n\n\t\tvar currentItem = getCurrentItem();\n\n\t\tvar payload = {\n\t\t\taction: 'visualdata-save-schema',\n\t\t\t'dialog-action': action,\n\t\t\t'previous-label': currentItem.wiki.name,\n\t\t\t'source-page': mw.config.get( 'wgPageName' ),\n\t\t\tformat: 'json',\n\t\t\tschema: {}\n\t\t};\n\t\t// https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets\n\t\treturn ProcessDialog.super.prototype.getActionProcess\n\t\t\t.call( this, action )\n\t\t\t.next( function () {\n\t\t\t\tswitch ( action ) {\n\t\t\t\t\tcase 'save':\n\t\t\t\t\t\tvar obj = { type: 'schema' };\n\t\t\t\t\t\tvar model = Models[ 0 ];\n\n\t\t\t\t\t\t// var propName = currentItem.type === 'array' ? 'items': 'properties'\n\n\t\t\t\t\t\tfor ( var i in model ) {\n\t\t\t\t\t\t\tobj[ i ] = getPropertyValue( i );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// @TODO sanitize label\n\n\t\t\t\t\t\tvar alert = null;\n\t\t\t\t\t\tif ( obj.name === '' ) {\n\t\t\t\t\t\t\talert = mw.msg( 'visualdata-jsmodule-schemas-alert-noname' );\n\t\t\t\t\t\t} else if ( currentItem.wiki.name === '' && obj.name in Schemas ) {\n\t\t\t\t\t\t\talert = mw.msg(\n\t\t\t\t\t\t\t\t'visualdata-jsmodule-schemas-alert-existing-schema'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\t!Object.keys( currentItem.properties ).length\n\t\t\t\t\t\t\t//  && !Object.keys(currentItem.allOf).length &&\n\t\t\t\t\t\t\t// !Object.keys(currentItem.anyOf).length &&\n\t\t\t\t\t\t\t// !Object.keys(currentItem.oneOf).length\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\talert = mw.msg(\n\t\t\t\t\t\t\t\t'visualdata-jsmodule-schemas-alert-no-properties'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( alert ) {\n\t\t\t\t\t\t\tVisualDataFunctions.OOUIAlert( new OO.ui.HtmlSnippet( alert ), {\n\t\t\t\t\t\t\t\tsize: 'medium'\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\treturn ProcessDialog.super.prototype.getActionProcess.call(\n\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\taction\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdelete obj.parentSchema;\n\t\t\t\t\t\tpayload.schema.wiki = obj;\n\t\t\t\t\t\tpayload.schema.type = 'object';\n\n\t\t\t\t\t\tfor ( var panel of [\n\t\t\t\t\t\t\t'properties'\n\t\t\t\t\t\t\t// \"anyOf\",\n\t\t\t\t\t\t\t// \"oneOf\",\n\t\t\t\t\t\t\t// \"additionalProperties\",\n\t\t\t\t\t\t] ) {\n\t\t\t\t\t\t\tif ( Object.keys( currentItem[ panel ] ).length ) {\n\t\t\t\t\t\t\t\tpayload.schema[ panel ] = currentItem[ panel ];\n\t\t\t\t\t\t\t\torderFields( payload.schema[ panel ], panel );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdelete payload.schema[ panel ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// eslint-disable-next-line no-fallthrough\n\t\t\t\t\tcase 'delete':\n\t\t\t\t\t\t// console.log(\"payload\", JSON.parse(JSON.stringify(payload)));\n\t\t\t\t\t\tpayload.schema = JSON.stringify( payload.schema );\n\n\t\t\t\t\t\t// return;\n\t\t\t\t\t\tvar callApi = function ( postData, resolve, reject ) {\n\t\t\t\t\t\t\tnew mw.Api()\n\t\t\t\t\t\t\t\t.postWithToken( 'csrf', postData )\n\t\t\t\t\t\t\t\t.done( function ( res ) {\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t\tif ( payload.action in res ) {\n\t\t\t\t\t\t\t\t\t\tvar data = res[ payload.action ];\n\t\t\t\t\t\t\t\t\t\tif ( 'schemas' in data ) {\n\t\t\t\t\t\t\t\t\t\t\tdata.schemas = JSON.parse( data.schemas );\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif ( data[ 'result-action' ] === 'error' ) {\n\t\t\t\t\t\t\t\t\t\t\tVisualDataFunctions.OOUIAlert(\n\t\t\t\t\t\t\t\t\t\t\t\tnew OO.ui.HtmlSnippet( data.error ),\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tsize: 'medium'\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tif ( 'jobs-count-warning' in data ) {\n\t\t\t\t\t\t\t\t\t\t\t\tVisualDataFunctions.OOUIAlert(\n\t\t\t\t\t\t\t\t\t\t\t\t\tmw.msg(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t'visualdata-jsmodule-create-jobs-alert',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tparseInt( data[ 'jobs-count-warning' ] )\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t{ size: 'medium' },\n\t\t\t\t\t\t\t\t\t\t\t\t\tcallApi,\n\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$.extend( postData, {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'confirm-job-execution': true\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t} ),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tresolve,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treject\n\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\tif ( parseInt( data[ 'jobs-count' ] ) ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tVisualDataFunctions.OOUIAlert(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tmw.msg(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'visualdata-jsmodule-created-jobs',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tparseInt( data[ 'jobs-count' ] )\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{ size: 'medium' }\n\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tSchemas = VisualData.updateSchemas( data, data[ 'result-action' ] );\n\t\t\t\t\t\t\t\t\t\t\t\t// initialize();\n\t\t\t\t\t\t\t\t\t\t\t\tModels.pop();\n\t\t\t\t\t\t\t\t\t\t\t\tSelectedItems.pop();\n\t\t\t\t\t\t\t\t\t\t\t\tWindowManager.closeActiveWindow();\n\t\t\t\t\t\t\t\t\t\t\t\tinitializeDataTable();\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tVisualDataFunctions.OOUIAlert( 'unknown error', {\n\t\t\t\t\t\t\t\t\t\t\tsize: 'medium'\n\t\t\t\t\t\t\t\t\t\t} );\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.fail( function ( res ) {\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\t\t\t\tconsole.error( 'visualdata-save-schema', res );\n\t\t\t\t\t\t\t\t\treject( res );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\t\t\t\t\tmw.loader.using( 'mediawiki.api', function () {\n\t\t\t\t\t\t\t\tcallApi( payload, resolve, reject );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} ).catch( ( err ) => {\n\t\t\t\t\t\t\tVisualDataFunctions.OOUIAlert( `error: ${ err }`, { size: 'medium' } );\n\t\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} ); // .next\n\n\t\t// eslint-disable-next-line no-unreachable\n\t\treturn ProcessDialog.super.prototype.getActionProcess.call( this, action );\n\t};\n\n\tProcessDialog.prototype.getTeardownProcess = function ( data ) {\n\t\treturn ProcessDialog.super.prototype.getTeardownProcess\n\t\t\t.call( this, data )\n\t\t\t.first( function () {\n\t\t\t\tModels.pop();\n\t\t\t\tSelectedItems.pop();\n\t\t\t\tWindowManager.removeActiveWindow();\n\t\t\t}, this );\n\t};\n\n\t/**\n\t * Override getBodyHeight to create a tall dialog relative to the screen.\n\t *\n\t * @return {number} Body height\n\t */\n\tProcessDialog.prototype.getBodyHeight = function () {\n\t\t// see here https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n\t\t// this.page1.content.$element.outerHeight( true );\n\t\treturn window.innerHeight - 100;\n\t};\n\n\tfunction ProcessDialogNested( config ) {\n\t\tProcessDialogNested.super.call( this, config );\n\n\t\tthis.data = config.data;\n\t}\n\tOO.inheritClass( ProcessDialogNested, OO.ui.ProcessDialog );\n\n\tProcessDialogNested.static.name = DialogName;\n\n\tProcessDialogNested.static.actions = [\n\t\t/*\n\t\t{\n\t\t\taction: 'delete',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-manageproperties-delete' ),\n\t\t\tflags: 'destructive'\n\t\t},\n\t\t*/\n\t\t{\n\t\t\taction: 'save',\n\t\t\tmodes: 'edit',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-save' ),\n\t\t\tflags: [ 'primary', 'progressive' ]\n\t\t},\n\t\t{\n\t\t\tmodes: 'edit',\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-dialog-cancel' ),\n\t\t\tflags: [ 'safe', 'close' ]\n\t\t}\n\t];\n\n\tProcessDialogNested.prototype.initialize = function () {\n\t\tProcessDialogNested.super.prototype.initialize.apply( this, arguments );\n\t\tthis.page1 = new PageOneLayoutNested( 'page1', {} );\n\t\tthis.page2 = new PageTwoLayout( 'properties', {\n\t\t\tclasses: [ 'visualdata-schemas-panel-properties' ]\n\t\t} );\n\t\t/*\n\t\tthis.page3 = new PageTwoLayout(\"anyOf\", {\n\t\t\tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t});\n\t\tthis.page4 = new PageTwoLayout(\"oneOf\", {\n\t\t\tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t});\n\n\t\tthis.page5 = new PageTwoLayout(\"allOf\", {\n\t\t\tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t});\n\t\t// this.page5 = new PageTwoLayout(\"prefixItems\", {\n\t\t// \tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t// });\n\t\tthis.page6 = new PageTwoLayout(\"additionalProperties\", {\n\t\t\tclasses: [\"visualdata-schemas-panel-properties\"],\n\t\t});\n\t\t*/\n\n\t\tvar booklet = new OO.ui.BookletLayout( {\n\t\t\toutlined: true,\n\t\t\texpanded: true,\n\t\t\tpadded: false\n\t\t} );\n\n\t\tbooklet.addPages( [\n\t\t\tthis.page1,\n\t\t\tthis.page2\n\t\t\t// this.page3,\n\t\t\t// this.page4,\n\t\t\t// this.page5,\n\t\t\t// this.page6,\n\t\t] );\n\t\tbooklet.setPage( 'page1' );\n\n\t\tbooklet.on( 'set', function ( value ) {\n\t\t\tif (\n\t\t\t\tvalue.name !== 'page1' &&\n\t\t\t\t!$.fn.DataTable.isDataTable( '#' + getDatatableId( value.name ) )\n\t\t\t) {\n\t\t\t\t// $('#visualdata-forms-datatable-dialog').DataTable().clear().draw();\n\t\t\t\tinitializeNestedDataTable( value.name );\n\t\t\t}\n\t\t} );\n\n\t\tthis.$body.append( booklet.$element );\n\n\t\tsetTimeout( function () {\n\t\t\tVisualDataFunctions.removeNbspFromLayoutHeader(\n\t\t\t\t'#visualdata-ProcessDialogEditProperties'\n\t\t\t);\n\t\t}, 30 );\n\t};\n\n\tfunction handleSaveArray( currentItem, obj ) {\n\t\tvar parentSchema = obj.parentSchema;\n\t\tdelete obj.parentSchema;\n\n\t\t// *** important !! otherwise it will be processed\n\t\t// as field by VisualDataSchemaProcessor\n\t\tif ( obj[ 'multiple-items' ] ) {\n\t\t\tparentSchema.type = 'schema';\n\t\t}\n\n\t\tif (\n\t\t\t( obj[ 'multiple-items' ] && currentItem.type === 'array' ) ||\n\t\t\t( !obj[ 'multiple-items' ] && currentItem.type !== 'array' )\n\t\t) {\n\t\t\tif ( obj[ 'multiple-items' ] ) {\n\t\t\t\tcurrentItem.wiki = parentSchema;\n\t\t\t\tcurrentItem.items = $.extend( currentItem.items, { wiki: obj } );\n\t\t\t\treturn currentItem;\n\t\t\t}\n\n\t\t\tcurrentItem.wiki = obj;\n\t\t\treturn currentItem;\n\t\t}\n\n\t\t// move child to parent\n\t\tif ( !obj[ 'multiple-items' ] ) {\n\t\t\t// currentItem.type should be always array\n\t\t\treturn $.extend(\n\t\t\t\tcurrentItem.type === 'array' ? currentItem.items : currentItem,\n\t\t\t\t{ wiki: obj }\n\t\t\t);\n\t\t}\n\n\t\t// create parent - child\n\t\treturn {\n\t\t\ttype: 'array',\n\t\t\twiki: parentSchema,\n\t\t\titems: $.extend( currentItem, { wiki: obj } )\n\t\t};\n\t}\n\n\tProcessDialogNested.prototype.getActionProcess = function ( action ) {\n\t\tvar dialog = this;\n\n\t\tif (\n\t\t\t!action ||\n\t\t\t( action === 'delete' &&\n\t\t\t\t// eslint-disable-next-line no-alert\n\t\t\t\t!confirm( mw.msg( 'visualdata-jsmodule-schemas-delete-schema-confirm' ) ) )\n\t\t) {\n\t\t\t//\treturn ProcessDialogNested.super.prototype.getActionProcess.call( this, action );\n\t\t}\n\n\t\tvar data = this.data;\n\t\tvar propName = data.propName;\n\n\t\tvar currentItem = getCurrentItem();\n\t\tvar parentSchema = currentItem;\n\t\tif (\n\t\t\tcurrentItem.type === 'array' &&\n\t\t\tVisualDataFunctions.isObject( currentItem.items )\n\t\t) {\n\t\t\tcurrentItem = currentItem.items;\n\t\t}\n\n\t\tfunction getValueRec( thisModel, thisObj ) {\n\t\t\tfor ( var i in thisModel ) {\n\t\t\t\tif ( !( 'getValue' in thisModel[ i ] ) ) {\n\t\t\t\t\tgetValueRec( thisModel[ i ], ( thisObj[ i ] = {} ) );\n\t\t\t\t} else {\n\t\t\t\t\tthisObj[ i ] = getWidgetValue( thisModel[ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch ( action ) {\n\t\t\tcase 'delete':\n\t\t\t\tif ( parentSchema.wiki.name !== '' ) {\n\t\t\t\t\tdelete SelectedItems[ SelectedItems.length - 1 ][ propName ][\n\t\t\t\t\t\tparentSchema.wiki.name\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'save':\n\t\t\t\tvar model = Models[ Models.length - 1 ];\n\t\t\t\tvar ParentObj = SelectedItems[ SelectedItems.length - 2 ];\n\n\t\t\t\tvar obj = { type: 'schema' };\n\t\t\t\tgetValueRec( model, obj );\n\n\t\t\t\tvar objName = obj[ 'multiple-items' ] ? obj.parentSchema.name : obj.name;\n\n\t\t\t\tvar target =\n\t\t\t\t\tParentObj.type !== 'array' ?\n\t\t\t\t\t\tParentObj[ propName ] :\n\t\t\t\t\t\tParentObj.items[ propName ];\n\n\t\t\t\tvar alert = null;\n\t\t\t\tif ( objName === '' ) {\n\t\t\t\t\talert = mw.msg( 'visualdata-jsmodule-schemas-alert-noname' );\n\n\t\t\t\t\t// @see VisualDataFormField\n\t\t\t\t} else if ( objName !== parentSchema.wiki.name && objName in target ) {\n\t\t\t\t\talert = mw.msg( 'visualdata-jsmodule-schemas-alert-existing-item' );\n\t\t\t\t} else if (\n\t\t\t\t\t!Object.keys( currentItem.properties ).length\n\t\t\t\t\t//  && !Object.keys(currentItem.allOf).length &&\n\t\t\t\t\t// !Object.keys(currentItem.anyOf).length &&\n\t\t\t\t\t// !Object.keys(currentItem.oneOf).length\n\t\t\t\t) {\n\t\t\t\t\talert = mw.msg( 'visualdata-jsmodule-schemas-alert-no-properties' );\n\t\t\t\t}\n\n\t\t\t\tif ( alert ) {\n\t\t\t\t\tVisualDataFunctions.OOUIAlert( new OO.ui.HtmlSnippet( alert ), {\n\t\t\t\t\t\tsize: 'medium'\n\t\t\t\t\t} );\n\n\t\t\t\t\treturn ProcessDialog.super.prototype.getActionProcess.call(\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\taction\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tVisualDataFunctions.renameObjectKey(\n\t\t\t\t\ttarget,\n\t\t\t\t\tparentSchema.wiki.name,\n\t\t\t\t\tobjName\n\t\t\t\t);\n\n\t\t\t\tvar updatedSchema = handleSaveArray( parentSchema, obj );\n\t\t\t\tupdatedSchema.type = !obj[ 'multiple-items' ] ? 'object' : 'array';\n\n\t\t\t\tvar panels = [\n\t\t\t\t\t'properties'\n\t\t\t\t\t// \"anyOf\",\n\t\t\t\t\t// \"oneOf\",\n\t\t\t\t\t// \"allOf\",\n\t\t\t\t\t// \"additionalProperties\",\n\t\t\t\t];\n\n\t\t\t\tvar target_ = !obj[ 'multiple-items' ] ?\n\t\t\t\t\tupdatedSchema :\n\t\t\t\t\tupdatedSchema.items;\n\n\t\t\t\tfor ( var panel of panels ) {\n\t\t\t\t\tif ( panel in target_ ) {\n\t\t\t\t\t\torderFields( target_[ panel ], panel );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ttarget[ objName ] = updatedSchema;\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn new OO.ui.Process( function () {\n\t\t\tdialog.close( { action: action } );\n\t\t} );\n\n\t\t// return ProcessDialogNested.super.prototype.getActionProcess.call( this, action );\n\t};\n\n\tProcessDialogNested.prototype.getTeardownProcess = function ( data ) {\n\t\tvar self = this;\n\t\treturn ProcessDialogNested.super.prototype.getTeardownProcess\n\t\t\t.call( this, data )\n\t\t\t.first( function () {\n\t\t\t\tModels.pop();\n\t\t\t\tSelectedItems.pop();\n\t\t\t\tinitializeNestedDataTable( self.data.propName );\n\t\t\t\tWindowManager.removeActiveWindow();\n\t\t\t}, this );\n\t};\n\n\t/**\n\t * Override getBodyHeight to create a tall dialog relative to the screen.\n\t *\n\t * @return {number} Body height\n\t */\n\tProcessDialogNested.prototype.getBodyHeight = function () {\n\t\t// see here https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs\n\t\t// this.page1.content.$element.outerHeight( true );\n\t\treturn window.innerHeight - 100;\n\t};\n\n\tfunction PageOneLayout( name, config ) {\n\t\tPageOneLayout.super.call( this, name, config );\n\n\t\tvar currentItem = getCurrentItem();\n\n\t\tvar model = Models[ Models.length - 1 ];\n\n\t\tvar fieldset = new OO.ui.FieldsetLayout( {\n\t\t\tlabel: ''\n\t\t} );\n\n\t\t//  || currentItem.wiki.name\n\t\tvar nameInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'name' )\n\t\t} );\n\n\t\tmodel.name = nameInput;\n\n\t\tvar titleInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'title' )\n\t\t} );\n\n\t\tmodel.title = titleInput;\n\n\t\tvar descriptionInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tautosize: true,\n\t\t\trows: 2,\n\t\t\tvalue: getPropertyValue( 'description' )\n\t\t} );\n\n\t\tmodel.description = descriptionInput;\n\n\t\tvar messageWidget = new OO.ui.MessageWidget( {\n\t\t\ttype: 'info',\n\t\t\tlabel: new OO.ui.HtmlSnippet(\n\t\t\t\tmw.msg(\n\t\t\t\t\t'visualdata-jsmodule-formfield-message-schemapage',\n\t\t\t\t\t`${ Config.VisualDataSchemaUrl }${ getPropertyValue( 'name' ) }`\n\t\t\t\t)\n\t\t\t),\n\t\t\tclasses: [ 'VisualDataFormFieldMessage' ]\n\t\t} );\n\n\t\tmessageWidget.toggle( currentItem.wiki.name !== '' );\n\n\t\tfieldset.addItems( [\n\t\t\tmessageWidget,\n\t\t\tnew OO.ui.FieldLayout( nameInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-name' ),\n\t\t\t\talign: 'top'\n\t\t\t} ),\n\n\t\t\tnew OO.ui.FieldLayout( titleInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-title' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-title-help' ),\n\t\t\t\talign: 'top',\n\t\t\t\thelpInline: true\n\t\t\t} ),\n\n\t\t\tnew OO.ui.FieldLayout( descriptionInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-description' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-description-help' ),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t} )\n\n\t\t\t// new OO.ui.FieldLayout(collapsibleInput, {\n\t\t\t// \tlabel: mw.msg(\"visualdata-jsmodule-schemas-collapsible\"),\n\t\t\t// \talign: \"top\",\n\t\t\t// \thelp: mw.msg(\"visualdata-jsmodule-schemas-collapsible-help\"),\n\t\t\t// \thelpInline: true,\n\t\t\t// }),\n\n\t\t\t// new OO.ui.FieldLayout(collapsedInput, {\n\t\t\t// \tlabel: mw.msg(\"visualdata-jsmodule-schemas-collapsed\"),\n\t\t\t// \talign: \"top\",\n\t\t\t// \thelp: mw.msg(\"visualdata-jsmodule-schemas-collapsed-help\"),\n\t\t\t// \thelpInline: true,\n\t\t\t// }),\n\t\t] );\n\n\t\tthis.content = new OO.ui.PanelLayout( {\n\t\t\t$content: fieldset.$element,\n\t\t\tpadded: true,\n\t\t\texpanded: false\n\t\t} );\n\n\t\tthis.$element.append( this.content.$element );\n\t}\n\n\tOO.inheritClass( PageOneLayout, OO.ui.PageLayout );\n\n\tPageOneLayout.prototype.setupOutlineItem = function () {\n\t\tthis.outlineItem.setLabel(\n\t\t\tmw.msg( 'visualdata-jsmodule-dialog-main' )\n\t\t);\n\t};\n\n\tfunction parentSchemaContainer( model, self ) {\n\t\tif ( !self ) {\n\t\t\tvar self = VisualDataSchemas;\n\t\t}\n\t\tvar layout = new OO.ui.PanelLayout( {\n\t\t\texpanded: false,\n\t\t\tpadded: true,\n\t\t\tframed: true,\n\t\t\tclasses: []\n\t\t} );\n\t\tvar fieldset = new OO.ui.FieldsetLayout( {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-container-schema' )\n\t\t} );\n\n\t\tlayout.$element.append( fieldset.$element );\n\n\t\tvar nameInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: self.getPropertyValue( 'name', 'parentSchema' )\n\t\t} );\n\n\t\tmodel.name = nameInput;\n\n\t\tvar titleInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: self.getPropertyValue( 'title', 'parentSchema' )\n\t\t} );\n\n\t\tmodel.title = titleInput;\n\n\t\tvar descriptionInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tautosize: true,\n\t\t\trows: 2,\n\t\t\tvalue: self.getPropertyValue( 'description', 'parentSchema' )\n\t\t} );\n\n\t\tmodel.description = descriptionInput;\n\n\t\t// @TODO\n\t\t// add:\n\t\t// min: number, at least: number\n\t\t// layout: section, horizontal, greed\n\t\t// collapsible: toggle\n\t\t// collasped: toggle\n\t\tvar minItemsInput = new OO.ui.NumberInputWidget( {\n\t\t\tvalue: self.getPropertyValue( 'min-items', 'parentSchema' ),\n\t\t\ttype: 'number'\n\t\t} );\n\t\tvar maxItemsInput = new OO.ui.NumberInputWidget( {\n\t\t\tvalue: self.getPropertyValue( 'max-items', 'parentSchema' ),\n\t\t\ttype: 'number'\n\t\t} );\n\n\t\tmodel[ 'min-items' ] = minItemsInput;\n\t\tmodel[ 'max-items' ] = maxItemsInput;\n\n\t\tvar uniqueItemsInput = new OO.ui.ToggleSwitchWidget( {\n\t\t\tvalue: self.getPropertyValue( 'unique-items', 'parentSchema' )\n\t\t} );\n\n\t\tmodel[ 'unique-items' ] = uniqueItemsInput;\n\n\t\tvar fieldMinItems = new OO.ui.FieldLayout( minItemsInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-min-items' ),\n\t\t\talign: 'top',\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-min-items-help' ),\n\t\t\thelpInline: true\n\t\t} );\n\n\t\tvar fieldMaxItems = new OO.ui.FieldLayout( maxItemsInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-max-items' ),\n\t\t\talign: 'top',\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-max-items-help' ),\n\t\t\thelpInline: true\n\t\t} );\n\n\t\tvar fieldUniqueItems = new OO.ui.FieldLayout( uniqueItemsInput, {\n\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-unique-items' ),\n\t\t\talign: 'top',\n\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-unique-items-help' ),\n\t\t\thelpInline: true\n\t\t} );\n\n\t\tvar messageWidget = new OO.ui.MessageWidget( {\n\t\t\ttype: 'info',\n\t\t\tlabel: new OO.ui.HtmlSnippet(\n\t\t\t\tmw.msg(\n\t\t\t\t\t'visualdata-jsmodule-schemas-message-container-info'\n\t\t\t\t)\n\t\t\t),\n\t\t\tclasses: [ 'VisualDataFormFieldMessage' ]\n\t\t} );\n\n\t\tfieldset.addItems( [\n\t\t\tmessageWidget,\n\n\t\t\tnew OO.ui.FieldLayout( nameInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-name' ),\n\t\t\t\talign: 'top'\n\t\t\t} ),\n\n\t\t\tnew OO.ui.FieldLayout( titleInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-title' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-title-help' ),\n\t\t\t\talign: 'top',\n\t\t\t\thelpInline: true\n\t\t\t} ),\n\n\t\t\tnew OO.ui.FieldLayout( descriptionInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-description' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-description-help' ),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t} ),\n\t\t\tfieldMinItems,\n\t\t\tfieldMaxItems,\n\t\t\tfieldUniqueItems\n\t\t] );\n\n\t\treturn layout;\n\t}\n\n\tfunction PageOneLayoutNested( name, config ) {\n\t\tPageOneLayoutNested.super.call( this, name, config );\n\n\t\tvar currentItem = getCurrentItem();\n\t\tvar parentSchema = {};\n\n\t\t// array items can share the same schema for\n\t\t// all items, or to contain a tuple (to be an\n\t\t// array of items of fixed length)\n\t\t// in the first case, we consider the schema\n\t\t// being the child schema,\n\t\t// in the second case being the parent schema\n\t\t// (in the firse case, we will provide an\n\t\t// editable panel with the properties of the\n\t\t// parent schema)\n\t\tif (\n\t\t\tcurrentItem.type === 'array' &&\n\t\t\tVisualDataFunctions.isObject( currentItem.items )\n\t\t) {\n\t\t\tparentSchema = currentItem;\n\t\t\tcurrentItem = currentItem.items;\n\t\t}\n\n\t\tvar model = Models[ Models.length - 1 ];\n\n\t\tvar fieldset = new OO.ui.FieldsetLayout( {\n\t\t\tlabel: ''\n\t\t} );\n\n\t\t//  || currentItem.wiki.name\n\t\tvar nameInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'name' )\n\t\t} );\n\n\t\tmodel.name = nameInput;\n\n\t\tvar titleInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'title' )\n\t\t} );\n\n\t\tmodel.title = titleInput;\n\n\t\tvar descriptionInput = new OO.ui.MultilineTextInputWidget( {\n\t\t\tautosize: true,\n\t\t\trows: 2,\n\t\t\tvalue: getPropertyValue( 'description' )\n\t\t} );\n\n\t\tmodel.description = descriptionInput;\n\n\t\t// *** TODO, manage arrays and tuples\n\t\t// @see https://json-schema.org/understanding-json-schema/reference/array.html#tuple-validation\n\n\t\tvar multipleItemsInputValue =\n\t\t\tgetPropertyValue( 'multiple-items' ) || parentSchema.type === 'array';\n\n\t\tvar multipleItemsInput = new OO.ui.ToggleSwitchWidget( {\n\t\t\tvalue: multipleItemsInputValue\n\t\t} );\n\n\t\tmodel[ 'multiple-items' ] = multipleItemsInput;\n\n\t\tvar layoutParentSchema = parentSchemaContainer( ( model.parentSchema = {} ) );\n\t\tlayoutParentSchema.toggle( multipleItemsInputValue );\n\t\tnameInput.setDisabled( multipleItemsInputValue );\n\n\t\tmultipleItemsInput.on( 'change', function ( enabled ) {\n\t\t\tlayoutParentSchema.toggle( enabled );\n\t\t\tnameInput.setDisabled( enabled );\n\t\t} );\n\n\t\t// var layout = new OO.ui.HorizontalLayout( {\n\t\t// \titems: [ minInstancesInput, maxInstancesInput ]\n\t\t// } );\n\n\t\tvar layoutInput = new OO.ui.DropdownInputWidget( {\n\t\t\toptions: VisualDataFunctions.createDropDownOptions( {\n\t\t\t\tsection: mw.msg( 'visualdata-jsmodule-schemas-layout-section' ),\n\t\t\t\thorizontal: mw.msg( 'visualdata-jsmodule-schemas-layout-horizontal' )\n\t\t\t\t// 'grid': mw.msg(\n\t\t\t\t// \t'visualdata-jsmodule-forms-freetext-showalways'\n\t\t\t\t// )\n\t\t\t} ),\n\t\t\tvalue: getPropertyValue( 'layout' ) || 'section'\n\t\t} );\n\n\t\tmodel.layout = layoutInput;\n\n\t\tvar visibilityInputValue = getPropertyValue( 'visibility' ) || 'visible';\n\n\t\tvar visibilityInput = new OO.ui.DropdownInputWidget( {\n\t\t\toptions: VisualDataFunctions.createDropDownOptions( {\n\t\t\t\tvisible: mw.msg( 'visualdata-jsmodule-formfield-visibility-visible' ),\n\t\t\t\tcondition: mw.msg( 'visualdata-jsmodule-formfield-visibility-condition' )\n\t\t\t} ),\n\t\t\tvalue: visibilityInputValue\n\t\t} );\n\n\t\tmodel.visibility = visibilityInput;\n\n\t\tvar items = [\n\t\t\tnew OO.ui.FieldLayout( nameInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-name' ),\n\t\t\t\talign: 'top'\n\t\t\t} ),\n\n\t\t\tnew OO.ui.FieldLayout( titleInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-title' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-title-help' ),\n\t\t\t\talign: 'top',\n\t\t\t\thelpInline: true\n\t\t\t} ),\n\n\t\t\tnew OO.ui.FieldLayout( descriptionInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-description' ),\n\t\t\t\talign: 'top'\n\t\t\t} ),\n\n\t\t\tnew OO.ui.FieldLayout( multipleItemsInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-multiple-items' ),\n\t\t\t\talign: 'top',\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-multiple-items-help' ),\n\t\t\t\t// 'Toggle on to allow multiple items', // mw.msg(),\n\t\t\t\thelpInline: true\n\t\t\t} ),\n\n\t\t\tlayoutParentSchema,\n\n\t\t\tnew OO.ui.FieldLayout( layoutInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-schemas-layout' ),\n\t\t\t\talign: 'top',\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-schemas-layout-help' ),\n\t\t\t\thelpInline: true\n\t\t\t} ),\n\n\t\t\tnew OO.ui.FieldLayout( visibilityInput, {\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-visibility-label' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-visibility-help' ),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t} )\n\t\t];\n\n\t\t// ------------------ show-if -----------------\n\n\t\tvar ParentObj = SelectedItems[ SelectedItems.length - 2 ].properties;\n\n\t\tvar otherFields = Object.keys( ParentObj ).filter( ( x ) => {\n\t\t\treturn ( ParentObj[ x ].wiki.type === 'property' &&\n\t\t\t\tParentObj[ x ].wiki[ 'multiple-items' ] === false );\n\t\t} );\n\n\t\tvar showifFieldInput = new OO.ui.DropdownInputWidget( {\n\t\t\toptions: VisualDataFunctions.createDropDownOptions( otherFields, { key: 'value' } ),\n\t\t\tvalue: getPropertyValue( 'showif-field' )\n\t\t} );\n\n\t\tvar showifConditionInput = new OO.ui.DropdownInputWidget( {\n\t\t\t// @https://github.com/Knowledge-Wiki/SemanticResultFormats/blob/561e5304e17fccc894d7b38ab88a03b75606d6c8/formats/datatables/Api.php\n\t\t\toptions: VisualDataFunctions.createDropDownOptions( {\n\t\t\t\t'=': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-=' ),\n\t\t\t\t'!=': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!=' ),\n\t\t\t\tstarts: mw.msg( 'visualdata-jsmodule-formfield-showif-condition-starts' ),\n\t\t\t\t'!starts': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!starts' ),\n\t\t\t\tcontains: mw.msg( 'visualdata-jsmodule-formfield-showif-condition-contains' ),\n\t\t\t\t'!contains': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!contains' ),\n\t\t\t\tends: mw.msg( 'visualdata-jsmodule-formfield-showif-condition-ends' ),\n\t\t\t\t'!ends': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!ends' ),\n\t\t\t\t'!null': mw.msg( 'visualdata-jsmodule-formfield-showif-condition-!null' ),\n\t\t\t\tregex: mw.msg( 'visualdata-jsmodule-formfield-showif-condition-regex' )\n\t\t\t} ),\n\t\t\tvalue: getPropertyValue( 'showif-condition' )\n\t\t} );\n\n\t\tvar showifValueInput = new OO.ui.TextInputWidget( {\n\t\t\tvalue: getPropertyValue( 'showif-value' )\n\t\t} );\n\n\t\tshowifConditionInput.on( 'change', function ( value ) {\n\t\t\tshowifValueInput.toggle( value !== '!null' );\n\t\t\tupdateModelShowif( getPropertyValue( 'visibility' ) === 'condition' );\n\t\t} );\n\n\t\tshowifValueInput.toggle( getPropertyValue( 'showif-condition' ) !== '!null' );\n\n\t\tvar layoutHorizontal = new OO.ui.HorizontalLayout( { items: [\n\t\t\tshowifFieldInput,\n\t\t\tshowifConditionInput,\n\t\t\tshowifValueInput\n\t\t] } );\n\n\t\tvar showifField = new OO.ui.FieldLayout(\n\t\t\tnew OO.ui.Widget( {\n\t\t\t\tcontent: [ layoutHorizontal ]\n\t\t\t} ),\n\t\t\t{\n\t\t\t\tlabel: mw.msg( 'visualdata-jsmodule-formfield-showif' ),\n\t\t\t\thelp: mw.msg( 'visualdata-jsmodule-formfield-showif-help' ),\n\t\t\t\thelpInline: true,\n\t\t\t\talign: 'top'\n\t\t\t}\n\t\t);\n\n\t\titems.push( showifField );\n\n\t\tvar modelMap = {\n\t\t\t'showif-field': showifFieldInput,\n\t\t\t'showif-condition': showifConditionInput,\n\t\t\t'showif-value': showifValueInput\n\t\t};\n\n\t\tfunction updateModelShowif( thisVisibleItems ) {\n\t\t\tfor ( var i in modelMap ) {\n\t\t\t\tif ( thisVisibleItems ) {\n\t\t\t\t\tmodel[ i ] = modelMap[ i ];\n\t\t\t\t} else {\n\t\t\t\t\tdelete model[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( getPropertyValue( 'showif-condition' ) === '!null' ) {\n\t\t\t\tdelete model[ 'showif-value' ];\n\t\t\t}\n\t\t}\n\n\t\tupdateModelShowif( visibilityInputValue === 'condition' );\n\t\tshowifField.toggle( visibilityInputValue === 'condition' );\n\n\t\tfunction onVisibilityInputChange( value ) {\n\t\t\tshowifField.toggle( value === 'condition' );\n\t\t\tupdateModelShowif( value === 'condition' );\n\t\t}\n\n\t\tvisibilityInput.on( 'change', function ( value ) {\n\t\t\tonVisibilityInputChange( value );\n\t\t} );\n\n\t\t// ------------------ show-if >>>>>>>>>>>>>>>>>\n\n\t\tfieldset.addItems( items );\n\n\t\tthis.content = new OO.ui.PanelLayout( {\n\t\t\t$content: fieldset.$element,\n\t\t\tpadded: true,\n\t\t\texpanded: false\n\t\t} );\n\n\t\tthis.$element.append( this.content.$element );\n\t}\n\n\tOO.inheritClass( PageOneLayoutNested, OO.ui.PageLayout );\n\n\tPageOneLayoutNested.prototype.setupOutlineItem = function () {\n\t\tthis.outlineItem.setLabel(\n\t\t\tmw.msg( 'visualdata-jsmodule-dialog-main' )\n\t\t);\n\t};\n\n\tfunction openDialog( schema, propName, initialTab ) {\n\t\tif ( !schema ) {\n\t\t\tSelectedItems.push( {\n\t\t\t\tproperties: {},\n\n\t\t\t\t// treat as objects\n\t\t\t\t// items: {},\n\t\t\t\t// anyOf: {},\n\t\t\t\t// oneOf: {},\n\t\t\t\t// allOf: {},\n\n\t\t\t\t// additionalProperties: {},\n\t\t\t\twiki: { name: '' }\n\t\t\t} );\n\t\t} else {\n\t\t\tSelectedItems.push(\n\t\t\t\tjQuery.extend(\n\t\t\t\t\t{\n\t\t\t\t\t\tproperties: {},\n\n\t\t\t\t\t\t// treat as objects\n\t\t\t\t\t\t// items: {},\n\t\t\t\t\t\t// anyOf: {},\n\t\t\t\t\t\t// oneOf: {},\n\t\t\t\t\t\t// allOf: {},\n\t\t\t\t\t\t// additionalProperties: {},\n\t\t\t\t\t\twiki: {}\n\t\t\t\t\t},\n\t\t\t\t\tschema\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tModels.push( { parentSchema: {} } );\n\n\t\t// *** place here properties to copy\n\t\t// @FIXME with arrays this is mistakenly copying to\n\t\t// the child, not the parent schema\n\t\tif ( 'uuid' in SelectedItems[ SelectedItems.length - 1 ].wiki ) {\n\t\t\tModels[ Models.length - 1 ].uuid = new VisualDataFunctions.MockupOOUIClass(\n\t\t\t\tschema.wiki.uuid );\n\t\t}\n\n\t\tvar processDialog;\n\t\tvar title;\n\n\t\tif ( !propName ) {\n\t\t\tprocessDialog = new ProcessDialog( {\n\t\t\t\tsize: 'larger',\n\t\t\t\tid: 'visualdata-ProcessDialogEditData'\n\t\t\t} );\n\n\t\t\ttitle =\n\t\t\t\tmw.msg(\n\t\t\t\t\t// The following messages are used here:\n\t\t\t\t\t// * visualdata-jsmodule-schemas-defineschema\n\t\t\t\t\t// * visualdata-jsmodule-schemas-defineschema - [name]\n\t\t\t\t\t'visualdata-jsmodule-schemas-defineschema'\n\t\t\t\t) + ( name ? ' - ' + name : '' );\n\t\t} else {\n\t\t\tprocessDialog = new ProcessDialogNested( {\n\t\t\t\tsize: 'larger',\n\t\t\t\tid: 'visualdata-ProcessDialogEditProperties',\n\t\t\t\tdata: { propName: propName }\n\t\t\t} );\n\n\t\t\ttitle =\n\t\t\t\tmw.msg(\n\t\t\t\t\t// The following messages are used here:\n\t\t\t\t\t// * visualdata-jsmodule-schemas-defineschema\n\t\t\t\t\t// * visualdata-jsmodule-schemas-defineschema - [name]\n\t\t\t\t\t'visualdata-jsmodule-schemas-defineschema'\n\t\t\t\t) + ( name ? ' - ' + name : '' );\n\t\t}\n\n\t\tWindowManager.newWindow( processDialog, { title: title, initialTab: initialTab || 'main' } );\n\n\t\tif ( !Config.jsonDiffLibrary && !mw.cookie.get( 'visualdata-check-json-diff-library' ) ) {\n\t\t\tVisualDataFunctions.OOUIAlert( new OO.ui.HtmlSnippet( mw.msg( 'visualdata-jsmodule-missing-json-diff-library' ) ), {\n\t\t\t\tsize: 'medium',\n\t\t\t\tactions: [ OO.ui.MessageDialog.static.actions[ 0 ] ]\n\t\t\t}, function () {\n\t\t\t\t// 15 days\n\t\t\t\tvar timeLapse = 15 * 86400;\n\t\t\t\tmw.cookie.set( 'visualdata-check-json-diff-library', true, {\n\t\t\t\t\tpath: '/',\n\t\t\t\t\texpires: timeLapse\n\t\t\t\t} );\n\t\t\t} );\n\t\t}\n\t}\n\n\t// function escape( s ) {\n\t// \treturn String( s )\n\t// \t\t.replace( /&/g, '&amp;' )\n\t// \t\t.replace( /</g, '&lt;' )\n\t// \t\t.replace( />/g, '&gt;' )\n\t// \t\t.replace( /\"/g, '&quot;' )\n\t// \t\t.replace( /'/g, '&#039;' );\n\t// }\n\n\tfunction initializeDataTable() {\n\t\tVisualDataFunctions.destroyDataTable(\n\t\t\t'visualdata-schemas-datatable'\n\t\t);\n\n\t\tvar data = [];\n\t\tfor ( var i in Schemas ) {\n\t\t\tvar value = Schemas[ i ];\n\n\t\t\t// *** or use https://datatables.net/manual/data/renderers#Text-helper\n\t\t\tdata.push( [\n\t\t\t\ti,\n\t\t\t\t'properties' in value ? Object.keys( value.properties ).join( ', ' ) : ''\n\t\t\t] );\n\t\t}\n\n\t\tDataTable = $( '#visualdata-schemas-datatable' ).DataTable( {\n\t\t\torder: 1,\n\t\t\tpageLength: 20,\n\n\t\t\t// https://datatables.net/reference/option/dom\n\t\t\tdom: '<\"visualdata-datatable-left\"f><\"visualdata-datatable-right\"l>rtip',\n\t\t\tlengthMenu: [ 10, 20, 50, 100, 200 ],\n\t\t\t// lengthChange: false,\n\t\t\tdata: data,\n\t\t\tstateSave: true,\n\t\t\tcolumns: mw\n\t\t\t\t.msg( 'visualdata-jsmodule-schemas-columns' )\n\t\t\t\t.split( /\\s*,\\s*/ )\n\t\t\t\t.map( function ( x ) {\n\t\t\t\t\treturn { title: x };\n\t\t\t\t} )\n\t\t} );\n\n\t\tDataTable.on( 'click', 'tr', function () {\n\t\t\tvar index = DataTable.row( this ).index();\n\t\t\tif ( index !== undefined ) {\n\t\t\t\tvar label = data[ index ][ 0 ];\n\t\t\t\topenSchemaDialog( label, false );\n\t\t\t}\n\t\t} );\n\t}\n\n\tfunction openSchemaDialog( label, initialTab ) {\n\t\tif ( !Object.keys( Schemas[ label ] ).length ) {\n\t\t\tVisualData.loadSchemas( [ label ] ).then( function ( schemas ) {\n\t\t\t\tfor ( var i in schemas ) {\n\t\t\t\t\tSchemas[ i ] = schemas[ i ];\n\t\t\t\t}\n\t\t\t\topenDialog( Schemas[ label ], null, initialTab );\n\t\t\t} );\n\t\t} else {\n\t\t\topenDialog( Schemas[ label ], null, initialTab );\n\t\t}\n\t}\n\n\tfunction createToolbarB( panelName ) {\n\t\tvar toolFactory = new OO.ui.ToolFactory();\n\t\tvar toolGroupFactory = new OO.ui.ToolGroupFactory();\n\n\t\tvar toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory, {\n\t\t\tactions: true\n\t\t} );\n\n\t\tvar currentItem = getCurrentItem();\n\t\t// var propName = currentItem.type === \"array\" ? \"items\" : panelName;\n\t\tvar propName = panelName;\n\n\t\tvar onSelect = function () {\n\t\t\tvar toolName = this.getName();\n\n\t\t\tvar callback = function () {\n\t\t\t\tinitializeNestedDataTable( panelName );\n\t\t\t};\n\t\t\tswitch ( toolName ) {\n\t\t\t\tcase 'add-geolocation':\n\t\t\t\t\tVisualDataGeolocationInst.openDialog(\n\t\t\t\t\t\tcallback,\n\t\t\t\t\t\tcurrentItem.type !== 'array' ?\n\t\t\t\t\t\t\tcurrentItem[ propName ] :\n\t\t\t\t\t\t\tcurrentItem.items[ propName ]\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'add-block-content':\n\t\t\t\t\tVisualDataContentBlockInst.openDialog(\n\t\t\t\t\t\tcallback,\n\t\t\t\t\t\tcurrentItem.type !== 'array' ?\n\t\t\t\t\t\t\tcurrentItem[ propName ] :\n\t\t\t\t\t\t\tcurrentItem.items[ propName ]\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'add-field':\n\t\t\t\t\tVisualDataFormFieldInst.openDialog(\n\t\t\t\t\t\tcallback,\n\t\t\t\t\t\tcurrentItem.type !== 'array' ?\n\t\t\t\t\t\t\tcurrentItem[ propName ] :\n\t\t\t\t\t\t\tcurrentItem.items[ propName ]\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'add-subitem':\n\t\t\t\t\topenDialog( null, propName );\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis.setActive( false );\n\t\t};\n\n\t\tvar toolGroup = [\n\t\t\t{\n\t\t\t\tname: 'add-field',\n\t\t\t\ticon: 'add',\n\t\t\t\ttitle: mw.msg( 'visualdata-jsmodule-schemas-add-field' ),\n\t\t\t\tonSelect: onSelect\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'add-block-content',\n\t\t\t\ticon: 'add',\n\t\t\t\ttitle: mw.msg( 'visualdata-jsmodule-schemas-add-block-content' ),\n\t\t\t\tonSelect: onSelect\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'add-subitem',\n\t\t\t\ticon: 'add',\n\t\t\t\ttitle: mw.msg( 'visualdata-jsmodule-schemas-add-subitem' ),\n\t\t\t\tonSelect: onSelect\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'add-geolocation',\n\t\t\t\ticon: 'add',\n\t\t\t\ttitle: mw.msg( 'visualdata-jsmodule-schemas-add-geolocation' ),\n\t\t\t\tonSelect: onSelect\n\t\t\t}\n\t\t];\n\t\tVisualDataFunctions.createToolGroup( toolFactory, 'group', toolGroup );\n\n\t\ttoolbar.setup( [\n\t\t\t{\n\t\t\t\tname: 'my-group',\n\t\t\t\t// type: \"bar\",\n\t\t\t\t// label: \"Create property\",\n\t\t\t\tinclude: [ { group: 'group' } ]\n\t\t\t}\n\t\t] );\n\n\t\treturn toolbar;\n\t}\n\n\tfunction createToolbarA() {\n\t\tvar toolFactory = new OO.ui.ToolFactory();\n\t\tvar toolGroupFactory = new OO.ui.ToolGroupFactory();\n\n\t\tvar toolbar = new OO.ui.Toolbar( toolFactory, toolGroupFactory, {\n\t\t\tactions: true\n\t\t} );\n\n\t\tvar onSelect = function () {\n\t\t\tvar toolName = this.getName();\n\n\t\t\tswitch ( toolName ) {\n\t\t\t\tcase 'createschema':\n\t\t\t\t\topenDialog( null, null );\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis.setActive( false );\n\t\t};\n\n\t\tvar toolGroup = [\n\t\t\t{\n\t\t\t\tname: 'createschema',\n\t\t\t\ticon: 'add',\n\t\t\t\ttitle: mw.msg( 'visualdata-jsmodule-schemas-create-schema' ),\n\t\t\t\tonSelect: onSelect\n\t\t\t}\n\t\t];\n\t\tVisualDataFunctions.createToolGroup( toolFactory, 'group', toolGroup );\n\n\t\ttoolbar.setup( [\n\t\t\t{\n\t\t\t\tname: 'my-group',\n\t\t\t\t// type: \"bar\",\n\t\t\t\t// label: \"Create property\",\n\t\t\t\tinclude: [ { group: 'group' } ]\n\t\t\t}\n\t\t] );\n\n\t\treturn toolbar;\n\t}\n\n\tfunction initialize() {\n\t\tif ( Config.context === 'ManageSchemas' ) {\n\t\t\t$( '#schemas-wrapper' ).empty();\n\n\t\t\tvar contentFrame = new OO.ui.PanelLayout( {\n\t\t\t\t$content: $(\n\t\t\t\t\t'<table id=\"visualdata-schemas-datatable\" class=\"visualdata-datatable display\" width=\"100%\"></table>'\n\t\t\t\t),\n\t\t\t\texpanded: false,\n\t\t\t\tpadded: true\n\t\t\t} );\n\n\t\t\tvar toolbar = createToolbarA();\n\n\t\t\tvar frame = new OO.ui.PanelLayout( {\n\t\t\t\t$content: [ toolbar.$element, contentFrame.$element ],\n\t\t\t\texpanded: false,\n\t\t\t\tframed: true,\n\t\t\t\tdata: { name: 'manage-schemas' }\n\t\t\t} );\n\n\t\t\t$( '#schemas-wrapper' ).append( frame.$element );\n\n\t\t\ttoolbar.initialize();\n\t\t\ttoolbar.emit( 'updateState' );\n\t\t}\n\n\t\tinitializeDataTable();\n\t}\n\n\tfunction setVars( config, windowManager, schemas ) {\n\t\tConfig = config;\n\t\tWindowManager = windowManager;\n\t\tSchemas = schemas;\n\n\t\tVisualDataFormFieldInst = new VisualDataFormField(\n\t\t\tconfig,\n\t\t\twindowManager,\n\t\t\tSchemas\n\t\t);\n\t\tVisualDataContentBlockInst = new VisualDataContentBlock(\n\t\t\tconfig,\n\t\t\twindowManager\n\t\t);\n\t\tVisualDataGeolocationInst = new VisualDataGeolocation(\n\t\t\tconfig,\n\t\t\twindowManager\n\t\t);\n\t}\n\n\treturn {\n\t\tinitialize,\n\t\tcreateToolbarA,\n\t\topenDialog,\n\t\tparentSchemaContainer,\n\t\tgetPropertyValue,\n\t\tgetCurrentItem,\n\t\tgetModel,\n\t\thandleSaveArray,\n\t\tgetWidgetValue,\n\t\topenSchemaDialog,\n\t\tsetVars\n\t};\n}() );\n\n$( function () {\n\tvar config = JSON.parse( mw.config.get( 'visualdata-config' ) );\n\t// console.log(\"config\", config);\n\n\tif ( config.context === 'ManageSchemas' ) {\n\t\tvar schemas = JSON.parse( mw.config.get( 'visualdata-schemas' ) );\n\t\t// console.log(\"schemas\", schemas);\n\n\t\tvar windowManager = new VisualDataWindowManager();\n\t\tvar instances = [];\n\t\tVisualData.setVars( config, schemas, instances );\n\n\t\tVisualDataSchemas.setVars(\n\t\t\tconfig,\n\t\t\twindowManager,\n\t\t\tschemas,\n\t\t\tinstances\n\t\t);\n\n\t\tVisualDataSchemas.initialize();\n\t}\n\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":"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/VisualDataUpload.js","messages":[{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":128,"column":3,"nodeType":"CallExpression","endLine":131,"endColumn":6},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":280,"column":3,"nodeType":"CallExpression","endLine":290,"endColumn":5},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":280,"column":3,"nodeType":"CallExpression","endLine":304,"endColumn":5},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .done","line":369,"column":3,"nodeType":"CallExpression","endLine":375,"endColumn":7},{"ruleId":"no-jquery/no-done-fail","severity":2,"message":"Prefer .then to .fail","line":369,"column":3,"nodeType":"CallExpression","endLine":378,"endColumn":7}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":26,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":32,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":105,"column":6,"nodeType":"MemberExpression","messageId":"unexpected","endLine":105,"endColumn":19,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[3108,3154],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":5,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2021-2022, https://wikisphere.org\n */\n\n( function () {\n\t// @credits resources/src/mediawiki.Upload.BookletLayout/BookletLayout.js\n\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataUpload = function ( config ) {\n\t\t// Parent constructor\n\t\tVisualDataUpload.parent.call( this, config );\n\n\t\t// this.$overlay = config.$overlay;\n\t\t// this.filekey = config.filekey;\n\t};\n\n\t/* Setup */\n\n\tOO.inheritClass( VisualDataUpload, OO.ui.BookletLayout );\n\n\tVisualDataUpload.prototype.initialize = function (\n\t\tselectFileWidget,\n\t\tparentWidget\n\t) {\n\t\t// this.clear();\n\t\tthis.upload = this.createUpload();\n\n\t\tthis.selectFileWidget = selectFileWidget;\n\t\t// this.filenameWidget = filenameWidget;\n\t\tthis.parentWidget = parentWidget;\n\t};\n\n\tVisualDataUpload.prototype.createUpload = function () {\n\t\treturn new mw.Upload( {\n\t\t\tparameters: {\n\t\t\t\terrorformat: 'html',\n\t\t\t\terrorlang: mw.config.get( 'wgUserLanguage' ),\n\t\t\t\terrorsuselocal: 1,\n\t\t\t\tformatversion: 2\n\t\t\t}\n\t\t} );\n\t};\n\n\tVisualDataUpload.prototype.uploadFiles = function ( files ) {\n\t\tfor ( var i in files ) {\n\t\t\tthis.uploadFile( files[ i ] );\n\t\t}\n\t};\n\n\tVisualDataUpload.prototype.uploadFile = function ( file ) {\n\t\tvar deferred = $.Deferred(),\n\t\t\tstartTime = mw.now(),\n\t\t\tlayout = this;\n\n\t\tif ( this.filekey ) {\n\t\t\tif ( file === null ) {\n\t\t\t\t// Someone gonna get-a hurt real bad\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"filekey not passed into file select widget, which is impossible. Quitting while we're behind.\"\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Stashed file already uploaded.\n\t\t\tdeferred.resolve();\n\t\t\tthis.uploadPromise = deferred;\n\t\t\tthis.parentWidget.emit( 'fileUploaded', file );\n\t\t\treturn deferred;\n\t\t}\n\n\t\tthis.setFilename( file.name );\n\n\t\tlayout.parentWidget.emit( 'fileUploadInit', file );\n\n\t\tthis.upload.setFile( file );\n\t\t// The original file name might contain invalid characters, so use our sanitized one\n\t\tthis.upload.setFilename( this.getFilename() );\n\t\t// this.upload.setFilename(  this.selectFileWidget.getValue().name );\n\n\t\tthis.upload.upload().then(\n\t\t\tfunction ( res ) {\n\t\t\t\tdeferred.resolve();\n\t\t\t\tlayout.parentWidget.emit( 'fileUploadComplete', file, res );\n\t\t\t},\n\t\t\tfunction () {\n\t\t\t\t// These errors will be thrown while the user is on the info page.\n\t\t\t\tlayout.getErrorMessageForStateDetails().then( function ( errorMessage ) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.error( 'errorMessage', errorMessage );\n\t\t\t\t\tdeferred.reject( errorMessage );\n\t\t\t\t\tlayout.parentWidget.emit( 'fileUploadErrorMessage', file, errorMessage );\n\t\t\t\t} );\n\t\t\t},\n\t\t\tfunction ( progress ) {\n\t\t\t\tvar elapsedTime = mw.now() - startTime,\n\t\t\t\t\testimatedTotalTime = ( 1 / progress ) * elapsedTime,\n\t\t\t\t\testimatedRemainingTime = moment.duration(\n\t\t\t\t\t\testimatedTotalTime - elapsedTime\n\t\t\t\t\t);\n\n\t\t\t\tlayout.parentWidget.emit(\n\t\t\t\t\t'fileUploadProgress',\n\t\t\t\t\tfile,\n\t\t\t\t\tprogress,\n\t\t\t\t\testimatedRemainingTime\n\t\t\t\t);\n\t\t\t\t// console.log(\"fileUploadProgress\", progress, estimatedRemainingTime);\n\t\t\t}\n\t\t);\n\n\t\t// cancel uploading\n\t\tdeferred.fail( function ( res ) {\n\t\t\t// layout.setPage( 'upload' );\n\t\t\tlayout.parentWidget.emit( 'fileUploadFail', file, res );\n\t\t} );\n\n\t\treturn deferred;\n\t};\n\n\tVisualDataUpload.prototype.getErrorMessageForStateDetails = function () {\n\t\tvar state = this.upload.getState(),\n\t\t\tstateDetails = this.upload.getStateDetails(),\n\t\t\twarnings = stateDetails.upload && stateDetails.upload.warnings,\n\t\t\t$ul = $( '<ul>' ),\n\t\t\t$error;\n\n\t\tif ( state === mw.Upload.State.ERROR ) {\n\t\t\t$error = new mw.Api().getErrorMessage( stateDetails );\n\n\t\t\treturn $.Deferred().resolve(\n\t\t\t\tnew OO.ui.Error( $error, { recoverable: false } )\n\t\t\t);\n\t\t}\n\n\t\tif ( state === mw.Upload.State.WARNING ) {\n\t\t\t// We could get more than one of these errors, these are in order\n\t\t\t// of importance. For example fixing the thumbnail like file name\n\t\t\t// won't help the fact that the file already exists.\n\t\t\tif ( warnings.exists !== undefined ) {\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error(\n\t\t\t\t\t\t$( '<p>' ).msg( 'fileexists', 'File:' + warnings.exists ),\n\t\t\t\t\t\t{ recoverable: false }\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else if ( warnings[ 'exists-normalized' ] !== undefined ) {\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error(\n\t\t\t\t\t\t$( '<p>' ).msg( 'fileexists', 'File:' + warnings[ 'exists-normalized' ] ),\n\t\t\t\t\t\t{ recoverable: false }\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else if ( warnings[ 'page-exists' ] !== undefined ) {\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error(\n\t\t\t\t\t\t$( '<p>' ).msg( 'filepageexists', 'File:' + warnings[ 'page-exists' ] ),\n\t\t\t\t\t\t{ recoverable: false }\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else if ( Array.isArray( warnings.duplicate ) ) {\n\t\t\t\twarnings.duplicate.forEach( function ( filename ) {\n\t\t\t\t\tvar $a = $( '<a>' ).text( filename ),\n\t\t\t\t\t\thref = mw.Title.makeTitle(\n\t\t\t\t\t\t\tmw.config.get( 'wgNamespaceIds' ).file,\n\t\t\t\t\t\t\tfilename\n\t\t\t\t\t\t).getUrl( {} );\n\n\t\t\t\t\t$a.attr( { href: href, target: '_blank' } );\n\t\t\t\t\t$ul.append( $( '<li>' ).append( $a ) );\n\t\t\t\t} );\n\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error(\n\t\t\t\t\t\t$( '<p>' )\n\t\t\t\t\t\t\t.msg( 'file-exists-duplicate', warnings.duplicate.length )\n\t\t\t\t\t\t\t.append( $ul ),\n\t\t\t\t\t\t{ recoverable: false }\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else if ( warnings[ 'thumb-name' ] !== undefined ) {\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error( $( '<p>' ).msg( 'filename-thumb-name' ), {\n\t\t\t\t\t\trecoverable: false\n\t\t\t\t\t} )\n\t\t\t\t);\n\t\t\t} else if ( warnings[ 'bad-prefix' ] !== undefined ) {\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error(\n\t\t\t\t\t\t$( '<p>' ).msg( 'filename-bad-prefix', warnings[ 'bad-prefix' ] ),\n\t\t\t\t\t\t{ recoverable: false }\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else if ( warnings[ 'duplicate-archive' ] !== undefined ) {\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error(\n\t\t\t\t\t\t$( '<p>' ).msg(\n\t\t\t\t\t\t\t'file-deleted-duplicate',\n\t\t\t\t\t\t\t'File:' + warnings[ 'duplicate-archive' ]\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{ recoverable: false }\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else if ( warnings[ 'was-deleted' ] !== undefined ) {\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error(\n\t\t\t\t\t\t$( '<p>' ).msg( 'filewasdeleted', 'File:' + warnings[ 'was-deleted' ] ),\n\t\t\t\t\t\t{ recoverable: false }\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} else if ( warnings.badfilename !== undefined ) {\n\t\t\t\t// Change the name if the current name isn't acceptable\n\t\t\t\t// TODO This might not really be the best place to do this\n\t\t\t\tthis.setFilename( warnings.badfilename );\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error( $( '<p>' ).msg( 'badfilename', warnings.badfilename ) )\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\treturn $.Deferred().resolve(\n\t\t\t\t\tnew OO.ui.Error(\n\t\t\t\t\t\t// Let's get all the help we can if we can't pin point the error\n\t\t\t\t\t\t$( '<p>' ).msg(\n\t\t\t\t\t\t\t'api-error-unknown-warning',\n\t\t\t\t\t\t\tJSON.stringify( stateDetails )\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{ recoverable: false }\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t};\n\n\tVisualDataUpload.prototype.renderUploadForm = function () {\n\t\tvar fieldset,\n\t\t\tlayout = this;\n\n\t\tthis.selectFileWidget = this.getFileWidget();\n\t\tfieldset = new OO.ui.FieldsetLayout();\n\t\tfieldset.addItems( [ this.selectFileWidget ] );\n\t\tthis.uploadForm = new OO.ui.FormLayout( { items: [ fieldset ] } );\n\n\t\t// Validation (if the SFW is for a stashed file, this never fires)\n\t\tthis.selectFileWidget.on( 'change', this.onUploadFormChange.bind( this ) );\n\n\t\tthis.selectFileWidget.on( 'change', function () {\n\t\t\tlayout.updateFilePreview();\n\t\t} );\n\n\t\treturn this.uploadForm;\n\t};\n\n\tVisualDataUpload.prototype.getFileWidget = function () {\n\t\tif ( this.filekey ) {\n\t\t\treturn new mw.widgets.StashedFileWidget( {\n\t\t\t\tfilekey: this.filekey\n\t\t\t} );\n\t\t}\n\n\t\treturn new OO.ui.SelectFileWidget( {\n\t\t\tshowDropTarget: true\n\t\t} );\n\t};\n\n\tVisualDataUpload.prototype.updateFilePreview = function () {\n\t\tthis.selectFileWidget\n\t\t\t.loadAndGetImageUrl()\n\t\t\t.done(\n\t\t\t\tfunction ( url ) {\n\t\t\t\t\tthis.filePreview.$element.find( 'p' ).remove();\n\t\t\t\t\tthis.filePreview.$element.css( 'background-image', 'url(' + url + ')' );\n\t\t\t\t\tthis.infoForm.$element.addClass(\n\t\t\t\t\t\t'mw-upload-bookletLayout-hasThumbnail'\n\t\t\t\t\t);\n\t\t\t\t}.bind( this )\n\t\t\t)\n\t\t\t.fail(\n\t\t\t\tfunction () {\n\t\t\t\t\tthis.filePreview.$element.find( 'p' ).remove();\n\t\t\t\t\tif ( this.selectFileWidget.getValue() ) {\n\t\t\t\t\t\tthis.filePreview.$element.append(\n\t\t\t\t\t\t\t$( '<p>' ).text( this.selectFileWidget.getValue().name )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tthis.filePreview.$element.css( 'background-image', '' );\n\t\t\t\t\tthis.infoForm.$element.removeClass(\n\t\t\t\t\t\t'mw-upload-bookletLayout-hasThumbnail'\n\t\t\t\t\t);\n\t\t\t\t}.bind( this )\n\t\t\t);\n\t};\n\n\tVisualDataUpload.prototype.onUploadFormChange = function () {\n\t\tthis.emit( 'uploadValid', !!this.selectFileWidget.getValue() );\n\t};\n\n\tVisualDataUpload.prototype.renderInfoForm = function () {\n\t\tvar fieldset;\n\n\t\tthis.filePreview = new OO.ui.Widget( {\n\t\t\tclasses: [ 'mw-upload-bookletLayout-filePreview' ]\n\t\t} );\n\t\tthis.progressBarWidget = new OO.ui.ProgressBarWidget( {\n\t\t\tprogress: 0\n\t\t} );\n\t\tthis.filePreview.$element.append( this.progressBarWidget.$element );\n\n\t\tthis.filenameWidget = new OO.ui.TextInputWidget( {\n\t\t\tindicator: 'required',\n\t\t\trequired: true,\n\t\t\tvalidate: /.+/\n\t\t} );\n\t\tthis.descriptionWidget = new OO.ui.MultilineTextInputWidget( {\n\t\t\tindicator: 'required',\n\t\t\trequired: true,\n\t\t\tvalidate: /\\S+/,\n\t\t\tautosize: true\n\t\t} );\n\n\t\tfieldset = new OO.ui.FieldsetLayout( {\n\t\t\tlabel: mw.msg( 'upload-form-label-infoform-title' )\n\t\t} );\n\t\tfieldset.addItems( [\n\t\t\tnew OO.ui.FieldLayout( this.filenameWidget, {\n\t\t\t\tlabel: mw.msg( 'upload-form-label-infoform-name' ),\n\t\t\t\talign: 'top',\n\t\t\t\thelp: mw.msg( 'upload-form-label-infoform-name-tooltip' )\n\t\t\t} ),\n\t\t\tnew OO.ui.FieldLayout( this.descriptionWidget, {\n\t\t\t\tlabel: mw.msg( 'upload-form-label-infoform-description' ),\n\t\t\t\talign: 'top',\n\t\t\t\thelp: mw.msg( 'upload-form-label-infoform-description-tooltip' )\n\t\t\t} )\n\t\t] );\n\t\tthis.infoForm = new OO.ui.FormLayout( {\n\t\t\tclasses: [ 'mw-upload-bookletLayout-infoForm' ],\n\t\t\titems: [ this.filePreview, fieldset ]\n\t\t} );\n\n\t\tthis.on(\n\t\t\t'fileUploadProgress',\n\t\t\tfunction ( progress ) {\n\t\t\t\tthis.progressBarWidget.setProgress( progress * 100 );\n\t\t\t}.bind( this )\n\t\t);\n\n\t\tthis.filenameWidget.on( 'change', this.onInfoFormChange.bind( this ) );\n\t\tthis.descriptionWidget.on( 'change', this.onInfoFormChange.bind( this ) );\n\n\t\treturn this.infoForm;\n\t};\n\n\tVisualDataUpload.prototype.onInfoFormChange = function () {\n\t\tvar layout = this;\n\t\t$.when(\n\t\t\tthis.filenameWidget.getValidity(),\n\t\t\tthis.descriptionWidget.getValidity()\n\t\t)\n\t\t\t.done( function () {\n\t\t\t\tlayout.emit( 'infoValid', true );\n\t\t\t} )\n\t\t\t.fail( function () {\n\t\t\t\tlayout.emit( 'infoValid', false );\n\t\t\t} );\n\t};\n\n\tVisualDataUpload.prototype.renderInsertForm = function () {\n\t\tvar fieldset;\n\n\t\tthis.filenameUsageWidget = new OO.ui.TextInputWidget();\n\t\tfieldset = new OO.ui.FieldsetLayout( {\n\t\t\tlabel: mw.msg( 'upload-form-label-usage-title' )\n\t\t} );\n\t\tfieldset.addItems( [\n\t\t\tnew OO.ui.FieldLayout( this.filenameUsageWidget, {\n\t\t\t\tlabel: mw.msg( 'upload-form-label-usage-filename' ),\n\t\t\t\talign: 'top'\n\t\t\t} )\n\t\t] );\n\t\tthis.insertForm = new OO.ui.FormLayout( { items: [ fieldset ] } );\n\n\t\treturn this.insertForm;\n\t};\n\n\tVisualDataUpload.prototype.getFile = function () {\n\t\treturn this.selectFileWidget.getValue();\n\t};\n\n\tVisualDataUpload.prototype.getFilename = function () {\n\t\t// var filename = this.filenameWidget.getValue();\n\t\tvar filename = this.filename;\n\t\tif ( this.filenameExtension ) {\n\t\t\tfilename += '.' + this.filenameExtension;\n\t\t}\n\t\treturn filename;\n\t};\n\n\tVisualDataUpload.prototype.setFilename = function ( filename ) {\n\t\tvar title = mw.Title.newFromFileName( filename );\n\n\t\tif ( title ) {\n\t\t\t// this.filenameWidget.setValue( title.getNameText() );\n\t\t\tthis.filenameExtension = mw.Title.normalizeExtension(\n\t\t\t\ttitle.getExtension()\n\t\t\t);\n\n\t\t\tthis.filename = title.getNameText();\n\t\t} else {\n\t\t\t// Seems to happen for files with no extension, which should fail some checks anyway...\n\t\t\t// this.filenameWidget.setValue( filename );\n\t\t\tthis.filename = filename;\n\t\t\tthis.filenameExtension = null;\n\t\t}\n\t};\n\n\tVisualDataUpload.prototype.getText = function () {\n\t\treturn this.descriptionWidget.getValue();\n\t};\n\n\tVisualDataUpload.prototype.setFile = function ( file ) {\n\t\tthis.selectFileWidget.setValue( [ file ] );\n\t};\n\n\tVisualDataUpload.prototype.setFilekey = function ( filekey ) {\n\t\tthis.upload.setFilekey( this.filekey );\n\t\tthis.selectFileWidget.setValue( filekey );\n\n\t\tthis.onUploadFormChange();\n\t};\n\n\tVisualDataUpload.prototype.clear = function () {\n\t\tthis.selectFileWidget.setValue( null );\n\t\tthis.progressBarWidget.setProgress( 0 );\n\t\tthis.filenameWidget.setValue( null ).setValidityFlag( true );\n\t\tthis.descriptionWidget.setValue( null ).setValidityFlag( true );\n\t\tthis.filenameUsageWidget.setValue( null );\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":"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/VisualDataWindowManager.js","messages":[],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":25,"column":1,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":62,"endColumn":2,"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":"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/Widgets/VisualDataButtonMultiselectWidget.js","messages":[{"ruleId":"no-jquery/no-in-array","severity":1,"message":"Prefer Array#indexOf to $.inArray","line":48,"column":12,"nodeType":"CallExpression","endLine":48,"endColumn":59}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":24,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":59,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. 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( function () {\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataButtonMultiselectWidget = function ( config ) {\n\t\tconfig = config || {};\n\n\t\tif ( !( 'classes' in config ) ) {\n\t\t\tconfig.classes = [];\n\t\t}\n\n\t\tthis.options = {};\n\t\tfor ( var value of config.options ) {\n\t\t\tthis.options[ [ value.data ] ] = value.label;\n\t\t}\n\n\t\t// ***important, add position: relative to display\n\t\t// property native validation\n\t\tconfig.classes.push( 'visualdata-button-multiselect-widget' );\n\n\t\tVisualDataButtonMultiselectWidget.super.call( this, config );\n\n\t\tvar self = this;\n\t\tthis.items = {};\n\t\tfor ( var i in this.options ) {\n\t\t\tthis.items[ i ] = new OO.ui.ToggleButtonWidget( {\n\t\t\t\tdata: i,\n\t\t\t\tlabel: this.options[ i ],\n\t\t\t\tvalue: $.inArray( this.options[ i ], config.selected ) !== -1\n\t\t\t} );\n\n\t\t\tthis.items[ i ].on( 'change', function () {\n\t\t\t\tself.emit( 'change', self.getValue().join().trim() );\n\t\t\t} );\n\t\t}\n\n\t\tfor ( var i in this.items ) {\n\t\t\tthis.$element.append( this.items[ i ].$element );\n\t\t}\n\t};\n\n\tOO.inheritClass( VisualDataButtonMultiselectWidget, OO.ui.Widget );\n\tOO.mixinClass( VisualDataButtonMultiselectWidget, OO.EventEmitter );\n\n\tVisualDataButtonMultiselectWidget.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( this.options[ i ] );\n\t\t\t}\n\t\t}\n\t\treturn ret;\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":"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/Widgets/VisualDataDateTimeInputWidget.js","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 105. Maximum allowed is 100.","line":66,"column":1,"nodeType":"Program","messageId":"max","endLine":66,"endColumn":100}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":24,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":46,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright ©2025, https://wikisphere.org\n */\n\n( function () {\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataDateTimeInputWidget = function ( config ) {\n\t\tvar type = 'datetime';\n\n\t\tif ( VisualDataFunctions.getNestedProp( [ 'data', 'model', 'schema', 'format' ], config ) ) {\n\t\t\ttype = config.data.model.schema.format;\n\n\t\t\t// *** not used anymore, set always as local\n\t\t\tif ( type === 'datetime-local' ) {\n\t\t\t\ttype = 'datetime';\n\t\t\t}\n\t\t}\n\n\t\tvar formatter = {\n\t\t\tformat: '@' + type\n\t\t};\n\n\t\tconfig.formatter = new mw.widgets.datetime.ProlepticGregorianDateTimeFormatter( formatter );\n\n\t\t// config.formatter.local = ( config.data.model.schema.format === 'datetime-local' );\n\t\tconfig.formatter.local = true;\n\n\t\tVisualDataDateTimeInputWidget.super.call( this, config );\n\t};\n\n\tOO.inheritClass( VisualDataDateTimeInputWidget, mw.widgets.datetime.DateTimeInputWidget );\n\n\t/**\n\t * @inheritDoc\n\t */\n\tVisualDataDateTimeInputWidget.prototype.parseDateValue = function ( value ) {\n\t\tvalue = String( value );\n\t\tswitch ( this.type ) {\n\t\t\tcase 'date':\n\t\t\t\tvalue = value + 'T00:00:00Z';\n\t\t\t\tbreak;\n\t\t\tcase 'time':\n\t\t\t\tvalue = '1970-01-01T' + value + 'Z';\n\t\t\t\tbreak;\n\t\t}\n\n\t\tlet date;\n\n\t\t// const m = /^(\\d{4,})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?Z$/.exec( value );\n\t\t// ***edited, matches both +01:00 (ISO 8601 vP) and +0100 (ISO 8601 vO)\n\n\t\tconst m = /^(\\d{4,})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?(Z|[+-]\\d{2}:?\\d{2}|[+-]\\d{4})?$/.exec( value );\n\n\t\tif ( m ) {\n\t\t\tif ( m[ 7 ] ) {\n\t\t\t\twhile ( m[ 7 ].length < 3 ) {\n\t\t\t\t\tm[ 7 ] += '0';\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tm[ 7 ] = 0;\n\t\t\t}\n\t\t\tdate = new Date();\n\t\t\tdate.setUTCFullYear( m[ 1 ], m[ 2 ] - 1, m[ 3 ] );\n\t\t\tdate.setUTCHours( m[ 4 ], m[ 5 ], m[ 6 ], m[ 7 ] );\n\t\t\tif ( date.getTime() < -62167219200000 || date.getTime() > 253402300799999 ||\n\t\t\t\tdate.getUTCFullYear() !== +m[ 1 ] ||\n\t\t\t\tdate.getUTCMonth() + 1 !== +m[ 2 ] ||\n\t\t\t\tdate.getUTCDate() !== +m[ 3 ] ||\n\t\t\t\tdate.getUTCHours() !== +m[ 4 ] ||\n\t\t\t\tdate.getUTCMinutes() !== +m[ 5 ] ||\n\t\t\t\tdate.getUTCSeconds() !== +m[ 6 ] ||\n\t\t\t\tdate.getUTCMilliseconds() !== +m[ 7 ]\n\t\t\t) {\n\t\t\t\tdate = null;\n\t\t\t}\n\t\t} else {\n\t\t\tdate = null;\n\t\t}\n\n\t\treturn date;\n\t};\n\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":"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/Widgets/VisualDataDropdownWidget.js","messages":[{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":38,"column":7,"nodeType":"VariableDeclarator","endLine":38,"endColumn":71},{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":53,"column":7,"nodeType":"VariableDeclarator","endLine":59,"endColumn":21}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":24,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":62,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. 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( function () {\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataDropdownWidget = function ( config ) {\n\t\tconfig = config || {};\n\n\t\tif ( !( 'classes' in config ) ) {\n\t\t\tconfig.classes = [];\n\t\t}\n\t\tvar self = this;\n\n\t\tconfig.classes.push( 'visualdata-dropdown-widget' );\n\n\t\tVisualDataDropdownWidget.super.call( this, config );\n\n\t\tvar options = config.options;\n\n\t\tvar select = $( '<select>' ).attr( 'class', 'oo-ui-indicator-down' );\n\t\tfor ( var option of options ) {\n\t\t\tselect.append(\n\t\t\t\t$( '<option>' )\n\t\t\t\t\t.attr( { value: option.data, selected: option.data === config.value } )\n\t\t\t\t\t.text( option.label )\n\t\t\t);\n\t\t}\n\n\t\tthis.select = select;\n\n\t\tselect.on( 'change', function () {\n\t\t\tself.emit( 'change', self.getValue() );\n\t\t} );\n\n\t\tvar div = $( '<div>' )\n\t\t\t.attr(\n\t\t\t\t'class',\n\t\t\t\t'oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-dropdownInputWidget'\n\t\t\t)\n\n\t\t\t.append( select );\n\n\t\tthis.$element.append( div );\n\t};\n\n\tOO.inheritClass( VisualDataDropdownWidget, OO.ui.Widget );\n\tOO.mixinClass( VisualDataDropdownWidget, OO.EventEmitter );\n\n\tVisualDataDropdownWidget.prototype.getValue = function () {\n\t\treturn this.select.val();\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":"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/Widgets/VisualDataLookupElement.js","messages":[],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":24,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":29,"endColumn":3,"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":"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/Widgets/VisualDataMaptiler.js","messages":[{"ruleId":"no-jquery/no-sizzle","severity":1,"message":"Selector extensions are not allowed","line":41,"column":9,"nodeType":"CallExpression","endLine":41,"endColumn":43},{"ruleId":"no-throw-literal","severity":2,"message":"Expected an error object to be thrown.","line":43,"column":4,"nodeType":"ThrowStatement","messageId":"object","endLine":43,"endColumn":41},{"ruleId":"max-len","severity":1,"message":"This line has a length of 102. Maximum allowed is 100.","line":66,"column":1,"nodeType":"Program","messageId":"max","endLine":66,"endColumn":91},{"ruleId":"max-len","severity":1,"message":"This line has a length of 123. Maximum allowed is 100.","line":68,"column":1,"nodeType":"Program","messageId":"max","endLine":68,"endColumn":112}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":26,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":31,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'config' is defined but never used.","line":26,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":26,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'self' is assigned a value but never used.","line":38,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":38,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":57,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":57,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'e' is defined but never used.","line":58,"column":62,"nodeType":"Identifier","messageId":"unusedVar","endLine":58,"endColumn":63,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'res' is defined but never used.","line":89,"column":27,"nodeType":"Identifier","messageId":"unusedVar","endLine":89,"endColumn":30,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'res' is defined but never used.","line":95,"column":41,"nodeType":"Identifier","messageId":"unusedVar","endLine":95,"endColumn":44,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'res' is defined but never used.","line":106,"column":37,"nodeType":"Identifier","messageId":"unusedVar","endLine":106,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'res' is defined but never used.","line":110,"column":47,"nodeType":"Identifier","messageId":"unusedVar","endLine":110,"endColumn":50,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'res' is defined but never used.","line":114,"column":47,"nodeType":"Identifier","messageId":"unusedVar","endLine":114,"endColumn":50,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2024, https://wikisphere.org\n */\n\n/* eslint-disable no-unused-vars */\n\n( function () {\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataMaptiler = function ( config ) {\n\t\tthis.scripts = [\n\t\t\t'https://cdn.maptiler.com/maptiler-sdk-js/v1.2.0/maptiler-sdk.umd.min.js',\n\t\t\t'https://cdn.maptiler.com/maptiler-geocoding-control/v1.2.0/maptilersdk.umd.js'\n\t\t];\n\t};\n\n\tVisualDataMaptiler.prototype.load = function () {\n\t\tVisualDataFunctions.loadScripts( this.scripts );\n\t};\n\n\tVisualDataMaptiler.prototype.initialize = async function ( $element, data ) {\n\t\tvar self = this;\n\n\t\t// only load scripts\n\t\tif ( !$element.parent().is( ':visible' ) ) {\n\t\t\tVisualDataFunctions.loadScripts( this.scripts );\n\t\t\tthrow 'Maptiler element not visible';\n\t\t}\n\n\t\t// *** prevents ajv error \"Maximum call stack size exceeded\"\n\t\tvar config = VisualDataFunctions.deepCopy( data.schema.wiki );\n\t\tvar latInput = data.model.properties.latitude.input;\n\t\tvar lngInput = data.model.properties.longitude.input;\n\t\tvar zoomInput = data.model.properties.zoom.input;\n\t\tvar mapId = 'visualdata-maptiler-map-' + data.path;\n\n\t\tif ( $( '#' + jQuery.escapeSelector( mapId ) ).length ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tVisualDataFunctions.loadScripts( this.scripts, function ( e ) {\n\t\t\t\tmaptilersdk.config.apiKey = mw.config.get( 'visualdata-maptiler-apikey' );\n\t\t\t\tvar $container = $( '<div style=\"width:100%;height:400px\" id=\"' + mapId + '\" />' );\n\t\t\t\t$element.append( $container );\n\n\t\t\t\tconfig[ 'maptiler-map-config' ].container = mapId;\n\t\t\t\tconfig[ 'maptiler-map-config' ].style = maptilersdk.MapStyle.HYBRID;\n\n\t\t\t\tvar center = [ parseFloat( lngInput.getValue() ), parseFloat( latInput.getValue() ) ];\n\n\t\t\t\tvar isValidCenter = !VisualDataFunctions.isNaN( center[ 0 ] ) && !VisualDataFunctions.isNaN( center[ 1 ] );\n\n\t\t\t\tif ( isValidCenter ) {\n\t\t\t\t\tconfig[ 'maptiler-map-config' ].center = center;\n\t\t\t\t\tconfig[ 'maptiler-map-config' ].zoom = parseInt( zoomInput.getValue() );\n\t\t\t\t\tconfig[ 'maptiler-map-config' ].geolocate = false;\n\n\t\t\t\t} else {\n\t\t\t\t\tif ( !( 'geolocate' in config[ 'maptiler-map-config' ] ) ) {\n\t\t\t\t\t\tconfig[ 'maptiler-map-config' ].geolocate = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst map = ( window.map = new maptilersdk.Map( config[ 'maptiler-map-config' ] ) );\n\t\t\t\tconfig[ 'maptiler-map-config' ].marker = false;\n\n\t\t\t\tvar marker;\n\n\t\t\t\tif ( config[ 'reverse-geocoding' ] ) {\n\t\t\t\t\tconst gc = new maptilersdkMaptilerGeocoder.GeocodingControl( config[ 'maptiler-map-config' ] );\n\n\t\t\t\t\tmap.on( 'zoomend', ( res ) => {\n\t\t\t\t\t\t// console.log('zoomend:', res);\n\t\t\t\t\t\tzoomInput.setValue( map.getZoom() );\n\t\t\t\t\t} );\n\n\t\t\t\t\t// https://docs.maptiler.com/sdk-js/modules/geocoding/api/api-reference/#event:featuresListed\n\t\t\t\t\tgc.addEventListener( 'response', ( res ) => {\n\t\t\t\t\t\t// console.log(\"response:\", res);\n\t\t\t\t\t} );\n\n\t\t\t\t\tgc.addEventListener( 'select', ( res ) => {\n\t\t\t\t\t\t// console.log(\"select:\", res );\n\t\t\t\t\t\tif ( res.detail ) {\n\t\t\t\t\t\t\tmarker.setLngLat( res.detail.center );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t\tgc.addEventListener( 'pick', ( res ) => {\n\t\t\t\t\t\t// console.log(\"pick:\", res );\n\t\t\t\t\t} );\n\n\t\t\t\t\tgc.addEventListener( 'featuresListed', ( res ) => {\n\t\t\t\t\t\t// console.log(\"featuresListed:\", res);\n\t\t\t\t\t} );\n\n\t\t\t\t\tgc.addEventListener( 'featuresMarked', ( res ) => {\n\t\t\t\t\t\t// console.log(\"featuresMarked:\", res);\n\t\t\t\t\t} );\n\n\t\t\t\t\tmap.addControl( gc, 'top-left' );\n\t\t\t\t}\n\n\t\t\t\tfunction onDragEnd() {\n\t\t\t\t\tvar lngLat = marker.getLngLat();\n\t\t\t\t\tsetTimeout( function () {\n\t\t\t\t\t\tlngInput.setValue( lngLat.lng );\n\t\t\t\t\t\tlatInput.setValue( lngLat.lat );\n\t\t\t\t\t\tzoomInput.setValue( map.getZoom() );\n\t\t\t\t\t}, 100 );\n\t\t\t\t}\n\n\t\t\t\tmap.on( 'load', function () {\n\t\t\t\t\tif ( !marker ) {\n\t\t\t\t\t\tmarker = new maptilersdk.Marker( {\n\t\t\t\t\t\t\tdraggable: true\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.setLngLat( map.getCenter() )\n\t\t\t\t\t\t\t.addTo( map );\n\n\t\t\t\t\t\tmarker.on( 'dragend', onDragEnd );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\tif ( isValidCenter ) {\n\t\t\t\t\tmarker = new maptilersdk.Marker( {\n\t\t\t\t\t\tdraggable: true\n\t\t\t\t\t} )\n\t\t\t\t\t\t.setLngLat( center )\n\t\t\t\t\t\t.addTo( map );\n\n\t\t\t\t\tmarker.on( 'dragend', onDragEnd );\n\t\t\t\t}\n\n\t\t\t\t// update marker\n\t\t\t\tdata.model.properties.latitude.input.on( 'change', function ( value ) {\n\t\t\t\t\tmarker.setLngLat( [ lngInput.getValue(), value ] );\n\t\t\t\t} );\n\t\t\t\tdata.model.properties.longitude.input.on( 'change', function ( value ) {\n\t\t\t\t\tmarker.setLngLat( [ value, latInput.getValue() ] );\n\t\t\t\t} );\n\n\t\t\t\tresolve();\n\t\t\t} );\n\t\t} );\n\t};\n\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":"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/Widgets/VisualDataMenuTagSearchMultiselect.js","messages":[{"ruleId":"jsdoc/check-tag-names","severity":1,"message":"Invalid JSDoc tag name \"mixins\".","line":29,"column":1,"nodeType":"Block","endLine":29,"endColumn":1},{"ruleId":"max-len","severity":1,"message":"This line has a length of 110. Maximum allowed is 100.","line":49,"column":1,"nodeType":"Program","messageId":"max","endLine":49,"endColumn":99},{"ruleId":"max-len","severity":1,"message":"This line has a length of 107. Maximum allowed is 100.","line":50,"column":1,"nodeType":"Program","messageId":"max","endLine":50,"endColumn":96}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":37,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":71,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2023, https://wikisphere.org\n */\n\n// @credits: mw.widgets.CategoryMultiselectWidget\n\n( function () {\n\t/**\n\t * @class VisualDataMenuTagSearchMultiselect\n\t * @uses mw.Api\n\t * @extends OO.ui.MenuTagMultiselectWidget\n\t * @mixins OO.ui.mixin.PendingElement\n\t *\n\t * @constructor\n\t * @param {Object} [config] Configuration options\n\t * @cfg {number} [limit=10] Maximum number of results to load\n\t */\n\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataMenuTagSearchMultiselect = function ( config ) {\n\t\t// Config initialization\n\t\tthis.limit = config.limit;\n\n\t\t// Parent constructor\n\t\tVisualDataMenuTagSearchMultiselect.parent.call(\n\t\t\tthis,\n\t\t\t$.extend( true, {}, config, {\n\t\t\t\tmenu: {\n\t\t\t\t\tfilterFromInput: false\n\t\t\t\t},\n\t\t\t\tplaceholder: mw.msg( 'visualdata-menutagmultiselect-placeholder' )\n\t\t\t\t// This allows the user to both select non-existent categories, and prevents the selector from\n\t\t\t\t// being wiped from #onMenuItemsChange when we change the available options in the dropdown\n\t\t\t\t// allowArbitrary: false\n\t\t\t} )\n\t\t);\n\n\t\t// Mixin constructors\n\t\tOO.ui.mixin.PendingElement.call(\n\t\t\tthis,\n\t\t\t$.extend( {}, config, { $pending: this.$handle } )\n\t\t);\n\n\t\t// Event handler to call the autocomplete methods\n\t\tthis.input.$input.on(\n\t\t\t'change input cut paste',\n\t\t\tOO.ui.debounce( this.updateMenuItems.bind( this ), 100 )\n\t\t);\n\n\t\t// Initialize\n\t\t// @TODO\n\t\tthis.api = { abort: function () {} }; // config.api || new mw.Api();\n\t\tthis.searchCache = {};\n\t};\n\n\t/* Setup */\n\n\tOO.inheritClass(\n\t\tVisualDataMenuTagSearchMultiselect,\n\t\tOO.ui.MenuTagMultiselectWidget\n\t);\n\tOO.mixinClass(\n\t\tVisualDataMenuTagSearchMultiselect,\n\t\tOO.ui.mixin.PendingElement\n\t);\n\n\t/* Methods */\n\n\t/**\n\t * Gets new items based on the input by calling\n\t * {@link #getNewMenuItems getNewItems} and updates the menu\n\t * after removing duplicates based on the data value.\n\t *\n\t * @private\n\t * @method\n\t */\n\tVisualDataMenuTagSearchMultiselect.prototype.updateMenuItems =\n\t\tfunction () {\n\t\t\tthis.getMenu().clearItems();\n\t\t\tthis.getNewMenuItems( this.input.$input.val() ).then(\n\t\t\t\tfunction ( items ) {\n\t\t\t\t\tvar existingItems,\n\t\t\t\t\t\tmenu = this.getMenu();\n\n\t\t\t\t\t// Never show the menu if the input lost focus in the meantime\n\t\t\t\t\tif ( !this.input.$input.is( ':focus' ) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Array of strings of the data of OO.ui.MenuOptionsWidgets\n\t\t\t\t\texistingItems = menu.getItems().map( function ( item ) {\n\t\t\t\t\t\treturn item.data;\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Remove if items' data already exists\n\t\t\t\t\tfor ( var i in items ) {\n\t\t\t\t\t\tif ( existingItems.includes( i ) ) {\n\t\t\t\t\t\t\tdelete items[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Map to an array of OO.ui.MenuOptionWidgets\n\t\t\t\t\tvar ret = [];\n\t\t\t\t\tfor ( var i in items ) {\n\t\t\t\t\t\tret.push(\n\t\t\t\t\t\t\tnew OO.ui.MenuOptionWidget( {\n\t\t\t\t\t\t\t\tdata: i,\n\t\t\t\t\t\t\t\tlabel: items[ i ]\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tmenu.addItems( ret ).toggle( true );\n\t\t\t\t}.bind( this )\n\t\t\t);\n\t\t};\n\n\t/**\n\t * @inheritdoc\n\t */\n\tVisualDataMenuTagSearchMultiselect.prototype.clearInput = function () {\n\t\tVisualDataMenuTagSearchMultiselect.parent.prototype.clearInput.call(\n\t\t\tthis\n\t\t);\n\t\t// Abort all pending requests, we won't need their results\n\t\tthis.api.abort();\n\t};\n\n\t/**\n\t * Searches for categories based on the input.\n\t *\n\t * @private\n\t * @method\n\t * @param {string} input The input used to prefix search categories\n\t * @return {jQuery.Promise} Resolves with an array of categories\n\t */\n\tVisualDataMenuTagSearchMultiselect.prototype.getNewMenuItems = function (\n\t\tinput\n\t) {\n\t\tvar deferred = $.Deferred();\n\n\t\tif ( input.trim() === '' ) {\n\t\t\tdeferred.resolve( [] );\n\t\t\treturn deferred.promise();\n\t\t}\n\n\t\t// Abort all pending requests, we won't need their results\n\t\tthis.api.abort();\n\n\t\tthis.pushPending();\n\n\t\treturn this.searchItems( input ).always( this.popPending.bind( this ) );\n\t};\n\n\t/**\n\t * @private\n\t * @method\n\t * @param {string} value The input value\n\t * @return {jQuery.Promise} Resolves with an array of items\n\t */\n\tVisualDataMenuTagSearchMultiselect.prototype.searchItems = function (\n\t\tvalue\n\t) {\n\t\tvar deferred = $.Deferred(),\n\t\t\tcacheKey = value;\n\n\t\t// Check cache\n\t\tif ( cacheKey in this.searchCache ) {\n\t\t\treturn this.searchCache[ cacheKey ];\n\t\t}\n\n\t\tthis.data.performQuery( this.data.model, value ).then( ( data ) => {\n\t\t\tdeferred.resolve( data );\n\t\t} );\n\n\t\t// Cache the result\n\t\tthis.searchCache[ cacheKey ] = deferred.promise();\n\n\t\treturn deferred.promise( { abort: function () {} } );\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":"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/Widgets/VisualDataRatingWidget.js","messages":[{"ruleId":"no-jquery/no-parse-html-literal","severity":1,"message":"Prefer DOM building to parsing HTML literals","line":38,"column":19,"nodeType":"CallExpression","endLine":38,"endColumn":47},{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":45,"column":8,"nodeType":"VariableDeclarator","endLine":51,"endColumn":7},{"ruleId":"no-jquery/no-sizzle","severity":1,"message":"Selector extensions are not allowed","line":67,"column":6,"nodeType":"CallExpression","endLine":69,"endColumn":7}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":24,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":91,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"eqeqeq","severity":2,"message":"Expected '===' and instead saw '=='.","line":54,"column":11,"nodeType":"BinaryExpression","messageId":"unexpected","endLine":54,"endColumn":13,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"eqeqeq","severity":2,"message":"Expected '===' and instead saw '=='.","line":64,"column":25,"nodeType":"BinaryExpression","messageId":"unexpected","endLine":64,"endColumn":27,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2021-2022, https://wikisphere.org\n */\n\n( function () {\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataRatingWidget = function ( config ) {\n\t\tconfig = config || {};\n\n\t\tif ( !( 'classes' in config ) ) {\n\t\t\tconfig.classes = [];\n\t\t}\n\n\t\t// ***important, add position: relative to display\n\t\t// property native validation\n\t\tconfig.classes.push( 'visualdata-rating-widget' );\n\n\t\tVisualDataRatingWidget.super.call( this, config );\n\n\t\t// @see https://iamkate.com/code/star-rating-widget/\n\t\tvar $fieldset = $( ' <div class=\"rating\">' );\n\n\t\tthis.$input = $fieldset;\n\n\t\tvar self = this;\n\t\tthis.isChecked = 0;\n\t\tfor ( var i = 1; i < 6; i++ ) {\n\t\t\tvar input = $( '<input>' ).attr( {\n\t\t\t\ttype: 'radio',\n\t\t\t\tvalue: i,\n\t\t\t\tid: 'rating-' + i,\n\t\t\t\tname: config.name,\n\t\t\t\t'data-i': i\n\t\t\t} );\n\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( i == config.value ) {\n\t\t\t\tinput.prop( 'checked', true );\n\t\t\t\tthis.isChecked = i;\n\t\t\t}\n\n\t\t\t// uncheck the radio button if\n\t\t\t// alread selected, and check the previous one\n\t\t\tinput.on( 'click', function () {\n\t\t\t\tvar ii = $( this ).data( 'i' );\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\tif ( self.isChecked == ii ) {\n\t\t\t\t\tself.isChecked = ii - 1;\n\t\t\t\t\t$( this ).prop( 'checked', false );\n\t\t\t\t\t$(\n\t\t\t\t\t\t\":input[name='\" + config.name + \"'][data-i='\" + ( ii - 1 ) + \"']\"\n\t\t\t\t\t).prop( 'checked', true );\n\t\t\t\t} else {\n\t\t\t\t\tself.isChecked = ii;\n\t\t\t\t}\n\n\t\t\t\tself.emit( 'change', self.getValue() );\n\n\t\t\t} );\n\n\t\t\t$fieldset.append( [\n\t\t\t\tinput,\n\t\t\t\t$( '<label>' ).attr( {\n\t\t\t\t\tfor: 'rating-' + i\n\t\t\t\t} )\n\t\t\t] );\n\t\t}\n\n\t\tthis.getValue = function () {\n\t\t\treturn this.isChecked ? String( this.isChecked ) : '';\n\t\t};\n\n\t\tthis.$element.append( $fieldset );\n\t};\n\n\tOO.inheritClass( VisualDataRatingWidget, OO.ui.Widget );\n\tOO.mixinClass( VisualDataRatingWidget, OO.EventEmitter );\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":"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/Widgets/VisualDataTinyMCE.js","messages":[{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":39,"column":3,"nodeType":"AssignmentExpression","endLine":41,"endColumn":34},{"ruleId":"no-jquery/no-parse-html-literal","severity":1,"message":"Prefer DOM building to parsing HTML literals","line":39,"column":19,"nodeType":"CallExpression","endLine":39,"endColumn":45},{"ruleId":"no-jquery/no-sizzle","severity":1,"message":"Selector extensions are not allowed","line":66,"column":9,"nodeType":"CallExpression","endLine":66,"endColumn":48},{"ruleId":"no-throw-literal","severity":2,"message":"Expected an error object to be thrown.","line":68,"column":4,"nodeType":"ThrowStatement","messageId":"object","endLine":68,"endColumn":40}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":26,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":54,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'self' is assigned a value but never used.","line":31,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":31,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":71,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":71,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'e' is defined but never used.","line":72,"column":62,"nodeType":"Identifier","messageId":"unusedVar","endLine":72,"endColumn":63,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2024, https://wikisphere.org\n */\n\n/* eslint-disable no-unused-vars */\n\n( function () {\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataTinyMCE = function ( config ) {\n\t\tconfig = config || {};\n\t\tif ( !( 'classes' in config ) ) {\n\t\t\tconfig.classes = [];\n\t\t}\n\t\tvar self = this;\n\t\tthis.initialized = false;\n\t\tthis.config = config;\n\n\t\tVisualDataTinyMCE.super.call( this, config );\n\n\t\tthis.textareaId = 'visualdata-tinimce-' + config.data.model.path;\n\n\t\tthis.textarea = $( '<textarea rows=\"8\">' )\n\t\t\t.attr( 'name', config.name )\n\t\t\t.attr( 'id', this.textareaId );\n\n\t\tthis.text = this.config.value || '';\n\t\tthis.textarea.val( this.text );\n\n\t\tthis.$element.append( this.textarea );\n\n\t\tvar mw_extensionAssetsPath = mw.config.get( 'wgExtensionAssetsPath' );\n\t\tthis.basePath = mw_extensionAssetsPath + '/VisualData/resources/tinymce';\n\n\t\tthis.scripts = [\n\t\t\tthis.basePath + '/tinymce.min.js'\n\t\t];\n\t};\n\n\tOO.inheritClass( VisualDataTinyMCE, OO.ui.Widget );\n\tOO.mixinClass( VisualDataTinyMCE, OO.EventEmitter );\n\n\tVisualDataTinyMCE.prototype.initialize = async function () {\n\t\tvar self = this;\n\t\tif ( self.initialized ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// only load scripts\n\t\tif ( !self.$element.parent().is( ':visible' ) ) {\n\t\t\tVisualDataFunctions.loadScripts( this.scripts );\n\t\t\tthrow 'TinyMCE element not visible';\n\t\t}\n\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tVisualDataFunctions.loadScripts( this.scripts, function ( e ) {\n\t\t\t\tthis.tinymce = tinymce.init( {\n\t\t\t\t\tbase_url: this.basePath,\n\t\t\t\t\tstatusbar: false,\n\t\t\t\t\tselector: '#' + jQuery.escapeSelector( self.textareaId ),\n\t\t\t\t\tobject_resizing: true,\n\t\t\t\t\tallow_html_in_named_anchor: true,\n\t\t\t\t\tbrowser_spellcheck: true,\n\t\t\t\t\tautomatic_uploads: true,\n\t\t\t\t\tpaste_data_images: true,\n\t\t\t\t\tshowPlaceholders: false,\n\t\t\t\t\tdecodeHtmlEntitiesOnInput: false,\n\t\t\t\t\tauto_focus: true,\n\t\t\t\t\tvisual: false,\n\t\t\t\t\tsetup: function ( editor ) {\n\t\t\t\t\t\teditor.on( 'init', function () {\n\t\t\t\t\t\t\tself.initialized = true;\n\t\t\t\t\t\t\t// editor.setContent( self.text );\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t\t// license_key: 'gpl|<your-license-key>',\n\t\t\t\t} );\n\t\t\t} );\n\t\t} );\n\t};\n\n\tVisualDataTinyMCE.prototype.getValue = function () {\n\t\tif ( typeof tinymce === 'undefined' ) {\n\t\t\treturn this.text;\n\t\t}\n\t\tvar editor = tinymce.get( this.textareaId );\n\t\tif ( editor && this.initialized ) {\n\t\t\treturn editor.getContent( this.textareaId );\n\t\t}\n\t\treturn this.text;\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":"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/Widgets/VisualDataVisualEditor.js","messages":[{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":40,"column":3,"nodeType":"AssignmentExpression","endLine":42,"endColumn":47},{"ruleId":"no-jquery/no-parse-html-literal","severity":1,"message":"Prefer DOM building to parsing HTML literals","line":40,"column":19,"nodeType":"CallExpression","endLine":40,"endColumn":45},{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":47,"column":3,"nodeType":"AssignmentExpression","endLine":47,"endColumn":69},{"ruleId":"no-jquery/no-sizzle","severity":1,"message":"Selector extensions are not allowed","line":69,"column":9,"nodeType":"CallExpression","endLine":69,"endColumn":48},{"ruleId":"no-throw-literal","severity":2,"message":"Expected an error object to be thrown.","line":70,"column":4,"nodeType":"ThrowStatement","messageId":"object","endLine":70,"endColumn":41}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":27,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":54,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'self' is assigned a value but never used.","line":32,"column":7,"nodeType":"Identifier","messageId":"unusedVar","endLine":32,"endColumn":11,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":37,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":37,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":97,"column":38,"nodeType":"Identifier","messageId":"unusedVar","endLine":97,"endColumn":44,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":101,"column":49,"nodeType":"Identifier","messageId":"unusedVar","endLine":101,"endColumn":55,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'e' is defined but never used.","line":102,"column":56,"nodeType":"Identifier","messageId":"unusedVar","endLine":102,"endColumn":57,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":161,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":161,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'reject' is defined but never used.","line":165,"column":34,"nodeType":"Identifier","messageId":"unusedVar","endLine":165,"endColumn":40,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":1,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2023-2024, https://wikisphere.org\n */\n\n/* eslint-disable no-tabs */\n/* eslint-disable no-unused-vars */\n\n( function () {\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataVisualEditor = function ( config ) {\n\t\tconfig = config || {};\n\t\tif ( !( 'classes' in config ) ) {\n\t\t\tconfig.classes = [];\n\t\t}\n\t\tvar self = this;\n\t\tthis.config = config;\n\n\t\t// @FIXME only allows wikitext for now\n\t\t// this.isHtml =\n\t\t// \t\"contentModel\" in this.config && this.config.contentModel === \"html\";\n\t\tVisualDataVisualEditor.super.call( this, config );\n\n\t\tthis.textarea = $( '<textarea rows=\"8\">' )\n\t\t\t.attr( 'name', config.name )\n\t\t\t.attr( 'class', 'visualdata toolbarOnTop' );\n\n\t\tthis.text = this.config.value || '';\n\t\tthis.textarea.val( this.text );\n\n\t\tthis.VEInstance = $( '<span>' ).attr( 'class', 've-area-wrapper' );\n\t\tthis.$element.append( this.VEInstance.append( this.textarea ) );\n\t\tthis.Editor = null;\n\t\t// this.editorID = VisualDataFunctions.uniqueID();\n\n\t\tthis.initializing = false;\n\t\tthis.destroyEditor();\n\t};\n\n\tOO.inheritClass( VisualDataVisualEditor, OO.ui.Widget );\n\tOO.mixinClass( VisualDataVisualEditor, OO.EventEmitter );\n\n\t// @see https://github.com/Open-CSP/FlexForm/blob/main/Modules/FlexForm.general.js\n\tVisualDataVisualEditor.prototype.initialize = async function () {\n\t\tvar self = this;\n\n\t\tif ( this.isInitialized() || this.initializing ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.initializing = true;\n\n\t\tif ( !self.$element.parent().is( ':visible' ) ) {\n\t\t\tthrow 'VEForAll element not visible';\n\t\t}\n\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tthis.loadVEForAll().then( function () {\n\t\t\t\tvar editor = self.getNewEditor();\n\t\t\t\tif ( editor ) {\n\t\t\t\t\tself.Editor = editor;\n\t\t\t\t\teditor.initCallbacks.push( function () {\n\t\t\t\t\t\tself.initializing = false;\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t} );\n\t\t\t\t} else {\n\t\t\t\t\treject( 'VEForAll no editor' );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t};\n\n\t// @see https://github.com/Open-CSP/FlexForm/blob/main/Modules/FlexForm.general.js\n\tVisualDataVisualEditor.prototype.loadVEForAll = async function () {\n\t\tvar self = this;\n\n\t\tvar callbackCond = function () {\n\t\t\treturn typeof $().applyVisualEditor === 'function';\n\t\t};\n\n\t\tvar callback = function ( resolve, reject ) {\n\t\t\tself.textarea.applyVisualEditor();\n\t\t\tresolve();\n\t\t};\n\t\tvar callbackMaxAttempts = function ( resolve, reject ) {\n\t\t\tjQuery( document ).on( 'VEForAllLoaded', function ( e ) {\n\t\t\t\tself.textarea.applyVisualEditor();\n\t\t\t\tresolve();\n\t\t\t} );\n\t\t};\n\n\t\treturn VisualDataFunctions.waitUntil(\n\t\t\tcallbackCond,\n\t\t\tcallback,\n\t\t\tcallbackMaxAttempts,\n\t\t\t5\n\t\t);\n\t};\n\n\tVisualDataVisualEditor.prototype.destroyEditor = function () {\n\t\tif ( typeof $.fn.getVEInstances === 'function' ) {\n\t\t\tvar visualEditors = $.fn.getVEInstances();\n\t\t\tfor ( var i in visualEditors ) {\n\t\t\t\tvar editor = visualEditors[ i ];\n\t\t\t\tif ( $( editor.$node ).attr( 'name' ) === this.config.name ) {\n\t\t\t\t\teditor.destroy();\n\t\t\t\t\tvisualEditors.splice( i, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// @see PageForms PF_submit.js\n\tVisualDataVisualEditor.prototype.getNewEditor = function () {\n\t\tif ( !( 'getVEInstances' in $.fn ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar visualEditors = $.fn.getVEInstances();\n\t\tfor ( var editor of visualEditors ) {\n\t\t\tif ( $( editor.$node ).attr( 'name' ) === this.config.name ) {\n\t\t\t\treturn editor;\n\t\t\t}\n\t\t}\n\t};\n\n\t// @see PageForms PF_submit.js\n\tVisualDataVisualEditor.prototype.getEditor = function () {\n\t\treturn this.Editor;\n\t};\n\n\tVisualDataVisualEditor.prototype.isInitialized = function () {\n\t\tvar editor = this.getEditor();\n\t\treturn ( editor && ( 'target' in editor ) );\n\t};\n\n\tVisualDataVisualEditor.prototype.getValue = async function () {\n\t\tvar self = this;\n\n\t\tif ( !this.isInitialized() ) {\n\t\t\treturn this.textarea.val();\n\t\t}\n\n\t\t// if (this.isHtml) {\n\t\t// \treturn VisualDataFunctions.decodeHTMLEntities( editor.target.getSurface().getHtml() );\n\t\t// }\n\n\t\tvar editor = this.getEditor();\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\t$.when( editor.target.updateContent() ).then( function () {\n\t\t\t\t// @see ext.veforall.target.js\n\t\t\t\t// *** sometimes convertToWikiText is not called\n\t\t\t\t// based on focus\n\t\t\t\teditor.target.$node.addClass( 've-for-all-waiting-for-update' );\n\t\t\t\tresolve( self.textarea.val() );\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":"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/Widgets/VisualDataintlTelInput.js","messages":[{"ruleId":"no-jquery/variable-pattern","severity":1,"message":"jQuery collection names must match the variablePattern","line":38,"column":7,"nodeType":"VariableDeclarator","endLine":43,"endColumn":6}],"suppressedMessages":[{"ruleId":"no-implicit-globals","severity":2,"message":"Global variable leak, declare the variable if it is intended to be local.","line":26,"column":2,"nodeType":"AssignmentExpression","messageId":"globalVariableLeak","endLine":91,"endColumn":3,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":51,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":51,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-tabs","severity":2,"message":"Unexpected tab character.","line":52,"column":6,"nodeType":"Program","messageId":"unexpectedTab","endLine":52,"endColumn":7,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"new-cap","severity":2,"message":"A constructor name should not start with a lowercase letter.","line":176,"column":25,"nodeType":"NewExpression","messageId":"lower","endLine":176,"endColumn":37,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":186,"column":7,"nodeType":"MemberExpression","messageId":"unexpected","endLine":186,"endColumn":20,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[5048,5110],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":2,"message":"Unexpected console statement.","line":195,"column":7,"nodeType":"MemberExpression","messageId":"unexpected","endLine":195,"endColumn":20,"suggestions":[{"messageId":"removeConsole","data":{"propertyName":"error"},"fix":{"range":[5308,5361],"text":""},"desc":"Remove the console.error()."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. 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/* eslint-disable no-tabs */\n\n( function () {\n\t// eslint-disable-next-line no-implicit-globals\n\tVisualDataIntlTelInput = function ( config ) {\n\t\tVisualDataIntlTelInput.super.call( this, config );\n\n\t\tvar self = this;\n\t\tthis.config = config;\n\n\t\t// https://github.com/jackocnr/intl-tel-input/tree/master?tab=readme-ov-file\n\t\tif ( 'nationalMode' in this.config && this.config.nationalMode === true ) {\n\t\t\tthis.config.showFlags = false;\n\t\t\tthis.config.allowDropdown = false;\n\t\t}\n\n\t\tvar input = $( '<input>' ).attr( {\n\t\t\ttype: 'tel',\n\t\t\tname: config.name,\n\t\t\tvalue: config.value,\n\t\t\tclass: 'oo-ui-inputWidget-input'\n\t\t} );\n\n\t\tthis.input = input;\n\n\t\t// required when handled by OO.ui.TagMultiselectWidget -> inputWidget: inputWidget\n\t\tthis.$input = input;\n\n\t\t// input.on(\"input\", function () {\n\t\t// \tself.config.value = self.input.val();\n\t\t// \tself.emit(\"change\", self.config.value);\n\t\t// });\n\n\t\tinput.on( 'blur', function () {\n\t\t\tself.formatNumber();\n\t\t} );\n\n\t\tthis.$element = $( '<div>' )\n\t\t\t.attr(\n\t\t\t\t'class',\n\t\t\t\t'oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-textInputWidget oo-ui-textInputWidget-type-text'\n\t\t\t)\n\t\t\t.append( input );\n\n\t\tself.fixConfigCountries( config );\n\n\t\tself.iti = window.intlTelInput(\n\t\t\tinput.get( 0 ),\n\t\t\t$.extend(\n\t\t\t\t{\n\t\t\t\t\tutilsScript:\n\t\t\t\t\t\t'https://cdn.jsdelivr.net/npm/intl-tel-input@18.3.3/build/js/utils.js',\n\t\t\t\t\tinitialCountry: 'auto',\n\t\t\t\t\tgeoIpLookup: function ( callback ) {\n\t\t\t\t\t\tfetch( 'https://ipapi.co/json' )\n\t\t\t\t\t\t\t.then( function ( res ) {\n\t\t\t\t\t\t\t\treturn res.json();\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.then( function ( data ) {\n\t\t\t\t\t\t\t\tcallback( data.country_code );\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.catch( function () {\n\t\t\t\t\t\t\t\tcallback( 'us' );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tconfig\n\t\t\t)\n\t\t);\n\t};\n\n\tOO.inheritClass( VisualDataIntlTelInput, OO.ui.Widget );\n\tOO.mixinClass( VisualDataIntlTelInput, OO.EventEmitter );\n\n\tVisualDataIntlTelInput.prototype.formatNumber = function () {\n\t\tif ( typeof intlTelInputUtils === 'undefined' ) {\n\t\t\treturn;\n\t\t}\n\t\t// https://github.com/jackocnr/intl-tel-input/blob/master/src/js/utils.js#L109\n\t\tvar numberFormat = intlTelInputUtils.numberFormat.E164;\n\t\tif ( 'nationalMode' in this.config && this.config.nationalMode === true ) {\n\t\t\tnumberFormat = intlTelInputUtils.numberFormat.NATIONAL;\n\t\t}\n\n\t\tif ( typeof this.iti === 'object' && typeof intlTelInputUtils === 'object' ) {\n\t\t\tthis.setValue(\n\t\t\t\tthis.iti.getNumber( numberFormat )\n\t\t\t);\n\t\t}\n\t};\n\n\tVisualDataIntlTelInput.prototype.validateFunc = async function () {\n\t\tif ( this.getValue().trim() === '' ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( !this.iti.isPossibleNumber() ) {\n\t\t\t// https://github.com/jackocnr/intl-tel-input/blob/master/src/js/utils.js#L148\n\t\t\tvar error = this.iti.getValidationError();\n\t\t\tvar msg = '';\n\t\t\tswitch ( error ) {\n\t\t\t\tcase 1:\n\t\t\t\t\tmsg = 'invalid country code';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tmsg = 'too short';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\tmsg = 'too long';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\tmsg = 'is possible local only';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\tmsg = 'invalid length';\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn 'wrong number' + ( msg ? `: ${ msg }` : '' );\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tVisualDataIntlTelInput.prototype.getValue = function () {\n\t\tthis.formatNumber();\n\t\t// return this.config.value;\n\t\treturn this.input.val();\n\t};\n\n\tVisualDataIntlTelInput.prototype.setValue = function ( value ) {\n\t\t// this.config.value = value;\n\t\tthis.input.val( value );\n\t};\n\n\tVisualDataIntlTelInput.prototype.fixConfigCountries = function ( config ) {\n\t\t// excludeCountries, initialCountry, onlyCountries, preferredCountries\n\t\tvar configCountries = [\n\t\t\t'excludeCountries',\n\t\t\t'initialCountry',\n\t\t\t'onlyCountries',\n\t\t\t'preferredCountries'\n\t\t];\n\n\t\tif (\n\t\t\t!Object.keys( config ).filter( ( x ) => configCountries.includes( x ) )\n\t\t\t\t.length\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// first get all countries to handle the error\n\t\t// \"No country data for ... \"\n\t\t// eslint-disable-next-line new-cap\n\t\tvar iso2 = new window.intlTelInput( this.input.get( 0 ) ).countries.map(\n\t\t\t( x ) => x.iso2\n\t\t);\n\n\t\tfor ( var i of configCountries ) {\n\t\t\tif ( i in config ) {\n\t\t\t\tif ( i === 'initialCountry' ) {\n\t\t\t\t\tconfig[ i ] = config[ i ].toLowerCase();\n\t\t\t\t\tif ( !iso2.includes( config[ i ] ) ) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.error( config[ i ] + ' is not a valid country code' );\n\t\t\t\t\t\tdelete config[ i ];\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar values = [];\n\t\t\t\tfor ( var ii of config[ i ] ) {\n\t\t\t\t\tif ( !iso2.includes( ii ) ) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.error( ii + ' is not a valid country code' );\n\t\t\t\t\t\tvalues.splice( ii, 1 );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconfig[ i ] = values;\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":"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/slick/main.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":24,"column":3,"nodeType":"CallExpression","endLine":24,"endColumn":23},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":25,"column":4,"nodeType":"CallExpression","endLine":25,"endColumn":37},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":45,"column":3,"nodeType":"CallExpression","endLine":45,"endColumn":36},{"ruleId":"no-jquery/no-global-selector","severity":1,"message":"Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible.","line":64,"column":2,"nodeType":"CallExpression","endLine":64,"endColumn":22}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * This file is part of the MediaWiki extension VisualData.\n *\n * VisualData 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 * VisualData 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 VisualData. If not, see <http://www.gnu.org/licenses/>.\n *\n * @file\n * @author thomas-topway-it <support@topway.it>\n * @copyright Copyright © 2024, https://wikisphere.org\n */\n\n( function () {\n\t$( window ).on( 'resize', function () {\n\t\t$( '.slick-slider' ).each( function () {\n\t\t\t$( '.slick-slider .slick-slide' ).each( function () {\n\t\t\t\tif ( $( window ).width() < 800 && !$( '.slick-slide-content.caption-title', $( this ) ).length ) {\n\t\t\t\t\t$( '.slick-slide-content.caption', $( this ) ).hide();\n\t\t\t\t} else {\n\t\t\t\t\t$( '.slick-slide-content.caption', $( this ) ).show();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t} );\n\n\tfunction init( $slide ) {\n\t\t// show pictures again\n\t\t$( $slide ).find( '.slick-slide-content' ).show();\n\n\t\t$slide.slick( $slide.data().slick );\n\n\t\tif ( $slide.data().slick.adaptiveHeight ) {\n\t\t\t$slide.addClass( 'adaptiveHeight' );\n\t\t}\n\n\t\t$( '.slick-slider .slick-slide' ).each( function () {\n\t\t\t// hide caption frame if title is empty\n\t\t\t// and screen < 800px\n\t\t\tif ( $( window ).width() < 800 && !$( '.slick-slide-content.caption-title', $( this ) ).length ) {\n\t\t\t\t$( '.slick-slide-content.caption', $( this ) ).hide();\n\t\t\t} else {\n\t\t\t\t$( '.slick-slide-content.caption', $( this ) ).show();\n\t\t\t}\n\n\t\t\tif ( $( this ).attr( 'data-url' ) ) {\n\t\t\t\t// $(this).attr('title', $(this).attr('data-title') )\n\t\t\t\t$( this ).css( 'cursor', 'pointer' );\n\t\t\t\t$( this ).on( 'click', function () {\n\t\t\t\t\twindow.location = $( this ).attr( 'data-url' );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n\n\t$( '.slick-slider' ).each( function () {\n\t\tinit( $( this ) );\n\t} );\n\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":"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
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
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
Disabling eslint rule 'no-throw-literal' (broken in .eslintrc.json) on .eslintrc.json
Disabling eslint rule 'no-throw-literal' (broken in .eslintrc.json) on .eslintrc.json
Disabling eslint rule 'no-throw-literal' (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/VersionCheck.js
  31:3   warning  Prefer .then to .done                                                               no-jquery/no-done-fail
  57:22  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  62:18  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  65:9   warning  Where possible, maintain application state in JS to avoid slower DOM queries        no-jquery/no-class-state

/src/repo/resources/VisualData.js
  56:4  warning  Prefer .then to .done  no-jquery/no-done-fail
  56:4  warning  Prefer .then to .fail  no-jquery/no-done-fail
  92:4  warning  Prefer .then to .done  no-jquery/no-done-fail
  92:4  warning  Prefer .then to .fail  no-jquery/no-done-fail

/src/repo/resources/VisualDataCalendar.js
  134:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataDatatables.js
    27:6  warning  jQuery collection names must match the variablePattern                              no-jquery/variable-pattern
    43:1  warning  This line has a length of 144. Maximum allowed is 100                               max-len
    59:1  warning  This line has a length of 111. Maximum allowed is 100                               max-len
   140:1  warning  This line has a length of 101. Maximum allowed is 100                               max-len
   173:3  warning  Prefer .then to .done                                                               no-jquery/no-done-fail
   173:3  warning  Prefer .then to .fail                                                               no-jquery/no-done-fail
   242:1  warning  This line has a length of 112. Maximum allowed is 100                               max-len
   279:3  warning  Prefer .then to .done                                                               no-jquery/no-done-fail
   279:3  warning  Prefer .then to .fail                                                               no-jquery/no-done-fail
   358:5  warning  Prefer Array#indexOf to $.inArray                                                   no-jquery/no-in-array
   491:1  warning  This line has a length of 111. Maximum allowed is 100                               max-len
   640:8  warning  Prefer Array#indexOf to $.inArray                                                   no-jquery/no-in-array
   681:1  warning  This line has a length of 119. Maximum allowed is 100                               max-len
   686:8  warning  Expected a 'break' statement before 'case'                                          no-fallthrough
   690:8  warning  Expected a 'break' statement before 'case'                                          no-fallthrough
   692:8  warning  Expected a 'break' statement before 'case'                                          no-fallthrough
   757:1  warning  This line has a length of 143. Maximum allowed is 100                               max-len
  1076:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  1093:3  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataFormField.js
   284:1  warning  This line has a length of 108. Maximum allowed is 100                               max-len
   300:1  warning  This line has a length of 135. Maximum allowed is 100                               max-len
  1042:4  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataForms.js
    26:1   warning  This line has a length of 101. Maximum allowed is 100                               max-len
    79:6   warning  Selector extensions are not allowed                                                 no-jquery/no-sizzle
   213:5   warning  Selector extensions are not allowed                                                 no-jquery/no-sizzle
   513:1   warning  This line has a length of 117. Maximum allowed is 100                               max-len
   530:1   warning  This line has a length of 125. Maximum allowed is 100                               max-len
   577:5   warning  Prefer .then to .done                                                               no-jquery/no-done-fail
   577:5   warning  Prefer .then to .fail                                                               no-jquery/no-done-fail
   878:5   warning  Prefer .then to .done                                                               no-jquery/no-done-fail
   878:5   warning  Prefer .then to .fail                                                               no-jquery/no-done-fail
   969:5   warning  Prefer .then to .fail                                                               no-jquery/no-done-fail
  1007:8   warning  jQuery collection names must match the variablePattern                              no-jquery/variable-pattern
  1007:17  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  1456:4   warning  jQuery collection names must match the variablePattern                              no-jquery/variable-pattern
  1458:26  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  2185:5   warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  2333:1   warning  This line has a length of 117. Maximum allowed is 100                               max-len
  2370:1   warning  This line has a length of 127. Maximum allowed is 100                               max-len
  2582:1   warning  This line has a length of 109. Maximum allowed is 100                               max-len
  2916:1   warning  This line has a length of 102. Maximum allowed is 100                               max-len
  2934:7   warning  jQuery collection names must match the variablePattern                              no-jquery/variable-pattern
  3102:9   warning  Prefer .then to .done                                                               no-jquery/no-done-fail
  3102:9   warning  Prefer .then to .fail                                                               no-jquery/no-done-fail
  3107:1   warning  This line has a length of 102. Maximum allowed is 100                               max-len
  3231:10  warning  Selector extensions are not allowed                                                 no-jquery/no-sizzle
  3381:1   warning  This line has a length of 108. Maximum allowed is 100                               max-len
  3386:1   warning  This line has a length of 105. Maximum allowed is 100                               max-len
  3601:15  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  3625:1   warning  This line has a length of 119. Maximum allowed is 100                               max-len
  3672:3   warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  3716:3   warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataInputConfig.js
  840:1  warning  This line has a length of 110. Maximum allowed is 100  max-len

/src/repo/resources/VisualDataMaps.js
   35:1  warning  This line has a length of 108. Maximum allowed is 100                               max-len
  119:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataPrintouts.js
  43:1  warning  This line has a length of 107. Maximum allowed is 100                               max-len
  56:1  warning  This line has a length of 144. Maximum allowed is 100                               max-len
  71:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  75:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataProcessModel.js
  222:1   warning  This line has a length of 116. Maximum allowed is 100  max-len
  226:11  warning  Selector extensions are not allowed                    no-jquery/no-sizzle

/src/repo/resources/VisualDataSchemas.js
   325:1   warning  This line has a length of 103. Maximum allowed is 100                               max-len
   640:8   warning  Prefer .then to .done                                                               no-jquery/no-done-fail
   640:8   warning  Prefer .then to .fail                                                               no-jquery/no-done-fail
  1608:15  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  1785:4   warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  1788:15  warning  Prefer DOM building to parsing HTML literals                                        no-jquery/no-parse-html-literal
  1804:4   warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

/src/repo/resources/VisualDataUpload.js
  128:3  warning  Prefer .then to .fail  no-jquery/no-done-fail
  280:3  warning  Prefer .then to .done  no-jquery/no-done-fail
  280:3  warning  Prefer .then to .fail  no-jquery/no-done-fail
  369:3  warning  Prefer .then to .done  no-jquery/no-done-fail
  369:3  warning  Prefer .then to .fail  no-jquery/no-done-fail

/src/repo/resources/Widgets/VisualDataButtonMultiselectWidget.js
  48:12  warning  Prefer Array#indexOf to $.inArray  no-jquery/no-in-array

/src/repo/resources/Widgets/VisualDataDateTimeInputWidget.js
  66:1  warning  This line has a length of 105. Maximum allowed is 100  max-len

/src/repo/resources/Widgets/VisualDataDropdownWidget.js
  38:7  warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  53:7  warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern

/src/repo/resources/Widgets/VisualDataMaptiler.js
  41:9  warning  Selector extensions are not allowed                    no-jquery/no-sizzle
  43:4  warning  Expected an error object to be thrown                  no-throw-literal
  66:1  warning  This line has a length of 102. Maximum allowed is 100  max-len
  68:1  warning  This line has a length of 123. Maximum allowed is 100  max-len

/src/repo/resources/Widgets/VisualDataMenuTagSearchMultiselect.js
  29:1  warning  Invalid JSDoc tag name "mixins"                        jsdoc/check-tag-names
  49:1  warning  This line has a length of 110. Maximum allowed is 100  max-len
  50:1  warning  This line has a length of 107. Maximum allowed is 100  max-len

/src/repo/resources/Widgets/VisualDataRatingWidget.js
  38:19  warning  Prefer DOM building to parsing HTML literals            no-jquery/no-parse-html-literal
  45:8   warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  67:6   warning  Selector extensions are not allowed                     no-jquery/no-sizzle

/src/repo/resources/Widgets/VisualDataTinyMCE.js
  39:3   warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  39:19  warning  Prefer DOM building to parsing HTML literals            no-jquery/no-parse-html-literal
  66:9   warning  Selector extensions are not allowed                     no-jquery/no-sizzle
  68:4   warning  Expected an error object to be thrown                   no-throw-literal

/src/repo/resources/Widgets/VisualDataVisualEditor.js
  40:3   warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  40:19  warning  Prefer DOM building to parsing HTML literals            no-jquery/no-parse-html-literal
  47:3   warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern
  69:9   warning  Selector extensions are not allowed                     no-jquery/no-sizzle
  70:4   warning  Expected an error object to be thrown                   no-throw-literal

/src/repo/resources/Widgets/VisualDataintlTelInput.js
  38:7  warning  jQuery collection names must match the variablePattern  no-jquery/variable-pattern

/src/repo/resources/slick/main.js
  24:3  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  25:4  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  45:3  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector
  64:2  warning  Avoid queries which search the entire DOM. Keep DOM nodes in memory where possible  no-jquery/no-global-selector

✖ 110 problems (0 errors, 110 warnings)


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

Running "banana:VisualData" (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: {'Squiz.Scope.MethodScope.Missing', 'Generic.Files.LineLength.TooLong', 'MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals', 'Generic.Files.OneObjectStructurePerFile.MultipleFound', 'MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName', 'MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic'}
$ vendor/bin/phpcs --report=json
--- stdout ---
{"totals":{"errors":54,"warnings":90,"fixable":0},"files":{"\/src\/repo\/VisualData.alias.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/VisualDataMagic.i18n.magic.php":{"errors":0,"warnings":0,"messages":[]},"\/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\/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\/BrowseData\/BrowseData.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/BrowseData\/BrowseForms.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/Scribunto\/LuaLibrary.php":{"errors":1,"warnings":0,"messages":[{"message":"You must use \"\/**\" style comments for a class comment, or add an empty line after stray comments","source":"MediaWiki.Commenting.CommentBeforeClass.StrayStyle","severity":5,"fixable":false,"type":"ERROR","line":35,"column":1}]},"\/src\/repo\/includes\/specials\/BrowseData\/BrowseSchemas.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiQueryResults.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":19,"column":4},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":65,"column":12}]},"\/src\/repo\/includes\/api\/VisualDataApiLoadData.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiCheckLatestVersion.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\/classes\/formats\/PagetitleResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":29,"column":12}]},"\/src\/repo\/maintenance\/ImportData.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/PageForms\/PFArrayMapTemplate.php":{"errors":2,"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","source":"MediaWiki.Commenting.CommentBeforeClass.SpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":10,"column":1},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":30,"column":19}]},"\/src\/repo\/includes\/specials\/SpecialManageSchemas.php":{"errors":0,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 135 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":95,"column":135}]},"\/src\/repo\/includes\/classes\/formats\/PageidResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":29,"column":12}]},"\/src\/repo\/includes\/specials\/SpecialVisualDataSubmit.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiQueryOptions.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiSubmitForm.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiGetSchemas.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\/pagers\/SchemasPager.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/BrowseData\/BrowseQueries.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/maintenance\/DeleteRegex.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/content\/VisualDataHtmlContent.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/JsonResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":31,"column":12}]},"\/src\/repo\/includes\/content\/VisualDataJsonDataContentHandler.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/content\/VisualDataJsonDataContent.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/JsonRawResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":40,"column":12}]},"\/src\/repo\/includes\/classes\/formats\/TemplateResultPrinter.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/pagers\/DataPager.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/VisualDataEditAction.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\/classes\/formats\/QueryResultPrinter.php":{"errors":0,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":63,"column":121}]},"\/src\/repo\/includes\/content\/VisualDataHtmlContentHandler.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/CountResultPrinter.php":{"errors":1,"warnings":1,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":42,"column":12},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":56,"column":129}]},"\/src\/repo\/includes\/classes\/PublishStashedFile.php":{"errors":3,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":41,"column":12},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":46,"column":12},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":170,"column":12}]},"\/src\/repo\/includes\/specials\/SpecialEditData.php":{"errors":2,"warnings":1,"messages":[{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":114,"column":22},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":116,"column":61},{"message":"Line exceeds 120 characters; contains 135 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":187,"column":135}]},"\/src\/repo\/includes\/classes\/UpdateDataJob.php":{"errors":2,"warnings":4,"messages":[{"message":"Visibility must be declared on method \"__construct\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":41,"column":5},{"message":"Visibility must be declared on method \"run\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":48,"column":5},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":116,"column":125},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":137,"column":125},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":149,"column":126},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":172,"column":128}]},"\/src\/repo\/includes\/specials\/pagers\/FormsPager.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiSaveSchema.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/aliases\/Html.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\/maintenance\/Uninstall.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/utils\/DateParser.php":{"errors":3,"warnings":0,"messages":[{"message":"Method name \"DateTimeImmutable\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":90,"column":12},{"message":"Method name \"date_parse\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":129,"column":12},{"message":"Method name \"IntlDateFormatter\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":152,"column":12}]},"\/src\/repo\/maintenance\/ProcessData.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/Importer.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/maintenance\/ReplaceText\/Search.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/pagers\/QueriesPager.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/utils\/HtmlTable.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/SpecialVisualDataBrowse.php":{"errors":0,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":151,"column":122}]},"\/src\/repo\/includes\/utils\/SafeJsonEncoder.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/TableResultPrinter.php":{"errors":0,"warnings":5,"messages":[{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":98,"column":121},{"message":"Line exceeds 120 characters; contains 132 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":120,"column":132},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":170,"column":121},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":171,"column":125},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":318,"column":129}]},"\/src\/repo\/includes\/classes\/formats\/Base64ResultPrinter.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/CarouselResultPrinter.php":{"errors":1,"warnings":3,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":339,"column":12},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":391,"column":121},{"message":"Line exceeds 120 characters; contains 138 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":469,"column":138},{"message":"Line exceeds 120 characters; contains 143 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":470,"column":143}]},"\/src\/repo\/maintenance\/RebuildData.php":{"errors":0,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 127 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":419,"column":127}]},"\/src\/repo\/includes\/classes\/formats\/DatatableResultPrinter.php":{"errors":0,"warnings":4,"messages":[{"message":"Line exceeds 120 characters; contains 140 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":412,"column":140},{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":487,"column":122},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":507,"column":128},{"message":"Line exceeds 120 characters; contains 132 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":585,"column":132}]},"\/src\/repo\/includes\/classes\/formats\/LuaResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":33,"column":12}]},"\/src\/repo\/includes\/importer\/VisualDataImporter1_35.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/MapResultPrinter.php":{"errors":1,"warnings":3,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":581,"column":12},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":640,"column":121},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":674,"column":121},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":675,"column":125}]},"\/src\/repo\/includes\/classes\/MimeTypes.php":{"errors":0,"warnings":8,"messages":[{"message":"Line exceeds 120 characters; contains 146 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":77,"column":146},{"message":"Line exceeds 120 characters; contains 147 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":122,"column":147},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":379,"column":133},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":456,"column":133},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":457,"column":121},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":643,"column":133},{"message":"Line exceeds 120 characters; contains 145 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":726,"column":145},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":802,"column":121}]},"\/src\/repo\/includes\/VisualDataHooks.php":{"errors":10,"warnings":8,"messages":[{"message":"Line exceeds 120 characters; contains 130 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":81,"column":130},{"message":"Line exceeds 120 characters; contains 135 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":121,"column":135},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":125,"column":24},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":127,"column":21},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":145,"column":22},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":146,"column":21},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":173,"column":24},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":175,"column":21},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":185,"column":126},{"message":"Line exceeds 120 characters; contains 134 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":227,"column":134},{"message":"Line exceeds 120 characters; contains 177 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":388,"column":177},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":502,"column":81},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":503,"column":31},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":619,"column":129},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":627,"column":43},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":627,"column":61},{"message":"Line exceeds 120 characters; contains 167 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":633,"column":167},{"message":"Line exceeds 120 characters; contains 147 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":640,"column":147}]},"\/src\/repo\/includes\/classes\/SubmitForm.php":{"errors":0,"warnings":11,"messages":[{"message":"Line exceeds 120 characters; contains 140 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":84,"column":140},{"message":"Line exceeds 120 characters; contains 156 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":112,"column":156},{"message":"Line exceeds 120 characters; contains 137 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":168,"column":137},{"message":"Line exceeds 120 characters; contains 124 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":244,"column":124},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":438,"column":17},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":479,"column":133},{"message":"Line exceeds 120 characters; contains 124 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":483,"column":124},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":503,"column":128},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":533,"column":128},{"message":"Line exceeds 120 characters; contains 131 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":545,"column":131},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":623,"column":129}]},"\/src\/repo\/includes\/importer\/VisualDataImporter.php":{"errors":1,"warnings":0,"messages":[{"message":"You must use \"\/**\" style comments for a class comment, or add an empty line after stray comments","source":"MediaWiki.Commenting.CommentBeforeClass.StrayStyle","severity":5,"fixable":false,"type":"ERROR","line":38,"column":1}]},"\/src\/repo\/includes\/classes\/DatabaseManager.php":{"errors":0,"warnings":3,"messages":[{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":759,"column":122},{"message":"Line exceeds 120 characters; contains 123 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1034,"column":123},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1050,"column":126}]},"\/src\/repo\/includes\/importer\/VisualDataImporter1_42.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/CalendarResultPrinter.php":{"errors":1,"warnings":2,"messages":[{"message":"Line exceeds 120 characters; contains 232 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":769,"column":9},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":875,"column":12},{"message":"Line exceeds 120 characters; contains 124 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":933,"column":9}]},"\/src\/repo\/includes\/classes\/QueryProcessor.php":{"errors":0,"warnings":7,"messages":[{"message":"Line exceeds 120 characters; contains 141 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":824,"column":141},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1064,"column":125},{"message":"Line exceeds 120 characters; contains 143 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1091,"column":143},{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1373,"column":13},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1493,"column":121},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1651,"column":129},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1689,"column":128}]},"\/src\/repo\/includes\/classes\/ResultPrinter.php":{"errors":0,"warnings":6,"messages":[{"message":"Line exceeds 120 characters; contains 143 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":137,"column":143},{"message":"Line exceeds 120 characters; contains 132 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":361,"column":132},{"message":"Line exceeds 120 characters; contains 137 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":380,"column":137},{"message":"Line exceeds 120 characters; contains 175 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":420,"column":175},{"message":"Line exceeds 120 characters; contains 150 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":495,"column":150},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":593,"column":121}]},"\/src\/repo\/includes\/classes\/PageForms\/PFArrayMap.php":{"errors":2,"warnings":1,"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","source":"MediaWiki.Commenting.CommentBeforeClass.SpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":10,"column":1},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":28,"column":19},{"message":"Line exceeds 120 characters; contains 124 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":59,"column":124}]},"\/src\/repo\/includes\/classes\/SchemaProcessor.php":{"errors":5,"warnings":9,"messages":[{"message":"Visibility must be declared on method \"handleSchemaTo\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":581,"column":5},{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":754,"column":122},{"message":"Line exceeds 120 characters; contains 142 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":755,"column":142},{"message":"Line exceeds 120 characters; contains 160 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":760,"column":160},{"message":"Line exceeds 120 characters; contains 164 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":761,"column":164},{"message":"Line exceeds 120 characters; contains 162 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":768,"column":162},{"message":"Line exceeds 120 characters; contains 166 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":769,"column":166},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":872,"column":128},{"message":"Visibility must be declared on method \"handleSchemaFrom\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":964,"column":5},{"message":"Visibility must be declared on method \"handleOptionsFrom\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":1131,"column":5},{"message":"Visibility must be declared on method \"isValidObj\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":1160,"column":5},{"message":"Method name \"SMWQueryResults\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":1298,"column":19},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1298,"column":126},{"message":"Line exceeds 120 characters; contains 130 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1430,"column":130}]},"\/src\/repo\/includes\/VisualData.php":{"errors":4,"warnings":9,"messages":[{"message":"Line exceeds 120 characters; contains 145 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1437,"column":145},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1982,"column":121},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2183,"column":21},{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2302,"column":122},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2333,"column":121},{"message":"Line exceeds 120 characters; contains 131 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2339,"column":131},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2492,"column":121},{"message":"Method name \"VEenabledForUser\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":2535,"column":20},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2539,"column":125},{"message":"Method name \"page_ancestors\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":3001,"column":19},{"message":"Method name \"array_filter_recursive\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":3328,"column":19},{"message":"Method name \"array_merge_recursive\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":3366,"column":19},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":3401,"column":13}]},"\/src\/repo\/includes\/api\/VisualDataApiDatatables.php":{"errors":2,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 134 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":127,"column":134},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":158,"column":9},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":233,"column":9}]}}}

--- end ---
PHPCS run failed
$ vendor/bin/phpcs --report=json
--- stdout ---
{"totals":{"errors":54,"warnings":90,"fixable":0},"files":{"\/src\/repo\/VisualData.alias.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/VisualDataMagic.i18n.magic.php":{"errors":0,"warnings":0,"messages":[]},"\/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\/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\/BrowseData\/BrowseForms.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/BrowseData\/BrowseData.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/BrowseData\/BrowseSchemas.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiLoadData.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiQueryResults.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":19,"column":4},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":65,"column":12}]},"\/src\/repo\/includes\/classes\/formats\/PagetitleResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":29,"column":12}]},"\/src\/repo\/includes\/api\/VisualDataApiCheckLatestVersion.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\/maintenance\/ImportData.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/PageForms\/PFArrayMapTemplate.php":{"errors":2,"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","source":"MediaWiki.Commenting.CommentBeforeClass.SpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":10,"column":1},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":30,"column":19}]},"\/src\/repo\/includes\/specials\/SpecialManageSchemas.php":{"errors":0,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 135 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":95,"column":135}]},"\/src\/repo\/includes\/classes\/formats\/JsonResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":31,"column":12}]},"\/src\/repo\/includes\/classes\/Scribunto\/LuaLibrary.php":{"errors":1,"warnings":0,"messages":[{"message":"You must use \"\/**\" style comments for a class comment, or add an empty line after stray comments","source":"MediaWiki.Commenting.CommentBeforeClass.StrayStyle","severity":5,"fixable":false,"type":"ERROR","line":35,"column":1}]},"\/src\/repo\/includes\/api\/VisualDataApiGetSchemas.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\/VisualDataApiSubmitForm.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiQueryOptions.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/PageidResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":29,"column":12}]},"\/src\/repo\/maintenance\/DeleteRegex.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/SpecialVisualDataSubmit.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/pagers\/SchemasPager.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/BrowseData\/BrowseQueries.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/TemplateResultPrinter.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/content\/VisualDataHtmlContent.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/JsonRawResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":40,"column":12}]},"\/src\/repo\/includes\/classes\/formats\/QueryResultPrinter.php":{"errors":0,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":63,"column":121}]},"\/src\/repo\/includes\/content\/VisualDataJsonDataContentHandler.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/content\/VisualDataJsonDataContent.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/VisualDataEditAction.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\/pagers\/DataPager.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/content\/VisualDataHtmlContentHandler.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/SpecialEditData.php":{"errors":2,"warnings":1,"messages":[{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":114,"column":22},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":116,"column":61},{"message":"Line exceeds 120 characters; contains 135 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":187,"column":135}]},"\/src\/repo\/includes\/classes\/formats\/CountResultPrinter.php":{"errors":1,"warnings":1,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":42,"column":12},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":56,"column":129}]},"\/src\/repo\/includes\/classes\/PublishStashedFile.php":{"errors":3,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":41,"column":12},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":46,"column":12},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":170,"column":12}]},"\/src\/repo\/maintenance\/Uninstall.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/pagers\/FormsPager.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/api\/VisualDataApiSaveSchema.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/aliases\/Html.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\/maintenance\/ReplaceText\/Search.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/utils\/DateParser.php":{"errors":3,"warnings":0,"messages":[{"message":"Method name \"DateTimeImmutable\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":90,"column":12},{"message":"Method name \"date_parse\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":129,"column":12},{"message":"Method name \"IntlDateFormatter\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":152,"column":12}]},"\/src\/repo\/maintenance\/ProcessData.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/UpdateDataJob.php":{"errors":2,"warnings":4,"messages":[{"message":"Visibility must be declared on method \"__construct\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":41,"column":5},{"message":"Visibility must be declared on method \"run\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":48,"column":5},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":116,"column":125},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":137,"column":125},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":149,"column":126},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":172,"column":128}]},"\/src\/repo\/includes\/classes\/Importer.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/pagers\/QueriesPager.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/utils\/HtmlTable.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/specials\/SpecialVisualDataBrowse.php":{"errors":0,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":151,"column":122}]},"\/src\/repo\/includes\/utils\/SafeJsonEncoder.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/maintenance\/RebuildData.php":{"errors":0,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 127 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":419,"column":127}]},"\/src\/repo\/includes\/classes\/formats\/MapResultPrinter.php":{"errors":1,"warnings":3,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":581,"column":12},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":640,"column":121},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":674,"column":121},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":675,"column":125}]},"\/src\/repo\/includes\/importer\/VisualDataImporter1_35.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/CarouselResultPrinter.php":{"errors":1,"warnings":3,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":339,"column":12},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":391,"column":121},{"message":"Line exceeds 120 characters; contains 138 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":469,"column":138},{"message":"Line exceeds 120 characters; contains 143 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":470,"column":143}]},"\/src\/repo\/includes\/classes\/formats\/TableResultPrinter.php":{"errors":0,"warnings":5,"messages":[{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":98,"column":121},{"message":"Line exceeds 120 characters; contains 132 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":120,"column":132},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":170,"column":121},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":171,"column":125},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":318,"column":129}]},"\/src\/repo\/includes\/classes\/formats\/Base64ResultPrinter.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/formats\/LuaResultPrinter.php":{"errors":1,"warnings":0,"messages":[{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":33,"column":12}]},"\/src\/repo\/includes\/classes\/formats\/DatatableResultPrinter.php":{"errors":0,"warnings":4,"messages":[{"message":"Line exceeds 120 characters; contains 140 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":412,"column":140},{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":487,"column":122},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":507,"column":128},{"message":"Line exceeds 120 characters; contains 132 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":585,"column":132}]},"\/src\/repo\/includes\/classes\/MimeTypes.php":{"errors":0,"warnings":8,"messages":[{"message":"Line exceeds 120 characters; contains 146 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":77,"column":146},{"message":"Line exceeds 120 characters; contains 147 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":122,"column":147},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":379,"column":133},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":456,"column":133},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":457,"column":121},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":643,"column":133},{"message":"Line exceeds 120 characters; contains 145 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":726,"column":145},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":802,"column":121}]},"\/src\/repo\/includes\/VisualDataHooks.php":{"errors":10,"warnings":8,"messages":[{"message":"Line exceeds 120 characters; contains 130 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":81,"column":130},{"message":"Line exceeds 120 characters; contains 135 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":121,"column":135},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":125,"column":24},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":127,"column":21},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":145,"column":22},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":146,"column":21},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":173,"column":24},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":175,"column":21},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":185,"column":126},{"message":"Line exceeds 120 characters; contains 134 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":227,"column":134},{"message":"Line exceeds 120 characters; contains 177 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":388,"column":177},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":502,"column":81},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":503,"column":31},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":619,"column":129},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":627,"column":43},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":627,"column":61},{"message":"Line exceeds 120 characters; contains 167 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":633,"column":167},{"message":"Line exceeds 120 characters; contains 147 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":640,"column":147}]},"\/src\/repo\/includes\/importer\/VisualDataImporter.php":{"errors":1,"warnings":0,"messages":[{"message":"You must use \"\/**\" style comments for a class comment, or add an empty line after stray comments","source":"MediaWiki.Commenting.CommentBeforeClass.StrayStyle","severity":5,"fixable":false,"type":"ERROR","line":38,"column":1}]},"\/src\/repo\/includes\/classes\/SubmitForm.php":{"errors":0,"warnings":11,"messages":[{"message":"Line exceeds 120 characters; contains 140 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":84,"column":140},{"message":"Line exceeds 120 characters; contains 156 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":112,"column":156},{"message":"Line exceeds 120 characters; contains 137 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":168,"column":137},{"message":"Line exceeds 120 characters; contains 124 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":244,"column":124},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":438,"column":17},{"message":"Line exceeds 120 characters; contains 133 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":479,"column":133},{"message":"Line exceeds 120 characters; contains 124 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":483,"column":124},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":503,"column":128},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":533,"column":128},{"message":"Line exceeds 120 characters; contains 131 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":545,"column":131},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":623,"column":129}]},"\/src\/repo\/includes\/classes\/DatabaseManager.php":{"errors":0,"warnings":3,"messages":[{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":759,"column":122},{"message":"Line exceeds 120 characters; contains 123 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1034,"column":123},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1050,"column":126}]},"\/src\/repo\/includes\/classes\/formats\/CalendarResultPrinter.php":{"errors":1,"warnings":2,"messages":[{"message":"Line exceeds 120 characters; contains 232 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":769,"column":9},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":875,"column":12},{"message":"Line exceeds 120 characters; contains 124 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":933,"column":9}]},"\/src\/repo\/includes\/importer\/VisualDataImporter1_42.php":{"errors":0,"warnings":0,"messages":[]},"\/src\/repo\/includes\/classes\/QueryProcessor.php":{"errors":0,"warnings":7,"messages":[{"message":"Line exceeds 120 characters; contains 141 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":824,"column":141},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1064,"column":125},{"message":"Line exceeds 120 characters; contains 143 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1091,"column":143},{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1373,"column":13},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1493,"column":121},{"message":"Line exceeds 120 characters; contains 129 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1651,"column":129},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1689,"column":128}]},"\/src\/repo\/includes\/classes\/PageForms\/PFArrayMap.php":{"errors":2,"warnings":1,"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","source":"MediaWiki.Commenting.CommentBeforeClass.SpacingAfter","severity":5,"fixable":false,"type":"ERROR","line":10,"column":1},{"message":"Missing function doc comment","source":"MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic","severity":5,"fixable":false,"type":"ERROR","line":28,"column":19},{"message":"Line exceeds 120 characters; contains 124 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":59,"column":124}]},"\/src\/repo\/includes\/classes\/ResultPrinter.php":{"errors":0,"warnings":6,"messages":[{"message":"Line exceeds 120 characters; contains 143 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":137,"column":143},{"message":"Line exceeds 120 characters; contains 132 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":361,"column":132},{"message":"Line exceeds 120 characters; contains 137 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":380,"column":137},{"message":"Line exceeds 120 characters; contains 175 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":420,"column":175},{"message":"Line exceeds 120 characters; contains 150 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":495,"column":150},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":593,"column":121}]},"\/src\/repo\/includes\/classes\/SchemaProcessor.php":{"errors":5,"warnings":9,"messages":[{"message":"Visibility must be declared on method \"handleSchemaTo\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":581,"column":5},{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":754,"column":122},{"message":"Line exceeds 120 characters; contains 142 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":755,"column":142},{"message":"Line exceeds 120 characters; contains 160 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":760,"column":160},{"message":"Line exceeds 120 characters; contains 164 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":761,"column":164},{"message":"Line exceeds 120 characters; contains 162 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":768,"column":162},{"message":"Line exceeds 120 characters; contains 166 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":769,"column":166},{"message":"Line exceeds 120 characters; contains 128 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":872,"column":128},{"message":"Visibility must be declared on method \"handleSchemaFrom\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":964,"column":5},{"message":"Visibility must be declared on method \"handleOptionsFrom\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":1131,"column":5},{"message":"Visibility must be declared on method \"isValidObj\"","source":"Squiz.Scope.MethodScope.Missing","severity":5,"fixable":false,"type":"ERROR","line":1160,"column":5},{"message":"Method name \"SMWQueryResults\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":1298,"column":19},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1298,"column":126},{"message":"Line exceeds 120 characters; contains 130 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1430,"column":130}]},"\/src\/repo\/includes\/VisualData.php":{"errors":4,"warnings":9,"messages":[{"message":"Line exceeds 120 characters; contains 145 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1437,"column":145},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":1982,"column":121},{"message":"Line exceeds 120 characters; contains 126 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2183,"column":21},{"message":"Line exceeds 120 characters; contains 122 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2302,"column":122},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2333,"column":121},{"message":"Line exceeds 120 characters; contains 131 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2339,"column":131},{"message":"Line exceeds 120 characters; contains 121 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2492,"column":121},{"message":"Method name \"VEenabledForUser\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":2535,"column":20},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":2539,"column":125},{"message":"Method name \"page_ancestors\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":3001,"column":19},{"message":"Method name \"array_filter_recursive\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":3328,"column":19},{"message":"Method name \"array_merge_recursive\" should use lower camel case.","source":"MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName","severity":5,"fixable":false,"type":"ERROR","line":3366,"column":19},{"message":"Line exceeds 120 characters; contains 125 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":3401,"column":13}]},"\/src\/repo\/includes\/api\/VisualDataApiDatatables.php":{"errors":2,"warnings":1,"messages":[{"message":"Line exceeds 120 characters; contains 134 characters","source":"Generic.Files.LineLength.TooLong","severity":5,"fixable":false,"type":"WARNING","line":127,"column":134},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":158,"column":9},{"message":"\"$_GET\" superglobals should not be accessed.","source":"MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals","severity":5,"fixable":false,"type":"ERROR","line":233,"column":9}]}}}

--- end ---
 * sniff MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation is now failing
 * sniff MediaWiki.Commenting.CommentBeforeClass.SpacingAfter is now failing
 * sniff MediaWiki.Commenting.CommentBeforeClass.StrayStyle 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
> minus-x check .
> phpcs -sp --cache
--- stdout ---
PHP 8.4.11 | 10 parallel jobs
............................................................ 60/70 ( 85%)
..........                                                   70/70 (100%)


Checked 70 files in 0.3 seconds
No syntax error found
MinusX
======
Processing /src/repo...
.............................................................
.............................................................
.............................................................
.............................................................
.............................................................
.........................
All good!
................................... 35 / 35 (100%)


Time: 282ms; Memory: 12MB


--- 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.SpacingAfter
  * MediaWiki.Commenting.CommentBeforeClass.StrayStyle


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


$ git add .
--- stdout ---

--- end ---
$ git commit -F /tmp/tmp87b9wsto
--- stdout ---
[master 1612e27] build: Updating dependencies
 20 files changed, 715 insertions(+), 144 deletions(-)

--- end ---
$ git format-patch HEAD~1 --stdout
--- stdout ---
From 1612e27fdbd990147c2675f93ce82f06b2591781 Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Tue, 7 Oct 2025 05:07:57 +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.SpacingAfter
  * MediaWiki.Commenting.CommentBeforeClass.StrayStyle

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

Change-Id: Ibf7edd2fa94f012c0f8085b9de34f4723c25ea61
---
 .eslintrc.json                                |   4 +-
 .phpcs.xml                                    |   3 +
 composer.json                                 |   2 +-
 package-lock.json                             | 762 +++++++++++++++---
 package.json                                  |   2 +-
 resources/VisualDataCalendar.js               |   2 +-
 resources/VisualDataDatatables.js             |   7 +-
 resources/VisualDataFormField.js              |  11 +-
 resources/VisualDataForms.js                  |  16 +-
 resources/VisualDataFunctions.js              |  10 +-
 resources/VisualDataInputConfig.js            |   4 +-
 resources/VisualDataProcessModel.js           |   9 +-
 resources/VisualDataWindowManager.js          |   1 -
 .../Widgets/VisualDataDateTimeInputWidget.js  |   4 +-
 resources/Widgets/VisualDataMaptiler.js       |   4 +-
 .../VisualDataMenuTagSearchMultiselect.js     |   2 +-
 resources/Widgets/VisualDataTinyMCE.js        |   4 +-
 resources/Widgets/VisualDataVisualEditor.js   |   4 +-
 resources/Widgets/VisualDataintlTelInput.js   |   6 +-
 resources/slick/main.js                       |   2 +-
 20 files changed, 715 insertions(+), 144 deletions(-)

diff --git a/.eslintrc.json b/.eslintrc.json
index e1f0c03..f672fa4 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -25,7 +25,9 @@
 		"arrow-body-style": "off",
 		"implicit-arrow-linebreak": "off",
 		"no-jquery/no-extend": "off",
-		"prefer-arrow-callback": "off"
+		"prefer-arrow-callback": "off",
+		"no-jquery/no-done-fail": "warn",
+		"no-throw-literal": "warn"
 	},
 	"parserOptions": {
 		"ecmaVersion": 8
diff --git a/.phpcs.xml b/.phpcs.xml
index f4b54ff..34b0920 100644
--- a/.phpcs.xml
+++ b/.phpcs.xml
@@ -7,6 +7,9 @@
 		<exclude name="MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals" />
 		<exclude name="Squiz.Scope.MethodScope.Missing" />
 		<exclude name="Generic.Files.OneObjectStructurePerFile.MultipleFound" />
+		<exclude name="MediaWiki.Commenting.ClassAnnotations.UnrecognizedAnnotation" />
+		<exclude name="MediaWiki.Commenting.CommentBeforeClass.SpacingAfter" />
+		<exclude name="MediaWiki.Commenting.CommentBeforeClass.StrayStyle" />
 	</rule>
 	<file>.</file>
 	<arg name="extensions" value="php"/>
diff --git a/composer.json b/composer.json
index 754cb28..3575ee5 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 989dc12..0fda9f9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
 		"": {
 			"name": "VisualData",
 			"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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.0.tgz",
+			"integrity": "sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/tsconfig-utils": "^8.46.0",
+				"@typescript-eslint/types": "^8.46.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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.0.tgz",
+			"integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.46.0",
+				"@typescript-eslint/visitor-keys": "8.46.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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.0.tgz",
+			"integrity": "sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==",
+			"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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz",
+			"integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==",
+			"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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.0.tgz",
+			"integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/project-service": "8.46.0",
+				"@typescript-eslint/tsconfig-utils": "8.46.0",
+				"@typescript-eslint/types": "8.46.0",
+				"@typescript-eslint/visitor-keys": "8.46.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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.0.tgz",
+			"integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==",
+			"dev": true,
+			"dependencies": {
+				"@eslint-community/eslint-utils": "^4.7.0",
+				"@typescript-eslint/scope-manager": "8.46.0",
+				"@typescript-eslint/types": "8.46.0",
+				"@typescript-eslint/typescript-estree": "8.46.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.46.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.0.tgz",
+			"integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "8.46.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz",
-			"integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==",
+			"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.8.0",
-				"@typescript-eslint/visitor-keys": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz",
-			"integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==",
+			"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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz",
-			"integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==",
+			"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.8.0",
-				"@typescript-eslint/visitor-keys": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz",
-			"integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==",
+			"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.8.0",
-				"@typescript-eslint/types": "8.8.0",
-				"@typescript-eslint/typescript-estree": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz",
-			"integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==",
+			"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.8.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"
@@ -4578,15 +4941,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": {
@@ -5040,12 +5403,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": {
@@ -5132,6 +5495,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.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.0.tgz",
+					"integrity": "sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/tsconfig-utils": "^8.46.0",
+						"@typescript-eslint/types": "^8.46.0",
+						"debug": "^4.3.4"
+					}
+				},
+				"@typescript-eslint/scope-manager": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.0.tgz",
+					"integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/types": "8.46.0",
+						"@typescript-eslint/visitor-keys": "8.46.0"
+					}
+				},
+				"@typescript-eslint/tsconfig-utils": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.0.tgz",
+					"integrity": "sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==",
+					"dev": true,
+					"requires": {}
+				},
+				"@typescript-eslint/types": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz",
+					"integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==",
+					"dev": true
+				},
+				"@typescript-eslint/typescript-estree": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.0.tgz",
+					"integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/project-service": "8.46.0",
+						"@typescript-eslint/tsconfig-utils": "8.46.0",
+						"@typescript-eslint/types": "8.46.0",
+						"@typescript-eslint/visitor-keys": "8.46.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.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.0.tgz",
+					"integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==",
+					"dev": true,
+					"requires": {
+						"@eslint-community/eslint-utils": "^4.7.0",
+						"@typescript-eslint/scope-manager": "8.46.0",
+						"@typescript-eslint/types": "8.46.0",
+						"@typescript-eslint/typescript-estree": "8.46.0"
+					}
+				},
+				"@typescript-eslint/visitor-keys": {
+					"version": "8.46.0",
+					"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.0.tgz",
+					"integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==",
+					"dev": true,
+					"requires": {
+						"@typescript-eslint/types": "8.46.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",
@@ -5199,36 +5692,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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz",
-			"integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==",
+			"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.8.0",
-				"@typescript-eslint/visitor-keys": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz",
-			"integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==",
+			"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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz",
-			"integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==",
+			"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.8.0",
-				"@typescript-eslint/visitor-keys": "8.8.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": {
@@ -5252,25 +5815,33 @@
 			}
 		},
 		"@typescript-eslint/utils": {
-			"version": "8.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz",
-			"integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==",
+			"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.8.0",
-				"@typescript-eslint/types": "8.8.0",
-				"@typescript-eslint/typescript-estree": "8.8.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.8.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz",
-			"integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==",
+			"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.8.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": {
@@ -5286,9 +5857,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": {
@@ -5860,11 +6431,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",
@@ -5875,7 +6449,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",
@@ -6010,9 +6584,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": {}
 		},
@@ -8152,9 +8726,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 53cf26d..4d15ad8 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/VisualDataCalendar.js b/resources/VisualDataCalendar.js
index 37d171f..5179cba 100644
--- a/resources/VisualDataCalendar.js
+++ b/resources/VisualDataCalendar.js
@@ -97,7 +97,7 @@ $( function () {
 				// eslint-disable-next-line no-underscore-dangle
 				var found_ = false;
 				for ( var i in params.headerToolbar ) {
-					if ( params.headerToolbar[ i ].indexOf( view_ ) !== -1 ) {
+					if ( params.headerToolbar[ i ].includes( view_ ) ) {
 						found_ = true;
 						break;
 					}
diff --git a/resources/VisualDataDatatables.js b/resources/VisualDataDatatables.js
index 47323b0..c658cd5 100644
--- a/resources/VisualDataDatatables.js
+++ b/resources/VisualDataDatatables.js
@@ -488,8 +488,7 @@ const VisualDataDatatables = function ( el, elIndex ) {
 					label: searchPanesOptions[ i ][ ii ].label,
 					value: function ( rowData, rowIdx ) {
 						return (
-							objectValues( data[ rowIdx ] )[ i ].indexOf(
-								searchPanesOptions[ i ][ ii ].value ) !== -1
+							objectValues( data[ rowIdx ] )[ i ].includes( searchPanesOptions[ i ][ ii ].value )
 						);
 					}
 				} );
@@ -1082,11 +1081,11 @@ $( function () {
 	} );
 
 	var modules = [];
-	if ( buttons.indexOf( 'pdf' ) !== -1 ) {
+	if ( buttons.includes( 'pdf' ) ) {
 		modules.push( 'ext.VisualData.Datatables.export.pdf' );
 	}
 
-	if ( buttons.indexOf( 'excel' ) !== -1 ) {
+	if ( buttons.includes( 'excel' ) ) {
 		modules.push( 'ext.VisualData.Datatables.export.excel' );
 	}
 
diff --git a/resources/VisualDataFormField.js b/resources/VisualDataFormField.js
index 48f7035..9c3a235 100644
--- a/resources/VisualDataFormField.js
+++ b/resources/VisualDataFormField.js
@@ -41,7 +41,7 @@ const VisualDataFormField = function ( phpConfig, windowManager, schemas ) {
 	var HandleQueryOptionsInt;
 
 	function inArray( val, arr ) {
-		return arr.indexOf( val ) !== -1;
+		return arr.includes( val );
 	}
 
 	function getCurrentItem() {
@@ -83,8 +83,8 @@ const VisualDataFormField = function ( phpConfig, windowManager, schemas ) {
 		// except multiselect
 		return ret.filter(
 			( x ) =>
-				( VisualDataFunctions.lookupInputs.indexOf( x ) === -1 &&
-					VisualDataFunctions.optionsInputs.indexOf( x ) === -1 ) ||
+				( !VisualDataFunctions.lookupInputs.includes( x ) &&
+					!VisualDataFunctions.optionsInputs.includes( x ) ) ||
 				VisualDataFunctions.isMultiselect( x )
 		);
 	}
@@ -99,8 +99,8 @@ const VisualDataFormField = function ( phpConfig, windowManager, schemas ) {
 
 			} else {
 				var visibleSharedOptions =
-					Object.keys( HandleOptionsInputsInt.modelMap ).indexOf( i ) !== -1 &&
-					Object.keys( HandleQueryOptionsInt.modelMap ).indexOf( i ) !== -1 &&
+					Object.keys( HandleOptionsInputsInt.modelMap ).includes( i ) &&
+					Object.keys( HandleQueryOptionsInt.modelMap ).includes( i ) &&
 					( optionsHasVisibleItems || queryHasVisibleItems );
 
 				if ( !visibleSharedOptions ) {
@@ -1112,7 +1112,6 @@ const VisualDataFormField = function ( phpConfig, windowManager, schemas ) {
 			var thisAvailableInputsValue = availableInputsInput.getValue();
 			var thisDefaultValueInput = getDefaultValueInput();
 
-			// eslint-disable-next-line no-use-before-define
 			Model.default = defaultValueInput;
 
 			if (
diff --git a/resources/VisualDataForms.js b/resources/VisualDataForms.js
index 2cab4d8..0744c5b 100644
--- a/resources/VisualDataForms.js
+++ b/resources/VisualDataForms.js
@@ -22,8 +22,6 @@
 /* eslint-disable no-tabs */
 /* eslint-disable no-unused-vars */
 /* eslint-disable no-underscore-dangle */
-/* eslint-disable es-x/no-async-functions */
-/* eslint-disable compat/compat */
 
 const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowManager, initForms ) {
 	var Model = {};
@@ -59,7 +57,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 	var FormID;
 
 	function inArray( val, arr ) {
-		return arr.indexOf( val ) !== -1;
+		return arr.includes( val );
 	}
 
 	function escapeJsonPointer( str ) {
@@ -386,10 +384,10 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 						res = ( value.indexOf( refValue ) !== 0 );
 						break;
 					case 'contains':
-						res = ( value.indexOf( refValue ) !== -1 );
+						res = ( value.includes( refValue ) );
 						break;
 					case '!contains':
-						res = ( value.indexOf( refValue ) === -1 );
+						res = ( !value.includes( refValue ) );
 						break;
 					case 'ends':
 						var regExp = new RegExp( escapeRegExp( refValue ) + '$' );
@@ -529,7 +527,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 											);
 										}
 										model.input.addOptions( items );
-										model.input.setValue( values.filter( ( x ) => Object.keys( data_ ).indexOf( x ) !== -1 ) );
+										model.input.setValue( values.filter( ( x ) => Object.keys( data_ ).includes( x ) ) );
 										break;
 								}
 							} );
@@ -638,7 +636,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 
 			var subquery = [];
 			for ( var value of arr ) {
-				if ( value.indexOf( '::' ) === -1 ) {
+				if ( !value.includes( '::' ) ) {
 					var trimmed = value.trim();
 					var match_ = trimmed.match( /<([^<>]+)>/ );
 
@@ -1044,7 +1042,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 			if ( value ) {
 				var valueLowerCase = value.toLowerCase();
 				values = values.filter(
-					( x ) => x.toLowerCase().indexOf( valueLowerCase ) !== -1
+					( x ) => x.toLowerCase().includes( valueLowerCase )
 				);
 			}
 
@@ -1787,7 +1785,7 @@ const VisualDataForms = function ( El, Config, Form, FormIndex, Schemas, WindowM
 
 				Form.schemas = Form.schemas.filter( ( x ) => x in Schemas );
 
-				if ( !SelectedSchema || Form.schemas.indexOf( SelectedSchema ) === -1 ) {
+				if ( !SelectedSchema || !Form.schemas.includes( SelectedSchema ) ) {
 					// @credits https://gerrit.wikimedia.org/r/c/mediawiki/extensions/VisualData/+/1034934
 					if ( 'selected-schema' in Form.options &&
 						Form.options[ 'selected-schema' ] !== '' &&
diff --git a/resources/VisualDataFunctions.js b/resources/VisualDataFunctions.js
index d796c36..10f96bc 100644
--- a/resources/VisualDataFunctions.js
+++ b/resources/VisualDataFunctions.js
@@ -109,7 +109,7 @@ VisualDataFunctions = ( function () {
 
 			case 'boolean':
 				if ( typeof value === 'string' ) {
-					value = [ 'true', 't', '1', 'on', 'yes', 'y' ].indexOf( value ) !== -1;
+					value = [ 'true', 't', '1', 'on', 'yes', 'y' ].includes( value );
 				} else {
 					value = !!value;
 				}
@@ -283,7 +283,7 @@ VisualDataFunctions = ( function () {
 		console.log( '' );
 
 		// @TODO redirect to the extension page for docs on specific inputs
-		if ( inputName.indexOf( 'OO.' ) === -1 && inputName.indexOf( 'mw.' ) === -1 ) {
+		if ( !inputName.includes( 'OO.' ) && !inputName.includes( 'mw.' ) ) {
 			return null;
 		}
 		// or `https://doc.wikimedia.org/oojs-ui/master/js/${inputName}.html`
@@ -292,7 +292,7 @@ VisualDataFunctions = ( function () {
 
 	function isMultiselect( inputName ) {
 		// return inArray(inputName, ManageProperties.multiselectInputs))
-		return inputName.indexOf( 'Multiselect' ) !== -1;
+		return inputName.includes( 'Multiselect' );
 	}
 
 	function inputInstanceFromName( inputName, config ) {
@@ -504,7 +504,7 @@ VisualDataFunctions = ( function () {
 	}
 
 	function inArray( val, arr ) {
-		return arr.indexOf( val ) !== -1;
+		return arr.includes( val );
 	}
 
 	function getKeyByValue( obj, value ) {
@@ -897,7 +897,7 @@ VisualDataFunctions = ( function () {
 	function arrayIntersect( arr1, arr2 ) {
 		var ret = [];
 		for ( var x of arr1 ) {
-			if ( arr2.indexOf( x ) !== -1 ) {
+			if ( arr2.includes( x ) ) {
 				ret.push( x );
 			}
 		}
diff --git a/resources/VisualDataInputConfig.js b/resources/VisualDataInputConfig.js
index 5f5616d..3e3cace 100644
--- a/resources/VisualDataInputConfig.js
+++ b/resources/VisualDataInputConfig.js
@@ -39,7 +39,7 @@ const VisualDataInputConfig = function ( phpConfig, windowManager ) {
 	var HelpUrl;
 
 	function inArray( val, arr ) {
-		return arr.indexOf( val ) !== -1;
+		return arr.includes( val );
 	}
 
 	// @TODO add default for each of them
@@ -945,7 +945,7 @@ const VisualDataInputConfig = function ( phpConfig, windowManager ) {
 			if ( value ) {
 				var valueLowerCase = value.toLowerCase();
 				values = values.filter(
-					( x ) => x.toLowerCase().indexOf( valueLowerCase ) !== -1
+					( x ) => x.toLowerCase().includes( valueLowerCase )
 				);
 			}
 
diff --git a/resources/VisualDataProcessModel.js b/resources/VisualDataProcessModel.js
index a68d216..3fd09de 100644
--- a/resources/VisualDataProcessModel.js
+++ b/resources/VisualDataProcessModel.js
@@ -19,7 +19,6 @@
  * @copyright Copyright © 2023, https://wikisphere.org
  */
 
-/* eslint-disable no-tabs */
 /* eslint-disable no-unused-vars */
 /* eslint-disable no-underscore-dangle */
 
@@ -176,10 +175,10 @@ const VisualDataProcessModel = function (
 			for ( var error of validateAjv.errors ) {
 				switch ( error.keyword ) {
 					case 'uniqueItems':
-						if ( Removed.indexOf( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.j }` ) === -1 ) {
+						if ( !Removed.includes( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.j }` ) ) {
 							AjvErrors.push( $.extend( VisualDataFunctions.deepCopy( error ), { instancePath: `${ error.instancePath }/${ error.params.i }` } ) );
 						}
-						if ( Removed.indexOf( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.i }` ) === -1 ) {
+						if ( !Removed.includes( `${ VisualDataFunctions.escapeJsonPointer( schemaName ) }${ error.instancePath }/${ error.params.i }` ) ) {
 							AjvErrors.push( $.extend( VisualDataFunctions.deepCopy( error ), { instancePath: `${ error.instancePath }/${ error.params.j }` } ) );
 						}
 						break;
@@ -328,7 +327,7 @@ const VisualDataProcessModel = function (
 
 				try {
 					for ( var schemaName in ModelSchemas ) {
-						if ( Form.schemas.indexOf( schemaName ) === -1 ) {
+						if ( !Form.schemas.includes( schemaName ) ) {
 							continue;
 						}
 						ret[ schemaName ] = await getValuesRec(
@@ -359,7 +358,7 @@ const VisualDataProcessModel = function (
 
 			case 'submit':
 				for ( var schemaName in ModelSchemas ) {
-					if ( Form.schemas.indexOf( schemaName ) === -1 ) {
+					if ( !Form.schemas.includes( schemaName ) ) {
 						continue;
 					}
 					ret[ schemaName ] = await getValuesRec(
diff --git a/resources/VisualDataWindowManager.js b/resources/VisualDataWindowManager.js
index 9f4b647..aca33ee 100644
--- a/resources/VisualDataWindowManager.js
+++ b/resources/VisualDataWindowManager.js
@@ -20,7 +20,6 @@
  */
 
 // @see https://doc.wikimedia.org/oojs-ui/master/js/
-// eslint-disable-next-line no-unused-vars
 
 // eslint-disable-next-line no-implicit-globals
 VisualDataWindowManager = function () {
diff --git a/resources/Widgets/VisualDataDateTimeInputWidget.js b/resources/Widgets/VisualDataDateTimeInputWidget.js
index 27e8324..1cd7476 100644
--- a/resources/Widgets/VisualDataDateTimeInputWidget.js
+++ b/resources/Widgets/VisualDataDateTimeInputWidget.js
@@ -19,8 +19,6 @@
  * @copyright Copyright ©2025, https://wikisphere.org
  */
 
-/* eslint-disable no-tabs */
-
 ( function () {
 	// eslint-disable-next-line no-implicit-globals
 	VisualDataDateTimeInputWidget = function ( config ) {
@@ -67,7 +65,7 @@
 
 		// const m = /^(\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?Z$/.exec( value );
 		// ***edited, matches both +01:00 (ISO 8601 vP) and +0100 (ISO 8601 vO)
-		// eslint-disable-next-line security/detect-unsafe-regex
+
 		const m = /^(\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?(Z|[+-]\d{2}:?\d{2}|[+-]\d{4})?$/.exec( value );
 
 		if ( m ) {
diff --git a/resources/Widgets/VisualDataMaptiler.js b/resources/Widgets/VisualDataMaptiler.js
index 18a4206..29294f3 100644
--- a/resources/Widgets/VisualDataMaptiler.js
+++ b/resources/Widgets/VisualDataMaptiler.js
@@ -40,7 +40,7 @@
 		// only load scripts
 		if ( !$element.parent().is( ':visible' ) ) {
 			VisualDataFunctions.loadScripts( this.scripts );
-			return Promise.reject( 'Maptiler element not visible' );
+			throw 'Maptiler element not visible';
 		}
 
 		// *** prevents ajv error "Maximum call stack size exceeded"
@@ -51,7 +51,7 @@
 		var mapId = 'visualdata-maptiler-map-' + data.path;
 
 		if ( $( '#' + jQuery.escapeSelector( mapId ) ).length ) {
-			return Promise.resolve();
+			return;
 		}
 
 		return new Promise( ( resolve, reject ) => {
diff --git a/resources/Widgets/VisualDataMenuTagSearchMultiselect.js b/resources/Widgets/VisualDataMenuTagSearchMultiselect.js
index faa6552..d920a83 100644
--- a/resources/Widgets/VisualDataMenuTagSearchMultiselect.js
+++ b/resources/Widgets/VisualDataMenuTagSearchMultiselect.js
@@ -111,7 +111,7 @@
 
 					// Remove if items' data already exists
 					for ( var i in items ) {
-						if ( existingItems.indexOf( i ) !== -1 ) {
+						if ( existingItems.includes( i ) ) {
 							delete items[ i ];
 						}
 					}
diff --git a/resources/Widgets/VisualDataTinyMCE.js b/resources/Widgets/VisualDataTinyMCE.js
index fbf907a..4e71a44 100644
--- a/resources/Widgets/VisualDataTinyMCE.js
+++ b/resources/Widgets/VisualDataTinyMCE.js
@@ -59,13 +59,13 @@
 	VisualDataTinyMCE.prototype.initialize = async function () {
 		var self = this;
 		if ( self.initialized ) {
-			return Promise.resolve();
+			return;
 		}
 
 		// only load scripts
 		if ( !self.$element.parent().is( ':visible' ) ) {
 			VisualDataFunctions.loadScripts( this.scripts );
-			return Promise.reject( 'TinyMCE element not visible' );
+			throw 'TinyMCE element not visible';
 		}
 
 		return new Promise( ( resolve, reject ) => {
diff --git a/resources/Widgets/VisualDataVisualEditor.js b/resources/Widgets/VisualDataVisualEditor.js
index 6c25230..0776dfe 100644
--- a/resources/Widgets/VisualDataVisualEditor.js
+++ b/resources/Widgets/VisualDataVisualEditor.js
@@ -61,13 +61,13 @@
 		var self = this;
 
 		if ( this.isInitialized() || this.initializing ) {
-			return Promise.resolve( true );
+			return true;
 		}
 
 		this.initializing = true;
 
 		if ( !self.$element.parent().is( ':visible' ) ) {
-			return Promise.reject( 'VEForAll element not visible' );
+			throw 'VEForAll element not visible';
 		}
 
 		return new Promise( ( resolve, reject ) => {
diff --git a/resources/Widgets/VisualDataintlTelInput.js b/resources/Widgets/VisualDataintlTelInput.js
index 2c8a9e5..b077258 100644
--- a/resources/Widgets/VisualDataintlTelInput.js
+++ b/resources/Widgets/VisualDataintlTelInput.js
@@ -164,7 +164,7 @@
 		];
 
 		if (
-			!Object.keys( config ).filter( ( x ) => configCountries.indexOf( x ) !== -1 )
+			!Object.keys( config ).filter( ( x ) => configCountries.includes( x ) )
 				.length
 		) {
 			return;
@@ -181,7 +181,7 @@
 			if ( i in config ) {
 				if ( i === 'initialCountry' ) {
 					config[ i ] = config[ i ].toLowerCase();
-					if ( iso2.indexOf( config[ i ] ) === -1 ) {
+					if ( !iso2.includes( config[ i ] ) ) {
 						// eslint-disable-next-line no-console
 						console.error( config[ i ] + ' is not a valid country code' );
 						delete config[ i ];
@@ -190,7 +190,7 @@
 				}
 				var values = [];
 				for ( var ii of config[ i ] ) {
-					if ( iso2.indexOf( ii ) === -1 ) {
+					if ( !iso2.includes( ii ) ) {
 						// eslint-disable-next-line no-console
 						console.error( ii + ' is not a valid country code' );
 						values.splice( ii, 1 );
diff --git a/resources/slick/main.js b/resources/slick/main.js
index 731c622..699c8d8 100644
--- a/resources/slick/main.js
+++ b/resources/slick/main.js
@@ -54,7 +54,7 @@
 			if ( $( this ).attr( 'data-url' ) ) {
 				// $(this).attr('title', $(this).attr('data-title') )
 				$( this ).css( 'cursor', 'pointer' );
-				$( this ).click( function () {
+				$( this ).on( 'click', function () {
 					window.location = $( this ).attr( 'data-url' );
 				} );
 			}
-- 
2.47.3


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