{
	"$schema": "http://json-schema.org/schema#",
	"description": "MediaWiki extension.json schema",
	"definitions": {
		"resourceLoaderFileInfo": {
			"oneOf": [
				{
					"type": "string",
					"description": "The name of the file"
				},
				{
					"type": "object",
					"required": [ "name" ],
					"properties": {
						"name": {
							"type": "string",
							"description": "The name of the file"
						},
						"type": {
							"type": "string",
							"description": "The type of the file. The default is to detect it from the extension",
							"enum": [ "script", "script-vue", "data", "text" ]
						},
						"main": {
							"type": "boolean",
							"description": "Used to indicate the main script in a package"
						},
						"content": {
							"type": "string",
							"description": "The content to use for the file"
						},
						"file": {
							"type": "string",
							"description": "The relative path to the file"
						},
						"callback": {
							"type": [ "string", "array" ],
							"description": "A PHP method to call for the file contents"
						},
						"callbackParam": {
							"description": "A value to be passed as the third parameter to the callback and versionCallback"
						},
						"versionCallback": {
							"type": [ "string", "array" ],
							"description": "A PHP method which will return either a FilePath or the definition summary for the file"
						},
						"config": {
							"type": "array",
							"description": "An array of config variable names to be delivered as a JSON data file",
							"items": {
								"type": "string"
							}
						}
					}
				}
			]
		},
		"ObjectFactorySpec": {
			"type": "object",
			"properties": {
				"factory": {
					"type": [ "string", "array" ],
					"description": "A factory function to be called to create the object"
				},
				"class": {
					"type": "string",
					"description": "The fully-qualified class name of the object. This should be omitted if a factory is specified."
				},
				"args": {
					"type": "array",
					"description": "The arguments passed to the object constructor or factory"
				},
				"services": {
					"type": "array",
					"description": "If supplied and non-empty, the named services are requested from the service container and prepended before 'args'."
				},
				"optional_services": {
					"type": "array",
					"description": "If supplied and non-empty, the named services are requested from the service container and appended after 'services' if the services are available; null is passed if the services are not available."
				}
			}
		}
	},
	"type": "object",
	"required": [
		"manifest_version",
		"name"
	],
	"properties": {
		"manifest_version": {
			"type": "integer",
			"description": "Version of the extension.json schema the extension.json file is in."
		},
		"name": {
			"type": "string",
			"description": "The extension's canonical name."
		},
		"namemsg": {
			"type": "string",
			"description": "i18n message key of the extension's name."
		},
		"type": {
			"type": "string",
			"description": "The extension's type.",
			"examples": [
				"api",
				"antispam",
				"editor",
				"media",
				"parserhook",
				"semantic",
				"skin",
				"specialpage",
				"variable",
				"wikibase",
				"other"
			],
			"default": "other"
		},
		"author": {
			"type": [
				"string",
				"array"
			],
			"description": "Extension's authors.",
			"items": {
				"type": "string"
			}
		},
		"version": {
			"type": "string",
			"description": "The version of this release of the extension."
		},
		"url": {
			"type": "string",
			"description": "URL to the homepage for the extension.",
			"format": "uri-reference"
		},
		"description": {
			"type": "string",
			"description": "Raw description of the extension."
		},
		"descriptionmsg": {
			"type": "string",
			"description": "Message key for a i18n message describing the extension."
		},
		"license-name": {
			"type": "string",
			"description": "SPDX identifier for the license under which the extension is released."
		},
		"requires": {
			"type": "object",
			"description": "Indicates what versions of PHP, MediaWiki core, extensions or skins are required. This syntax may be extended in the future, for example to check dependencies between other services.",
			"additionalProperties": false,
			"properties": {
				"MediaWiki": {
					"type": "string",
					"description": "Version constraint string against MediaWiki core."
				},
				"platform": {
					"type": "object",
					"description": "Indicates version constraints against platform services.",
					"additionalProperties": false,
					"properties": {
						"php": {
							"type": "string",
							"description": "Version constraint string against PHP."
						},
						"ability-shell": {
							"type": "boolean",
							"default": false,
							"description": "Whether this extension requires shell access."
						}
					},
					"patternProperties": {
						"^ext-": {
							"type": "string",
							"description": "Required PHP extension.",
							"enum": [ "*" ]
						}
					}
				},
				"extensions": {
					"type": "object",
					"description": "Set of version constraint strings against specific extensions."
				},
				"skins": {
					"type": "object",
					"description": "Set of version constraint strings against specific skins."
				}
			}
		},
		"suggests": {
			"type": "object",
			"description": "Indicates what versions of PHP and MediaWiki extensions or skins are optional suggestions. This syntax may be extended in the future, for example to check dependencies between other services.",
			"additionalProperties": false,
			"properties": {
				"platform": {
					"type": "object",
					"description": "Indicates optional version constraints against platform services.",
					"additionalProperties": false,
					"properties": {
						"php": {
							"type": "string",
							"description": "Optional version constraint string against PHP."
						},
						"ability-shell": {
							"type": "boolean",
							"default": false,
							"description": "Whether this extension requires shell access."
						}
					},
					"patternProperties": {
						"^ext-": {
							"type": "string",
							"description": "Optional PHP extension.",
							"enum": [ "*" ]
						}
					}
				},
				"extensions": {
					"type": "object",
					"description": "Set of optional version constraint strings against specific extensions."
				},
				"skins": {
					"type": "object",
					"description": "Set of optional version constraint strings against specific skins."
				}
			}
		},
		"dev-requires": {
			"type": "object",
			"description": "Indicates what dependencies are required for development purposes such as running tests. This syntax may be extended in the future.",
			"additionalProperties": false,
			"properties": {
				"MediaWiki": {
					"type": "string",
					"description": "Version constraint string against MediaWiki core."
				},
				"platform": {
					"type": "object",
					"description": "Indicates version constraints against platform services.",
					"additionalProperties": false,
					"properties": {
						"php": {
							"type": "string",
							"description": "Version constraint string against PHP."
						},
						"ability-shell": {
							"type": "boolean",
							"default": false,
							"description": "Whether this extension requires shell access."
						}
					},
					"patternProperties": {
						"^ext-": {
							"type": "string",
							"description": "Required PHP extension.",
							"enum": [ "*" ]
						}
					}
				},
				"extensions": {
					"type": "object",
					"description": "Set of version constraint strings against specific extensions."
				},
				"skins": {
					"type": "object",
					"description": "Set of version constraint strings against specific skins."
				}
			}
		},
		"ResourceFileModulePaths": {
			"type": "object",
			"description": "Default paths to use for all ResourceLoader file modules",
			"additionalProperties": false,
			"properties": {
				"localBasePath": {
					"type": "string",
					"description": "Base path to prepend to all local paths, relative to current directory"
				},
				"remoteExtPath": {
					"type": "string",
					"description": "Base path to prepend to all remote paths, relative to $wgExtensionAssetsPath"
				},
				"remoteSkinPath": {
					"type": "string",
					"description": "Base path to prepend to all remote paths, relative to $wgStylePath"
				}
			}
		},
		"ResourceModules": {
			"type": "object",
			"description": "ResourceLoader modules to register",
			"patternProperties": {
				"^[a-zA-Z0-9-\\.]+$": {
					"type": "object",
					"anyOf": [
						{
							"description": "A FileModule definition",
							"additionalProperties": false,
							"properties": {
								"localBasePath": {
									"type": "string",
									"description": "Base path to prepend to all local paths in $options. Defaults to $IP"
								},
								"remoteBasePath": {
									"type": "string",
									"description": "Base path to prepend to all remote paths in $options. Defaults to $wgScriptPath"
								},
								"remoteExtPath": {
									"type": "string",
									"description": "Equivalent of remoteBasePath, but relative to $wgExtensionAssetsPath"
								},
								"skipFunction": {
									"type": "string",
									"description": "Path to a file containing a JavaScript \"skip function\", if desired."
								},
								"scripts": {
									"type": [ "string", "array" ],
									"description": "Scripts to always include. Array of file paths or package file objects.",
									"items": { "$ref": "#/definitions/resourceLoaderFileInfo" }
								},
								"languageScripts": {
									"type": "object",
									"description": "Scripts to include in specific language contexts (mapping of language code to file path(s))",
									"patternProperties": {
										"^[a-zA-Z0-9-]{2,}$": {
											"type": [
												"string",
												"array"
											],
											"items": { "$ref": "#/definitions/resourceLoaderFileInfo" }
										}
									}
								},
								"skinScripts": {
									"type": "object",
									"description": "Scripts to include in specific skin contexts (mapping of skin name to script(s)",
									"patternProperties": {
										".+": {
											"type": [
												"string",
												"array"
											],
											"items": { "$ref": "#/definitions/resourceLoaderFileInfo" }
										}
									}
								},
								"debugScripts": {
									"type": [ "string", "array" ],
									"description": "Scripts to include in debug contexts",
									"items": {
										"$ref": "#/definitions/resourceLoaderFileInfo"
									}
								},
								"dependencies": {
									"type": [ "string", "array" ],
									"description": "Modules which must be loaded before this module",
									"items": {
										"type": "string"
									}
								},
								"styles": {
									"type": [ "string", "array", "object" ],
									"description": "Styles to always load",
									"items": {
										"type": "string"
									}
								},
								"skinStyles": {
									"type": "object",
									"description": "Styles to include in specific skin contexts (mapping of skin name to style(s))",
									"patternProperties": {
										".+": {
											"type": [
												"string",
												"array"
											],
											"items": {
												"type": "string"
											}
										}
									}
								},
								"messages": {
									"type": [ "string", "array" ],
									"description": "Messages to always load",
									"items": {
										"type": "string"
									}
								},
								"group": {
									"type": "string",
									"description": "Group with which this module should be loaded"
								},
								"deprecated": {
									"type": [ "object", "string", "boolean" ],
									"description": "Whether the module is deprecated and usage is discouraged. Either a boolean, or a string or an object with key message can be used to customise deprecation message."
								},
								"position": {
									"type": "string",
									"description": "Position on the page to load this module at (unused since MediaWiki 1.29)",
									"enum": [
										"bottom",
										"top"
									]
								},
								"templates": {
									"type": [ "object", "array" ],
									"description": "Templates to be loaded for client-side usage"
								},
								"targets": {
									"type": [ "string", "array" ],
									"description": "ResourceLoader target the module can run on (unused since MediaWiki 1.42)",
									"items": {
										"type": "string"
									}
								},
								"noflip": {
									"type": "boolean",
									"description": "Whether to skip CSSJanus LTR-to-RTL flipping for this module. Recommended for styles imported from libraries that already properly handle their RTL styles. Default is false, meaning CSSJanus will be applied on RTL-mode output."
								},
								"packageFiles": {
									"type": [ "string", "array" ],
									"description": "Package files that can be require()d",
									"items": {
										"$ref": "#/definitions/resourceLoaderFileInfo"
									}
								},
								"es6": {
									"type": "boolean",
									"description": "Deprecated flag as to whether this module requires an ES6-capable browser; ignored since MediaWiki 1.41. Default is true."
								},
								"skipStructureTest": {
									"type": "boolean",
									"description": "Whether to skip ResourcesTest::testRespond()"
								}
							}
						},
						{
							"description": "A WikiModule definition",
							"additionalProperties": false,
							"properties": {
								"class": {
									"type": "string"
								},
								"group": {
									"type": "string",
									"description": "Group with which this module should be loaded"
								},
								"position": {
									"type": "string",
									"description": "Position on the page to load this module at (unused since MediaWiki 1.29)",
									"enum": [
										"bottom",
										"top"
									]
								},
								"targets": {
									"type": [ "string", "array" ],
									"description": "ResourceLoader target the module can run on (unused since MediaWiki 1.42)",
									"items": {
										"type": "string"
									}
								},
								"scripts": {
									"type": "array",
									"description": "A list of on-wiki pages containing JavaScript that should be loaded",
									"items": {
										"type": "string"
									}
								},
								"styles": {
									"type": "array",
									"description": "A list of on-wiki pages containing CSS that should be loaded",
									"items": {
										"type": "string"
									}
								}
							}
						},
						{
							"description": "An ImageModule definition",
							"additionalProperties": false,
							"properties": {
								"class": {
									"type": "string"
								},
								"localBasePath": {
									"type": "string",
									"description": "Base path to prepend to all local paths. Defaults to $IP"
								},
								"defaultColor": {
									"type": "string"
								},
								"data": {
									"type": "string"
								},
								"prefix": {
									"type": "string"
								},
								"selector": {
									"type": "string"
								},
								"selectorWithoutVariant": {
									"type": "string"
								},
								"selectorWithVariant": {
									"type": "string"
								},
								"useDataURI": {
									"type": "boolean"
								},
								"variants": {
									"type": "object"
								},
								"images": {
									"type": "object"
								},
								"position": {
									"type": "string",
									"description": "Position on the page to load this module at (unused since MediaWiki 1.29)",
									"enum": [
										"top",
										"bottom"
									]
								}
							}
						},
						{
							"description": "An arbitrary ResourceLoader Module definition by class",
							"properties": {
								"class": {
									"type": "string",
									"pattern": "^(?!ResourceLoader(File|Image|Wiki)Module).*$"
								}
							},
							"required": [ "class" ]
						}
					]
				}
			}
		},
		"ResourceModuleSkinStyles": {
			"type": "object",
			"description": "ResourceLoader modules for custom skin styles"
		},
		"ResourceLoaderSources": {
			"type": "object",
			"description": "ResourceLoader sources to register"
		},
		"SkinLessImportPaths": {
			"type": "object",
			"description": "Path to the skin-specific LESS import directory, keyed by skin name. Can be used to define skin-specific LESS variables."
		},
		"QUnitTestModule": {
			"type": "object",
			"description": "A ResourceLoader FileModule definition registered only when wgEnableJavaScriptTest is true.",
			"additionalProperties": false,
			"properties": {
				"localBasePath": {
					"type": "string",
					"description": "Prefix for local paths to files in $options, relative to extension directory"
				},
				"remoteExtPath": {
					"type": "string",
					"description": "Prefix for URLs to files in $options, relative to $wgExtensionAssetsPath"
				},
				"remoteSkinPath": {
					"type": "string",
					"description": "Prefix for URLs to files in $options, relative to $wgStylePath"
				},
				"scripts": {
					"type": [ "string", "array" ],
					"description": "Scripts to include (array of file paths)",
					"items": {
						"type": "string"
					}
				},
				"packageFiles": {
					"type": [ "string", "array" ],
					"description": "Package files that can be require()d",
					"items": {
						"type": [ "string", "object" ]
					}
				},
				"dependencies": {
					"type": [ "string", "array" ],
					"description": "Modules which must be loaded before this module",
					"items": {
						"type": "string"
					}
				},
				"styles": {
					"type": [ "string", "array", "object" ],
					"description": "Styles to load",
					"items": {
						"type": "string"
					}
				},
				"templates": {
					"type": [ "object", "array" ],
					"description": "Templates to be loaded for client-side usage",
					"items": {
						"type": "string"
					}
				},
				"messages": {
					"type": [ "string", "array" ],
					"description": "Messages to load",
					"items": {
						"type": "string"
					}
				}
			}
		},
		"MessagePosterModule": {
			"type": "object",
			"description": "Additional JavaScript files and modules that will register content models with mw.messagePoster.factory.",
			"additionalProperties": false,
			"properties": {
				"localBasePath": {
					"type": "string",
					"description": "Prefix for local paths to files in $options, relative to extension directory"
				},
				"scripts": {
					"type": "array",
					"description": "Scripts to include as array of file paths",
					"items": {
						"type": "string"
					}
				},
				"dependencies": {
					"type": "array",
					"description": "Modules which must load before these files",
					"items": {
						"type": "string"
					}
				}
			}
		},
		"ConfigRegistry": {
			"type": "object",
			"description": "Registry of factory functions to create Config objects"
		},
		"SessionProviders": {
			"type": "object",
			"description": "Session providers"
		},
		"AuthManagerAutoConfig": {
			"type": "object",
			"description": "AuthManager auto-configuration",
			"additionalProperties": false,
			"properties": {
				"preauth": {
					"type": "object",
					"description": "Pre-authentication providers"
				},
				"primaryauth": {
					"type": "object",
					"description": "Primary authentication providers"
				},
				"secondaryauth": {
					"type": "object",
					"description": "Secondary authentication providers"
				}
			}
		},
		"CentralIdLookupProviders": {
			"type": "object",
			"description": "Central ID lookup providers"
		},
		"namespaces": {
			"type": "array",
			"description": "Method to add extra namespaces",
			"items": {
				"type": "object",
				"properties": {
					"id": {
						"type": "integer"
					},
					"constant": {
						"type": "string"
					},
					"name": {
						"type": "string"
					},
					"gender": {
						"type": "object",
						"properties": {
							"male": {
								"type": "string"
							},
							"female": {
								"type": "string"
							}
						}
					},
					"subpages": {
						"type": "boolean",
						"default": false
					},
					"content": {
						"type": "boolean",
						"default": false
					},
					"defaultcontentmodel": {
						"type": "string"
					},
					"protection": {
						"type": [ "string", "array" ],
						"description": "Userright(s) required to edit in this namespace"
					},
					"capitallinkoverride": {
						"type": "boolean",
						"description": "Set $wgCapitalLinks on a per-namespace basis"
					},
					"conditional": {
						"type": "boolean",
						"description": "Whether the namespace is conditional upon configuration and should not be registered (requires separate registration via a hook)",
						"default": false
					},
					"movable": {
						"type": "boolean",
						"description": "Whether it is possible to move pages in this namespace",
						"default": true
					},
					"includable": {
						"type": "boolean",
						"description": "Whether it is possible to include/transclude pages in this namespace",
						"default": true
					}
				},
				"required": [ "id", "constant", "name" ]
			}
		},
		"TrackingCategories": {
			"type": "array",
			"description": "Tracking category message keys",
			"items": {
				"type": "string"
			}
		},
		"DefaultUserOptions": {
			"type": "object",
			"description": "Default values of user options"
		},
		"ConditionalUserOptions": {
			"type": "object",
			"description": "Conditional defaults of user options"
		},
		"HiddenPrefs": {
			"type": "array",
			"description": "Preferences users cannot set",
			"items": {
				"type": "string"
			}
		},
		"GroupPermissions": {
			"type": "object",
			"description": "Default permissions to give to user groups",
			"patternProperties": {
				"^[a-z]+$": {
					"type": "object",
					"patternProperties": {
						"^[a-z]+$": {
							"type": "boolean"
						}
					}
				}
			}
		},
		"PrivilegedGroups": {
			"type": "array",
			"description": "User groups that should be considered privileged",
			"items": {
				"type": "string"
			}
		},
		"RevokePermissions": {
			"type": "object",
			"description": "Default permissions to revoke from user groups",
			"patternProperties": {
				"^[a-z]+$": {
					"type": "object",
					"patternProperties": {
						"^[a-z]+$": {
							"type": "boolean"
						}
					}
				}
			}
		},
		"GrantPermissions": {
			"type": "object",
			"description": "Map of permissions granted to authorized consumers to their bundles, called 'grants'",
			"patternProperties": {
				"^[a-z]+$": {
					"type": "object",
					"patternProperties": {
						"^[a-z]+$": {
							"type": "boolean"
						}
					}
				}
			}
		},
		"GrantPermissionGroups": {
			"type": "object",
			"description": "Map of grants to their UI grouping",
			"patternProperties": {
				"^[a-z]+$": {
					"type": "string"
				}
			}
		},
		"GrantRiskGroups": {
			"type": "object",
			"description": "Map of grants to their risk category",
			"patternProperties": {
				"^[a-z]+$": {
					"type": "string"
				}
			}
		},
		"ImplicitGroups": {
			"type": "array",
			"description": "Implicit groups"
		},
		"GroupsAddToSelf": {
			"type": "object",
			"description": "Groups a user can add to themselves"
		},
		"GroupsRemoveFromSelf": {
			"type": "object",
			"description": "Groups a user can remove from themselves"
		},
		"AddGroups": {
			"type": "object",
			"description": "Groups a user can add to users"
		},
		"RemoveGroups": {
			"type": "object",
			"description": "Groups a user can remove from users"
		},
		"AvailableRights": {
			"type": "array",
			"description": "User rights added by the extension",
			"items": {
				"type": "string"
			}
		},
		"ContentHandlers": {
			"type": "object",
			"description": "Mapping of model ID to class name or an ObjectFactory specification.",
			"patternProperties": {
				"^[A-Za-z]+$": {
					"oneOf": [
						{
							"type": "string",
							"description": "Class name of the ContentHandler."
						},
						{
							"type": "object",
							"description": "ObjectFactory specification of the ContentHandler."
						}
					]
				}
			}
		},
		"RateLimits": {
			"type": "object",
			"description": "Rate limits"
		},
		"RecentChangesFlags": {
			"type": "object",
			"description": "Flags (letter symbols) shown on RecentChanges pages"
		},
		"MediaHandlers": {
			"type": "object",
			"description": "Plugins for media file type handling. Each entry in the array maps a MIME type to a PHP class name."
		},
		"ExtensionFunctions": {
			"type": [
				"array",
				"string"
			],
			"description": "Function to call after setup has finished",
			"items": {
				"type": "string"
			}
		},
		"ExtensionMessagesFiles": {
			"type": "object",
			"description": "File paths containing PHP internationalization data"
		},
		"RestModuleFiles": {
			"type": "array",
			"description": "Paths of REST API module files"
		},
		"MessagesDirs": {
			"type": "object",
			"description": "Directory paths containing JSON internationalization data"
		},
		"TranslationAliasesDirs": {
			"type": "object",
			"description": "Message directories containing JSON files for localisation of special page aliases"
		},
		"ExtensionEntryPointListFiles": {
			"type": "object"
		},
		"SpecialPages": {
			"type": "object",
			"description": "SpecialPages implemented in this extension (mapping of page name to class name or to ObjectFactory spec, or factory callback)"
		},
		"AutoloadNamespaces": {
			"type": "object",
			"description": "Mapping of PSR-4 compliant namespace to directory for autoloading",
			"patternProperties": {
				"^[A-Za-z0-9\\\\]+\\\\$": {
					"type": "string"
				}
			},
			"additionalProperties": false
		},
		"AutoloadClasses": {
			"type": "object"
		},
		"TestAutoloadNamespaces": {
			"type": "object",
			"description": "Mapping of PSR-4 compliant namespace to directory for autoloading to be used in tests",
			"patternProperties": {
				"^[A-Za-z0-9\\\\]+\\\\$": {
					"type": "string"
				}
			},
			"additionalProperties": false
		},
		"TestAutoloadClasses": {
			"type": "object"
		},
		"Hooks": {
			"type": "object",
			"description": "Hooks this extension uses (mapping of hook name to callback)",
			"additionalProperties": {
				"oneOf": [
					{
						"type": "string",
						"description": "A global function name, static function name, or the name of a property in HookHandlers"
					},
					{
						"type": "object",
						"description": "A handler specification",
						"properties": {
							"handler": {
								"type": "string",
								"description": "The name of a property in HookHandlers"
							},
							"deprecated": {
								"type": "boolean",
								"description": "The deprecation acknowledgement flag for the handler. If this is true, calls will be filtered if the relevant hook is deprecated."
							}
						},
						"required": [
							"handler"
						]
					},
					{
						"type": "array",
						"description": "An ordered array of handlers",
						"items": {
							"oneOf": [
								{
									"type": "string",
									"description": "A global function name, static function name, or the name of a property in HookHandlers"
								},
								{
									"type": "object",
									"description": "A handler specification",
									"properties": {
										"handler": {
											"type": "string",
											"description": "The name of a property in HookHandlers"
										},
										"deprecated": {
											"type": "boolean",
											"description": "The deprecation acknowledgement flag for the handler. If this is true, calls will be filtered if the relevant hook is deprecated."
										}
									},
									"required": [
										"handler"
									]
								}
							]
						}
					}
				]
			}
		},
		"HookHandlers": {
			"type": "object",
			"description": "ObjectFactory specifications for new-style hook handlers",
			"additionalProperties": { "$ref": "#/definitions/ObjectFactorySpec" }
		},
		"DeprecatedHooks": {
			"type": "object",
			"description": "Hooks which are defined and deprecated by the extension",
			"additionalProperties": {
				"type": "object",
				"properties": {
					"deprecatedVersion": {
						"type": "string",
						"description": "The version in which the hook was deprecated"
					},
					"component": {
						"type": "string",
						"description": "The component to which the deprecated version relates. If omitted, the extension name will be used."
					},
					"silent": {
						"type": "boolean",
						"description": "If true, no warning is raised when the hook is called or when a handler is declared. However, call filtering is still activated."
					}
				},
				"required": [
					"deprecatedVersion"
				]
			}
		},
		"JobClasses": {
			"type": "object",
			"description": "Job types this extension implements (mapping of job type to class name or factory function)"
		},
		"LogTypes": {
			"type": "array",
			"description": "List of new log types this extension uses"
		},
		"LogRestrictions": {
			"type": "object"
		},
		"FilterLogTypes": {
			"type": "object"
		},
		"ActionFilteredLogs": {
			"type": "object",
			"description": "List of log types which can be filtered by log actions",
			"patternProperties": {
				"^[a-z-]+$": {
					"type": "object",
					"patternProperties": {
						"^[a-z-]+$": {
							"type": "array",
							"items": {
								"type": "string"
							}
						}
					}
				}
			}
		},
		"LogNames": {
			"type": "object"
		},
		"LogHeaders": {
			"type": "object"
		},
		"LogActions": {
			"type": "object"
		},
		"LogActionsHandlers": {
			"type": "object"
		},
		"Actions": {
			"type": "object"
		},
		"APIModules": {
			"type": "object"
		},
		"APIFormatModules": {
			"type": "object"
		},
		"APIMetaModules": {
			"type": "object"
		},
		"APIPropModules": {
			"type": "object"
		},
		"APIListModules": {
			"type": "object"
		},
		"ValidSkinNames": {
			"type": "object",
			"description": "Mapping of skin canonical names to PHP class name using the Object Factory specification. Or historically, the human readable name of the skin."
		},
		"FeedClasses": {
			"type": "object",
			"description": "Available feeds objects"
		},
		"SkinOOUIThemes": {
			"type": "object",
			"description": "Map of skin names to OOUI themes to use. Same format as MediaWiki\\ResourceLoader\\OOUIModule::$builtinSkinThemeMap."
		},
		"OOUIThemePaths": {
			"type": "object",
			"description": "Map of custom OOUI theme names to paths to load them from. Same format as MediaWiki\\ResourceLoader\\OOUIModule::$builtinThemePaths.",
			"patternProperties": {
				"^[A-Za-z]+$": {
					"type": "object",
					"additionalProperties": false,
					"properties": {
						"scripts": {
							"type": "string",
							"description": "Path to script file."
						},
						"styles": {
							"type": "string",
							"description": "Path to style files. '{module}' will be replaced with the module's name."
						},
						"images": {
							"type": "string",
							"description": "Path to image definition files. '{module}' will be replaced with the module's name. If the files don't exist, default theme's images will be used instead."
						}
					}
				}
			}
		},
		"SkinCodexThemes": {
			"type": "object",
			"description": "Name of the Codex theme to use for each skin, keyed by skin name. Skins not specified here default to the wikimedia-ui theme."
		},
		"PasswordPolicy": {
			"type": "object",
			"description": "Password policies"
		},
		"FileExtensions": {
			"type": "array",
			"description": "Preferred file extensions for uploading",
			"items": {
				"type": "string"
			}
		},
		"RawHtmlMessages": {
			"type": "array",
			"description": "Messages which are rendered as raw HTML",
			"items": {
				"type": "string"
			}
		},
		"LateJSConfigVarNames": {
			"type": "array",
			"description": "Names of JS config vars (as used in MakeGlobalVariablesScript hook or in ParserOutput::setJsConfigVar) that may be set from the end of the HTML body instead of the HTML head, to improve page load time. In JavaScript, these variables should be accessed via mw.hook('wikipage.content').",
			"items": {
				"type": "string"
			}
		},
		"DatabaseVirtualDomains": {
			"type": "array",
			"description": "Names of virtual domains that are used to get a db connection.",
			"items": {
				"type": "string"
			}
		},
		"ReauthenticateTime": {
			"type": "object",
			"patternProperties": {
				".*": {
					"type": "integer"
				}
			}
		},
		"callback": {
			"type": [
				"array",
				"string"
			],
			"description": "A function to be called right after MediaWiki processes this file"
		},
		"config": {
			"type": "object",
			"description": "Configuration options for this extension",
			"properties": {
				"_prefix": {
					"type": "string",
					"default": "wg",
					"description": "Prefix to put in front of configuration settings when exporting them to $GLOBALS"
				}
			},
			"patternProperties": {
				"^[a-zA-Z_\u007f-\u00ff][a-zA-Z0-9_\u007f-\u00ff]*$": {
					"properties": {
						"_merge_strategy": {
							"type": "string",
							"enum": [
								"array_replace_recursive",
								"array_plus_2d",
								"array_plus",
								"array_merge",
								"provide_default"
							],
							"default": "array_merge"
						}
					}
				}
			}
		},
		"SearchMappings": {
			"type": "object",
			"description": "Mapping of search canonical names (used in $wgSearchType and $wgSearchTypeAlternatives) using the Object Factory specification"
		},
		"ServiceWiringFiles": {
			"type": "array",
			"description": "List of service wiring files to be loaded by the default instance of MediaWikiServices"
		},
		"RestRoutes": {
			"type": "array",
			"description": "List of route specifications to be added to the REST API",
			"items": {
				"allOf": [
					{
						"type": "object",
						"properties": {
							"method": {
								"oneOf": [
									{
										"type": "string",
										"description": "The HTTP method name"
									},
									{
										"type": "array",
										"items": {
											"type": "string",
											"description": "An acceptable HTTP method name"
										}
									}
								]
							},
							"path": {
								"type": "string",
								"description": "The path template. This should start with an initial slash, designating the root of the REST API. Path parameters are enclosed in braces, for example /endpoint/{param}."
							},
							"factory": { "description": "See the ObjectFactorySpec definition" },
							"class": { "description": "See the ObjectFactorySpec definition" },
							"args": { "description": "See the ObjectFactorySpec definition" },
							"services": { "description": "See the ObjectFactorySpec definition" },
							"optional_services": { "description": "See the ObjectFactorySpec definition" }
						}
					},
					{ "$ref": "#/definitions/ObjectFactorySpec" }
				]
			}
		},
		"ParsoidModules": {
			"type": "array",
			"description": "List of extension modules to be registered with the Parsoid wikitext parser",
			"items": {
				"oneOf": [
					{
						"type": "string",
						"description": "The fully-qualified name of a class implementing Wikimedia\\Parsoid\\Ext\\ExtensionModule"
					},
					{
						"type": "object",
						"description": "Object factory specification for a class implementing Wikimedia\\Parsoid\\Ext\\ExtensionModule",
						"properties": {
							"factory": {
								"type": [ "string", "array" ],
								"description": "A factory function to be called to create an ExtensionModule. This should be omitted if a class is specified."
							}
						},
						"required": [ "factory" ]
					},
					{
						"type": "object",
						"description": "Object factory specification for a class implementing Wikimedia\\Parsoid\\Ext\\ExtensionModule",
						"properties": {
							"class": {
								"type": "string",
								"description": "The fully-qualified class name of a class implementing Wikimedia\\Parsoid\\Ext\\ExtensionModule. This should be omitted if a factory is specified."
							}
						},
						"required": [ "class" ]
					},
					{
						"type": "object",
						"description": "A Parsoid extension module configuration array",
						"properties": {
							"class": {
								"type": "null",
								"description": "This property must not be present in a configuration array"
							},
							"factory": {
								"type": "null",
								"description": "This property must not be present in a configuration array"
							},
							"domProcessors": {
								"type": "array",
								"items": {
									"description": "Object factory specification of a class implementing Wikimedia\\Parsoid\\Ext\\DOMProcessor"
								}
							},
							"styles": {
								"type": "array",
								"items": {
									"type": "string",
									"description": "Additional ResourceLoader styles to include"
								}
							},
							"annotations": {
								"type": "array",
								"items": {
									"type": "string",
									"description": "The name of an annotation tag"
								}
							},
							"tags": {
								"type": "array",
								"items": {
									"type": "object",
									"description": "An extension tag",
									"properties": {
										"name": {
											"type": "string",
											"description": "The name of the extension tag"
										},
										"handler": {
											"description": "An object factory specification of a class extending Wikimedia\\Parsoid\\Ext\\ExtensionTagHandler"
										},
										"options": {
											"type": "object",
											"description": "Additional Parsoid processing configuration for this extension tag"
										}
									},
									"required": [ "name" ]
								}
							}
						}
					}
				]
			}
		},
		"TempUserSerialProviders": {
			"type": "object",
			"description": "Map of temporary user serial provider type name to ObjectFactory spec",
			"patternProperties": {
				".*": { "$ref": "#/definitions/ObjectFactorySpec" }
			}
		},
		"TempUserSerialMappings": {
			"type": "object",
			"description": "Map of temporary user serial map type name to ObjectFactory spec",
			"patternProperties": {
				".*": { "$ref": "#/definitions/ObjectFactorySpec" }
			}
		},
		"UserOptionsStoreProviders": {
			"type": "object",
			"description": "Map of user options store providers (specs for ObjectFactory, indexed by provider name). The class should implement the UserOptionsStore interface.",
			"patternProperties": {
				".*": { "$ref": "#/definitions/ObjectFactorySpec" }
			}
		},
		"UserRegistrationProviders": {
			"type": "object",
			"description": "Map of user registration timestamp providers (specs for ObjectFactory, indexed by provider name)",
			"patternProperties": {
				".*": { "$ref": "#/definitions/ObjectFactorySpec" }
			}
		},
		"ForeignResourcesDir": {
			"type": "string",
			"description": "The directory holding the foreign-resources.yaml file, relative to the extension root. See https://www.mediawiki.org/wiki/Foreign_resources"
		},
		"load_composer_autoloader": {
			"type": "boolean",
			"description": "Load the composer autoloader for this extension, if one is present"
		}
	}
}
