Merge "UsersMultiselect widget and form field."
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 1 Feb 2017 14:37:50 +0000 (14:37 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 1 Feb 2017 14:37:50 +0000 (14:37 +0000)
1  2 
autoload.php
includes/htmlform/HTMLForm.php
languages/i18n/en.json
languages/i18n/qqq.json
resources/Resources.php

diff --combined autoload.php
@@@ -247,6 -247,7 +247,6 @@@ $wgAutoloadLocalClasses = 
        'CheckStorage' => __DIR__ . '/maintenance/storage/checkStorage.php',
        'CheckSyntax' => __DIR__ . '/maintenance/checkSyntax.php',
        'CheckUsernames' => __DIR__ . '/maintenance/checkUsernames.php',
 -      'ChronologyProtector' => __DIR__ . '/includes/libs/rdbms/ChronologyProtector.php',
        'ClassCollector' => __DIR__ . '/includes/utils/AutoloadGenerator.php',
        'CleanupAncientTables' => __DIR__ . '/maintenance/cleanupAncientTables.php',
        'CleanupBlocks' => __DIR__ . '/maintenance/cleanupBlocks.php',
        'FormSpecialPage' => __DIR__ . '/includes/specialpage/FormSpecialPage.php',
        'FormatJson' => __DIR__ . '/includes/json/FormatJson.php',
        'FormatMetadata' => __DIR__ . '/includes/media/FormatMetadata.php',
 +      'FormattedRCFeed' => __DIR__ . '/includes/rcfeed/FormattedRCFeed.php',
        'FormlessAction' => __DIR__ . '/includes/actions/FormlessAction.php',
        'GIFHandler' => __DIR__ . '/includes/media/GIF.php',
        'GIFMetadataExtractor' => __DIR__ . '/includes/media/GIFMetadataExtractor.php',
        'HTMLTextFieldWithButton' => __DIR__ . '/includes/htmlform/fields/HTMLTextFieldWithButton.php',
        'HTMLTitleTextField' => __DIR__ . '/includes/htmlform/fields/HTMLTitleTextField.php',
        'HTMLUserTextField' => __DIR__ . '/includes/htmlform/fields/HTMLUserTextField.php',
+       'HTMLUsersMultiselectField' => __DIR__ . '/includes/htmlform/fields/HTMLUsersMultiselectField.php',
        'HTTPFileStreamer' => __DIR__ . '/includes/libs/filebackend/HTTPFileStreamer.php',
        'HWLDFWordAccumulator' => __DIR__ . '/includes/diff/DairikiDiff.php',
        'HashBagOStuff' => __DIR__ . '/includes/libs/objectcache/HashBagOStuff.php',
        'MaintenanceFormatInstallDoc' => __DIR__ . '/maintenance/formatInstallDoc.php',
        'MakeTestEdits' => __DIR__ . '/maintenance/makeTestEdits.php',
        'MalformedTitleException' => __DIR__ . '/includes/title/MalformedTitleException.php',
 +      'ManageJobs' => __DIR__ . '/maintenance/manageJobs.php',
        'ManualLogEntry' => __DIR__ . '/includes/logging/LogEntry.php',
        'MapCacheLRU' => __DIR__ . '/includes/libs/MapCacheLRU.php',
        'MappedIterator' => __DIR__ . '/includes/libs/MappedIterator.php',
        'MediaWiki\\Widget\\DateTimeInputWidget' => __DIR__ . '/includes/widget/DateTimeInputWidget.php',
        'MediaWiki\\Widget\\NamespaceInputWidget' => __DIR__ . '/includes/widget/NamespaceInputWidget.php',
        'MediaWiki\\Widget\\SearchInputWidget' => __DIR__ . '/includes/widget/SearchInputWidget.php',
 +      'MediaWiki\\Widget\\Search\\BasicSearchResultSetWidget' => __DIR__ . '/includes/widget/search/BasicSearchResultSetWidget.php',
 +      'MediaWiki\\Widget\\Search\\DidYouMeanWidget' => __DIR__ . '/includes/widget/search/DidYouMeanWidget.php',
        'MediaWiki\\Widget\\Search\\FullSearchResultWidget' => __DIR__ . '/includes/widget/search/FullSearchResultWidget.php',
 +      'MediaWiki\\Widget\\Search\\InterwikiSearchResultSetWidget' => __DIR__ . '/includes/widget/search/InterwikiSearchResultSetWidget.php',
 +      'MediaWiki\\Widget\\Search\\SearchFormWidget' => __DIR__ . '/includes/widget/search/SearchFormWidget.php',
        'MediaWiki\\Widget\\Search\\SearchResultWidget' => __DIR__ . '/includes/widget/search/SearchResultWidget.php',
        'MediaWiki\\Widget\\Search\\SimpleSearchResultWidget' => __DIR__ . '/includes/widget/search/SimpleSearchResultWidget.php',
        'MediaWiki\\Widget\\TitleInputWidget' => __DIR__ . '/includes/widget/TitleInputWidget.php',
        'MediaWiki\\Widget\\UserInputWidget' => __DIR__ . '/includes/widget/UserInputWidget.php',
+       'MediaWiki\\Widget\\UsersMultiselectWidget' => __DIR__ . '/includes/widget/UsersMultiselectWidget.php',
        'MemCachedClientforWiki' => __DIR__ . '/includes/compat/MemcachedClientCompat.php',
        'MemcLockManager' => __DIR__ . '/includes/libs/lockmanager/MemcLockManager.php',
        'MemcachedBagOStuff' => __DIR__ . '/includes/libs/objectcache/MemcachedBagOStuff.php',
        'RCCacheEntry' => __DIR__ . '/includes/changes/RCCacheEntry.php',
        'RCCacheEntryFactory' => __DIR__ . '/includes/changes/RCCacheEntryFactory.php',
        'RCDatabaseLogEntry' => __DIR__ . '/includes/logging/LogEntry.php',
 +      'RCFeed' => __DIR__ . '/includes/rcfeed/RCFeed.php',
        'RCFeedEngine' => __DIR__ . '/includes/rcfeed/RCFeedEngine.php',
        'RCFeedFormatter' => __DIR__ . '/includes/rcfeed/RCFeedFormatter.php',
        'RESTBagOStuff' => __DIR__ . '/includes/libs/objectcache/RESTBagOStuff.php',
        'TitlePrefixSearch' => __DIR__ . '/includes/PrefixSearch.php',
        'TitleValue' => __DIR__ . '/includes/title/TitleValue.php',
        'TrackBlobs' => __DIR__ . '/maintenance/storage/trackBlobs.php',
 +      'TrackingCategories' => __DIR__ . '/includes/TrackingCategories.php',
        'TraditionalImageGallery' => __DIR__ . '/includes/gallery/TraditionalImageGallery.php',
 -      'TransactionProfiler' => __DIR__ . '/includes/libs/rdbms/TransactionProfiler.php',
        'TransformParameterError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
        'TransformTooBigImageAreaError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
        'TransformationalImageHandler' => __DIR__ . '/includes/media/TransformationalImageHandler.php',
        'UserBlockedError' => __DIR__ . '/includes/exception/UserBlockedError.php',
        'UserCache' => __DIR__ . '/includes/cache/UserCache.php',
        'UserDupes' => __DIR__ . '/maintenance/userDupes.inc',
 +      'UserGroupMembership' => __DIR__ . '/includes/user/UserGroupMembership.php',
        'UserMailer' => __DIR__ . '/includes/mail/UserMailer.php',
        'UserNamePrefixSearch' => __DIR__ . '/includes/user/UserNamePrefixSearch.php',
        'UserNotLoggedIn' => __DIR__ . '/includes/exception/UserNotLoggedIn.php',
        'ViewCLI' => __DIR__ . '/maintenance/view.php',
        'VirtualRESTService' => __DIR__ . '/includes/libs/virtualrest/VirtualRESTService.php',
        'VirtualRESTServiceClient' => __DIR__ . '/includes/libs/virtualrest/VirtualRESTServiceClient.php',
 +      'WANCacheReapUpdate' => __DIR__ . '/includes/deferred/WANCacheReapUpdate.php',
        'WANObjectCache' => __DIR__ . '/includes/libs/objectcache/WANObjectCache.php',
 +      'WANObjectCacheReaper' => __DIR__ . '/includes/libs/objectcache/WANObjectCacheReaper.php',
        'WantedCategoriesPage' => __DIR__ . '/includes/specials/SpecialWantedcategories.php',
        'WantedFilesPage' => __DIR__ . '/includes/specials/SpecialWantedfiles.php',
        'WantedPagesPage' => __DIR__ . '/includes/specials/SpecialWantedpages.php',
        'WikiRevision' => __DIR__ . '/includes/import/WikiRevision.php',
        'WikiStatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
        'WikiTextStructure' => __DIR__ . '/includes/content/WikiTextStructure.php',
 +      'Wikimedia\\Rdbms\\ChronologyProtector' => __DIR__ . '/includes/libs/rdbms/ChronologyProtector.php',
        'Wikimedia\\Rdbms\\ConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/ConnectionManager.php',
        'Wikimedia\\Rdbms\\SessionConsistentConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php',
 +      'Wikimedia\\Rdbms\\TransactionProfiler' => __DIR__ . '/includes/libs/rdbms/TransactionProfiler.php',
        'WikitextContent' => __DIR__ . '/includes/content/WikitextContent.php',
        'WikitextContentHandler' => __DIR__ . '/includes/content/WikitextContentHandler.php',
        'WinCacheBagOStuff' => __DIR__ . '/includes/libs/objectcache/WinCacheBagOStuff.php',
@@@ -165,6 -165,7 +165,7 @@@ class HTMLForm extends ContextSource 
                'url' => 'HTMLTextField',
                'title' => 'HTMLTitleTextField',
                'user' => 'HTMLUserTextField',
+               'usersmultiselect' => 'HTMLUsersMultiselectField',
        ];
  
        public $mFieldData;
                if ( $this->mName ) {
                        $attribs['name'] = $this->mName;
                }
 +              if ( $this->needsJSForHtml5FormValidation() ) {
 +                      $attribs['novalidate'] = true;
 +              }
                return $attribs;
        }
  
        protected function getMessage( $value ) {
                return Message::newFromSpecifier( $value )->setContext( $this );
        }
 +
 +      /**
 +       * Whether this form, with its current fields, requires the user agent to have JavaScript enabled
 +       * for the client-side HTML5 form validation to work correctly. If this function returns true, a
 +       * 'novalidate' attribute will be added on the `<form>` element. It will be removed if the user
 +       * agent has JavaScript support, in htmlform.js.
 +       *
 +       * @return boolean
 +       * @since 1.29
 +       */
 +      public function needsJSForHtml5FormValidation() {
 +              foreach ( $this->mFlatFields as $fieldname => $field ) {
 +                      if ( $field->needsJSForHtml5FormValidation() ) {
 +                              return true;
 +                      }
 +              }
 +              return false;
 +      }
  }
diff --combined languages/i18n/en.json
        "searcharticle": "Go",
        "history": "Page history",
        "history_short": "History",
 +      "history_small": "history",
        "updatedmarker": "updated since my last visit",
        "printableversion": "Printable version",
        "permalink": "Permanent link",
        "saveprefs": "Save",
        "restoreprefs": "Restore all default settings (in all sections)",
        "prefs-editing": "Editing",
 -      "rows": "Rows:",
 -      "columns": "Columns:",
        "searchresultshead": "Search",
        "stub-threshold": "Threshold for stub link formatting ($1):",
        "stub-threshold-sample-link": "sample",
        "username": "{{GENDER:$1|Username}}:",
        "prefs-memberingroups": "{{GENDER:$2|Member}} of {{PLURAL:$1|group|groups}}:",
        "prefs-memberingroups-type": "$1",
 +      "group-membership-link-with-expiry": "$1 (until $2)",
        "prefs-registration": "Registration time:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Real name:",
        "editusergroup": "Load user groups",
        "editinguser": "Changing user rights of {{GENDER:$1|user}} <strong>[[User:$1|$1]]</strong> $2",
        "viewinguserrights": "Viewing user rights of {{GENDER:$1|user}} <strong>[[User:$1|$1]]</strong> $2",
 -      "userrights-editusergroup": "Edit user groups",
 -      "userrights-viewusergroup": "View user groups",
 +      "userrights-editusergroup": "Edit {{GENDER:$1|user}} groups",
 +      "userrights-viewusergroup": "View {{GENDER:$1|user}} groups",
        "saveusergroups": "Save {{GENDER:$1|user}} groups",
        "userrights-groupsmember": "Member of:",
        "userrights-groupsmember-auto": "Implicit member of:",
        "userrights-changeable-col": "Groups you can change",
        "userrights-unchangeable-col": "Groups you cannot change",
        "userrights-irreversible-marker": "$1*",
 +      "userrights-expiry-current": "Expires $1",
 +      "userrights-expiry-none": "Does not expire",
 +      "userrights-expiry": "Expires:",
 +      "userrights-expiry-existing": "Existing expiration time: $3, $2",
 +      "userrights-expiry-othertime": "Other time:",
 +      "userrights-expiry-options": "1 day:1 day,1 week:1 week,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year",
 +      "userrights-invalid-expiry": "The expiry time for group \"$1\" is invalid.",
 +      "userrights-expiry-in-past": "The expiry time for group \"$1\" is in the past.",
        "userrights-conflict": "Conflict of user rights changes! Please review and confirm your changes.",
        "group": "Group:",
        "group-user": "Users",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Show",
        "rcfilters-activefilters": "Active filters",
 +      "rcfilters-restore-default-filters": "Restore default filters",
 +      "rcfilters-clear-all-filters": "Clear all filters",
        "rcfilters-search-placeholder": "Filter recent changes (browse or start typing)",
        "rcfilters-invalid-filter": "Invalid filter",
 +      "rcfilters-empty-filter": "No active filters. All contributions are shown.",
        "rcfilters-filterlist-title": "Filters",
        "rcfilters-filterlist-noresults": "No filters found",
 +      "rcfilters-filtergroup-registration": "User registration",
 +      "rcfilters-filter-registered-label": "Registered",
 +      "rcfilters-filter-registered-description": "Logged-in editors.",
 +      "rcfilters-filter-unregistered-label": "Unregistered",
 +      "rcfilters-filter-unregistered-description": " Editors who aren’t logged in.",
        "rcfilters-filtergroup-authorship": "Edit authorship",
        "rcfilters-filter-editsbyself-label": "Your own edits",
        "rcfilters-filter-editsbyself-description": "Edits by you.",
        "rcfilters-filter-editsbyother-label": "Edits by others",
 -      "rcfilters-filter-editsbyother-description": "Edits created by other users (not you.)",
 -      "rcfilters-filtergroup-userExpLevel": "User experience level",
 +      "rcfilters-filter-editsbyother-description": "Edits created by other users (not you).",
 +      "rcfilters-filtergroup-userExpLevel": "Experience level (for registered users only)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Newcomers",
 -      "rcfilters-filter-userExpLevel-newcomer-description": "Very new editors: fewer than 10 edits and 4 days of activity.",
 +      "rcfilters-filter-userExpLevel-newcomer-description": "Fewer than 10 edits and 4 days of activity.",
        "rcfilters-filter-userExpLevel-learner-label": "Learners",
 -      "rcfilters-filter-userExpLevel-learner-description": "More days of activity and edits than 'Newcomers' but fewer than 'Experienced users.'",
 +      "rcfilters-filter-userExpLevel-learner-description": "More days of activity and edits than \"Newcomers\" but fewer than \"Experienced users\".",
        "rcfilters-filter-userExpLevel-experienced-label": "Experienced users",
        "rcfilters-filter-userExpLevel-experienced-description": "More than 30 days of activity and 500 edits.",
 +      "rcfilters-filtergroup-automated": "Automated contributions",
 +      "rcfilters-filter-bots-label": "Bot",
 +      "rcfilters-filter-bots-description": "Edits made by automated tools.",
 +      "rcfilters-filter-humans-label": "Human (not bot)",
 +      "rcfilters-filter-humans-description": "Edits made by human editors.",
 +      "rcfilters-filtergroup-significance": "Significance",
 +      "rcfilters-filter-minor-label": "Minor edits",
 +      "rcfilters-filter-minor-description": "Edits the author labeled as minor.",
 +      "rcfilters-filter-major-label": "Non-minor edits",
 +      "rcfilters-filter-major-description": "Edits not labeled as minor.",
 +      "rcfilters-filtergroup-changetype": "Type of change",
 +      "rcfilters-filter-pageedits-label": "Page edits",
 +      "rcfilters-filter-pageedits-description": "Edits to wiki content, discussions, category descriptions....",
 +      "rcfilters-filter-newpages-label": "Page creations",
 +      "rcfilters-filter-newpages-description": "Edits that make new pages.",
 +      "rcfilters-filter-categorization-label": "Category changes",
 +      "rcfilters-filter-categorization-description": "Records of pages being added or removed from categories.",
 +      "rcfilters-filter-logactions-label": "Logged actions",
 +      "rcfilters-filter-logactions-description": "Administrative actions, account creations, page deletions, uploads....",
        "rcnotefrom": "Below {{PLURAL:$5|is the change|are the changes}} since <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
        "rclistfrom": "Show new changes starting from $2, $3",
        "rcshowhideminor": "$1 minor edits",
        "uncategorizedimages-summary": "",
        "uncategorizedtemplates": "Uncategorized templates",
        "uncategorizedtemplates-summary": "",
 +      "uncategorized-categories-exceptionlist": " # Contains a list of categories, which shouldn't be mentioned on Special:UncategorizedCategories. One per line, starting with \"*\". Lines starting with another character (including whitespaces) are ignored. Use \"#\" for comments.",
        "unusedcategories": "Unused categories",
        "unusedcategories-summary": "",
        "unusedimages": "Unused files",
        "apisandbox-sending-request": "Sending API request...",
        "apisandbox-loading-results": "Receiving API results...",
        "apisandbox-results-error": "An error occurred while loading the API query response: $1.",
 -      "apisandbox-request-params-json": "JSON parameters:",
 +      "apisandbox-request-selectformat-label": "Show request data as:",
 +      "apisandbox-request-format-url-label": "URL query string",
        "apisandbox-request-url-label": "Request URL:",
 +      "apisandbox-request-format-json-label": "JSON",
 +      "apisandbox-request-json-label": "Request JSON:",
        "apisandbox-request-time": "Request time: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Correct token and resubmit",
        "apisandbox-results-fixtoken-fail": "Failed to fetch \"$1\" token.",
        "emailccsubject": "Copy of your message to $1: $2",
        "emailsent": "Email sent",
        "emailsenttext": "Your email message has been sent.",
 -      "emailuserfooter": "This email was {{GENDER:$1|sent}} by $1 to {{GENDER:$2|$2}} by the \"{{int:emailuser}}\" function at {{SITENAME}}. {{GENDER:$2|Your}} email will be sent directly to the {{GENDER:$1|original sender}}, revealing {{GENDER:$2|your}} email address to {{GENDER:$1|them}}.",
 +      "emailuserfooter": "This email was {{GENDER:$1|sent}} by $1 to {{GENDER:$2|$2}} by the \"{{int:emailuser}}\" function at {{SITENAME}}. If {{GENDER:$2|you}} reply to this email, {{GENDER:$2|your}} email will be sent directly to the {{GENDER:$1|original sender}}, revealing {{GENDER:$2|your}} email address to {{GENDER:$1|them}}.",
        "usermessage-summary": "Leaving system message.",
        "usermessage-editor": "System messenger",
        "usermessage-template": "MediaWiki:UserMessage",
        "newuserlog-autocreate-entry": "Account created automatically",
        "rightslogentry": "changed group membership for $1 from $2 to $3",
        "rightslogentry-autopromote": "was automatically promoted from $2 to $3",
 +      "rightslogentry-temporary-group": "$1 (temporary, until $2)",
        "feedback-adding": "Adding feedback to page...",
        "feedback-back": "Back",
        "feedback-bugcheck": "Great! Just check that it is not already one of the [$1 known bugs].",
        "feedback-useragent": "User agent:",
        "searchsuggest-search": "Search {{SITENAME}}",
        "searchsuggest-containing": "containing...",
 -      "api-error-autoblocked": "Your IP address has been blocked automatically, because it was used by a blocked user.",
 -      "api-error-badaccess-groups": "You are not permitted to upload files to this wiki.",
        "api-error-badtoken": "Internal error: Bad token.",
 -      "api-error-blocked": "You have been blocked from editing.",
 -      "api-error-copyuploaddisabled": "Uploading by URL is disabled on this server.",
 -      "api-error-duplicate": "There {{PLURAL:$1|is another file|are some other files}} already on the site with the same content.",
 -      "api-error-duplicate-archive": "There {{PLURAL:$1|was another file|were some other files}} already on the site with the same content, but {{PLURAL:$1|it was|they were}} deleted.",
 -      "api-error-empty-file": "The file you submitted was empty.",
        "api-error-emptypage": "Creating new, empty pages is not allowed.",
 -      "api-error-fetchfileerror": "Internal error: Something went wrong while fetching the file.",
 -      "api-error-fileexists-forbidden": "A file with name \"$1\" already exists, and cannot be overwritten.",
 -      "api-error-fileexists-shared-forbidden": "A file with name \"$1\" already exists in the shared file repository, and cannot be overwritten.",
 -      "api-error-file-too-large": "The file you submitted was too large.",
 -      "api-error-filename-tooshort": "The filename is too short.",
 -      "api-error-filetype-banned": "This type of file is banned.",
 -      "api-error-filetype-banned-type": "$1 {{PLURAL:$4|is not a permitted file type|are not permitted file types}}. Permitted {{PLURAL:$3|file type is|file types are}} $2.",
 -      "api-error-filetype-missing": "The filename is missing an extension.",
 -      "api-error-hookaborted": "The modification you tried to make was aborted by an extension.",
 -      "api-error-http": "Internal error: Unable to connect to server.",
 -      "api-error-illegal-filename": "The filename is not allowed.",
 -      "api-error-internal-error": "Internal error: Something went wrong with processing your upload on the wiki.",
 -      "api-error-invalid-file-key": "Internal error: File was not found in temporary storage.",
 -      "api-error-missingparam": "Internal error: Missing parameters on request.",
 -      "api-error-missingresult": "Internal error: Could not determine if the copy succeeded.",
 -      "api-error-mustbeloggedin": "You must be logged in to upload files.",
 -      "api-error-mustbeposted": "Internal error: Request requires HTTP POST.",
 -      "api-error-noimageinfo": "The upload succeeded, but the server did not give us any information about the file.",
 -      "api-error-nomodule": "Internal error: No upload module set.",
 -      "api-error-ok-but-empty": "Internal error: No response from server.",
 -      "api-error-overwrite": "Overwriting an existing file is not allowed.",
 -      "api-error-ratelimited": "You're trying to upload more files in a short space of time than this wiki allows.\nPlease try again in a few minutes.",
 -      "api-error-stashfailed": "Internal error: Server failed to store temporary file.",
        "api-error-publishfailed": "Internal error: Server failed to publish temporary file.",
 -      "api-error-stasherror": "There was an error while uploading the file to stash.",
 -      "api-error-stashedfilenotfound": "The stashed file was not found when attempting to upload it from the stash.",
 -      "api-error-stashpathinvalid": "The path at which the stashed file should have been found was invalid.",
 -      "api-error-stashfilestorage": "There was an error while storing the file in the stash.",
 -      "api-error-stashzerolength": "The server could not stash the file, because it had zero length.",
 -      "api-error-stashnotloggedin": "You must be logged in to save files in the upload stash.",
 -      "api-error-stashwrongowner": "The file you were attempting to access in the stash does not belong to you.",
 -      "api-error-stashnosuchfilekey": "The file key you were attempting to access in the stash does not exist.",
 -      "api-error-timeout": "The server did not respond within the expected time.",
 -      "api-error-unclassified": "An unknown error occurred.",
 -      "api-error-unknown-code": "Unknown error: \"$1\".",
 -      "api-error-unknown-error": "Internal error: Something went wrong when trying to upload your file.",
 +      "api-error-stashfailed": "Internal error: Server failed to store temporary file.",
        "api-error-unknown-warning": "Unknown warning: \"$1\".",
        "api-error-unknownerror": "Unknown error: \"$1\".",
 -      "api-error-uploaddisabled": "Uploading is disabled on this wiki.",
 -      "api-error-verification-error": "This file might be corrupt, or have the wrong extension.",
 -      "api-error-was-deleted": "A file of this name has been previously uploaded and subsequently deleted.",
        "duration-seconds": "$1 {{PLURAL:$1|second|seconds}}",
        "duration-minutes": "$1 {{PLURAL:$1|minute|minutes}}",
        "duration-hours": "$1 {{PLURAL:$1|hour|hours}}",
        "mw-widgets-titleinput-description-new-page": "page does not exist yet",
        "mw-widgets-titleinput-description-redirect": "redirect to $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Add a category...",
+       "mw-widgets-usersmultiselect-placeholder": "Add more...",
        "sessionmanager-tie": "Cannot combine multiple request authentication types: $1.",
        "sessionprovider-generic": "$1 sessions",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "cookie-based sessions",
        "usercssispublic": "Please note: CSS subpages should not contain confidential data as they are viewable by other users.",
        "restrictionsfield-badip": "Invalid IP address or range: $1",
        "restrictionsfield-label": "Allowed IP ranges:",
 -      "restrictionsfield-help": "One IP address or CIDR range per line. To enable everything, use<br><code>0.0.0.0/0</code><br><code>::/0</code>",
 +      "restrictionsfield-help": "One IP address or CIDR range per line. To enable everything, use:<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "revision $1",
        "pageid": "page ID $1"
  }
diff --combined languages/i18n/qqq.json
                        "Ата",
                        "Matěj Suchánek",
                        "Chaduvari",
 -                      "MarcoAurelio"
 +                      "MarcoAurelio",
 +                      "Joao Xavier",
 +                      "Winstonyin"
                ]
        },
        "sidebar": "{{notranslate}}",
        "searcharticle": "Button description in the search menu displayed on every page. The \"Search\" button is {{msg-mw|Searchbutton}}.\n{{Identical|Go}}",
        "history": "{{Identical|Page history}}",
        "history_short": "Text used on the history tab.\n\n{{Identical|History}}",
 +      "history_small": "Uncapitalized version of {{msg-mw|History short}}.\n\n{{Identical|History}}",
        "updatedmarker": "Displayed in the page history (of a page you are [[Special:Watchlist|watching]]), when the page has been edited since the last time you visited it. This feature is used if [[mw:Manual:$wgShowUpdatedMarker|$wgShowUpdatedMarker]] is enabled.",
        "printableversion": "Display name for link in wiki menu that leads to a printable version of a content page. Example: see one but last menu item on [[Main Page]].\n\nSee also:\n* {{msg-mw|Printableversion}}\n* {{msg-mw|Accesskey-t-print}}\n* {{msg-mw|Tooltip-t-print}}\n{{Identical|Printable version}}",
        "permalink": "Display name for a permanent link to the current revision of a page. When the page is edited, permalink will still link to this revision. Example: Last menu link on [[{{MediaWiki:Mainpage}}]]\n\nSee also:\n* {{msg-mw|Permalink}}\n* {{msg-mw|Accesskey-t-permalink}}\n* {{msg-mw|Tooltip-t-permalink}}\n{{Identical|Permalink}}",
        "sig_tip": "This is the text that appears when you hover the mouse over the second key from the right on the edit toolbar.\n{{Identical|Signature with timestamp}}",
        "hr_tip": "This is the text that appears when you hover the mouse over the first button on the right on the edit toolbar.",
        "summary": "The Summary text beside the edit summary field\n\nSee also:\n* {{msg-mw|Subject}}\nSee also:\n* {{msg-mw|Accesskey-summary}}\n* {{msg-mw|Tooltip-summary}}\n{{Identical|Summary}}",
 -      "subject": "Used as label for input box in the EditPage page.\n\nSee also:\n* {{msg-mw|Summary}}\n{{Identical|Subject}}",
 +      "subject": "Used as label for the section title input box when adding a new section on a talk page.\n\nSee also:\n* {{msg-mw|Summary}}\n{{Identical|Subject}}",
        "minoredit": "Text above Save page button in editor\n\nSee also:\n* {{msg-mw|Minoredit}}\n* {{msg-mw|Accesskey-minoredit}}\n* {{msg-mw|Tooltip-minoredit}}",
        "watchthis": "Text of checkbox above {{msg-mw|Showpreview}} button in editor.\n\nSee also:\n* {{msg-mw|Watchthis}}\n* {{msg-mw|Accesskey-watch}}\n* {{msg-mw|Tooltip-watch}}\n{{Identical|Watch this page}}",
        "savearticle": "Text on the button to create a new page. It should be an action which is short and makes clear that the effect is immediate and public.\n\nSee also {{msg-mw|showpreview}} and {{msg-mw|showdiff}} for the other buttons, and {{msg-mw|savechanges}} for the label for the button when the page is being modified.\n\nSee also:\n* {{msg-mw|Accesskey-publish}}\n* {{msg-mw|Tooltip-publish}}\n{{Identical|Save page}}",
        "missingcommenttext": "This message is shown, when the textbox by a new-section is empty.",
        "missingcommentheader": "Edit summary that is shown if you enable \"Prompt me when entering a blank summary\" and add a new section without headline to a talk page.\n\n\"Subject\" is {{msg-mw|subject}}.\n\nSee also:\n* {{msg-mw|Missingsummary}}\n* {{msg-mw|Savearticle}}",
        "summary-preview": "Preview of the edit summary, shown under the edit summary itself.\nShould match: {{msg-mw|summary}}.",
 -      "subject-preview": "Should match {{msg-mw|subject}}",
 +      "subject-preview": "Used as label for preview of the section title when adding a new section on a talk page.\n\nShould match {{msg-mw|subject}}.\n\nSee also:\n* {{msg-mw|Summary-preview}}\n\n{{Identical|Subject}}",
        "previewerrortext": "When a user has the editing preference LivePreview enabled, clicked the Preview or Show Changes button in the edit page and the action did not succeed.",
        "blockedtitle": "Used as title displayed for blocked users. The corresponding message body is one of the following messages:\n* {{msg-mw|Blockedtext|notext=1}}\n* {{msg-mw|Autoblockedtext|notext=1}}\n* {{msg-mw|Systemblockedtext}}",
        "blockedtext": "Text displayed to blocked users.\n\n\"email this user\" should be consistent with {{msg-mw|Emailuser}}.\n\nParameters:\n* $1 - the blocking sysop (with a link to his/her userpage)\n* $2 - the reason for the block\n* $3 - the current IP address of the blocked user\n* $4 - (Unused) the blocking sysop's username (plain text, without the link)\n* $5 - the unique numeric identifier of the applied autoblock\n* $6 - the expiry of the block\n* $7 - the intended target of the block (what the blocking user specified in the blocking form)\n* $8 - the timestamp when the block started\nSee also:\n* {{msg-mw|Grouppage-sysop}}\n* {{msg-mw|Autoblockedtext}}\n* {{msg-mw|Systemblockedtext}}",
        "saveprefs": "Button for saving changes in the preferences page.\n\nSee also:\n* {{msg-mw|Saveprefs}}\n* {{msg-mw|Accesskey-preferences-save}}\n* {{msg-mw|Tooltip-preferences-save}}\n{{Identical|Save}}",
        "restoreprefs": "Used as link text in [[Special:Preferences]]. The link points to [[Special:Preferences/reset]] which shows the \"Restore all default settings\" form.\n\nAlso used as label for the Submit button in [[Special:Preferences/reset]].",
        "prefs-editing": "Title of a tab in [[Special:Preferences]].\nWhen changing this message, please also update {{msg-mw|vector-editwarning-warning}} which references to this message.\n{{Identical|Editing}}",
 -      "rows": "Used on [[Special:Preferences]], \"Editing\" section in the \"Size of editing window\" fieldset.\n{{Identical|Row}}",
 -      "columns": "Used on [[Special:Preferences]], \"Editing\" section in the \"Size of editing window\" fieldset.\n{{Identical|Column}}",
        "searchresultshead": "Replaced by {{msg-mw|prefs-searchoptions}}, though may still be used in some extensions. DEPRECATED.\n\n{{Identical|Search}}",
        "stub-threshold": "Used in [[Special:Preferences]], \"Advanced options\" section. The setting allows the user to select a threshold value, in bytes, from a predefined list of options. Any links that lead to pages smaller than the threshold (\"stub links\") will be styled differently.\n\nParameters:\n* $1: the text of {{msg-mw|stub-threshold-sample-link}}, styled as a stub link",
        "stub-threshold-sample-link": "Passed as a parameter to the {{msg-mw|stub-threshold}} message.\n{{Identical|Sample}}",
        "username": "Username field in [[Special:Preferences]]. $1 is the current user name for GENDER distinction (depends on sex setting).\n\n{{Identical|Username}}",
        "prefs-memberingroups": "This message is shown on [[Special:Preferences]], first tab.\n\nParameters:\n* $1 - number of user groups\n* $2 - the username for GENDER\nSee also:\n* {{msg-mw|Prefs-memberingroups-type}}",
        "prefs-memberingroups-type": "{{optional}}\nParameters:\n* $1 - list of group names\n* $2 - list of group member names. Label for these is {{msg-mw|Prefs-memberingroups}}",
 +      "group-membership-link-with-expiry": "Used as part of a list of user groups, to show the time and date when a user's membership of a group expires. That is, they are a member of that group \"until\" the specified date and time.\n\nParameters:\n* $1 - group name\n* $2 - time and date of expiry\n* $3 - date of expiry\n* $4 - time of expiry",
        "prefs-registration": "Used in [[Special:Preferences]].",
        "prefs-registration-date-time": "{{optional}}\nUsed in [[Special:Preferences]]. Parameters are:\n* $1 date and time of registration\n* $2 date of registration\n* $3 time of registration",
        "yourrealname": "Used in [[Special:Preferences]], first tab.\n{{Identical|Real name}}",
        "userrights-changeable-col": "Used when editing user groups in [[Special:Userrights]].\n\nThe message is the head of a column of group assignments.\n\nParameters:\n* $1 - (Optional) for PLURAL use, the number of items in the column following the message. Avoid PLURAL, if your language can do without.",
        "userrights-unchangeable-col": "Used when editing user groups in [[Special:Userrights]]. The message is the head of a column of group assignments.\n\nParameters:\n* $1 - (Optional) for PLURAL use, the number of items in the column following the message. Avoid PLURAL, if your language allows that.",
        "userrights-irreversible-marker": "{{optional}}\nParameters:\n* $1 - group member",
 +      "userrights-expiry-current": "Indicates when a user's membership of a user group expires.\n\nParameters:\n* $1 - time and date of expiry\n* $2 - date of expiry\n* $3 - time of expiry\n{{Identical|Expire}}",
 +      "userrights-expiry-none": "Indicates that a user's membership of a user group lasts indefinitely, and does not expire.",
 +      "userrights-expiry": "Used as a label for a form element which can be used to select an expiry date/time.\n{{Identical|Expire}}",
 +      "userrights-expiry-existing": "Shows the existing expiry time in the drop down menu underneath the individual user right on Special:UserRights.\n\nParameters:\n* $1 - Date and time of the existing expiry\n* $2 - date of the existing expiry\n* $3 - time of the existing expiry\n\nSee also:\n* {{msg-mw|protect-existing-expiry}}",
 +      "userrights-expiry-othertime": "{{Identical|Other time}}",
 +      "userrights-expiry-options": "{{doc-important|Be careful: '''1 translation:1 english''', so the first part is the translation and the second part should stay in English.}}\nOptions for the duration of the user group membership. Example: See e.g. [[MediaWiki:Userrights-expiry-options/nl]] if you still don't know how to do it.\n\nSee also {{msg-mw|protect-expiry-options}}.",
 +      "userrights-invalid-expiry": "Error message on [[Special:UserRights]].\n\nParameters:\n* $1 - group name",
 +      "userrights-expiry-in-past": "Error message on [[Special:UserRights]] when the user types an expiry date that has already passed.\n\nParameters:\n* $1 - group name",
        "userrights-conflict": "Shown on [[Special:UserRights]] if the target's rights have been changed since the form was loaded.",
        "group": "{{Identical|Group}}",
        "group-user": "{{doc-group|user}}\n{{Identical|User}}",
        "grant-group-private-information": "{{Related|Grant-group}}",
        "grant-group-other": "{{Related|Grant-group}}",
        "grant-blockusers": "Name for grant \"blockusers\".\n{{Related|Grant}}",
 -      "grant-createaccount": "Name for grant \"createaccount\".\n{{Related|Grant}}",
 +      "grant-createaccount": "Name for grant \"createaccount\".\n{{Related|Grant}}\n{{Identical|Create account}}",
        "grant-createeditmovepage": "Name for grant \"createeditmovepage\".\n{{Related|Grant}}",
        "grant-delete": "Name for grant \"delete\".\n{{Related|Grant}}",
        "grant-editinterface": "Name for grant \"editinterface\".\n\n\"JS\" stands for \"JavaScript\".\n{{Related|Grant}}",
        "recentchanges-legend-plusminus": "{{optional}}\nA plus/minus sign with a number for the legend.",
        "recentchanges-submit": "Label for submit button in [[Special:RecentChanges]]\n{{Identical|Show}}",
        "rcfilters-activefilters": "Title for the filters selection showing the active filters.",
 +      "rcfilters-restore-default-filters": "Label for the button that resets filters to defaults",
 +      "rcfilters-clear-all-filters": "Title for the button that clears all filters",
        "rcfilters-search-placeholder": "Placeholder for the filter search input.",
 -      "rcfilters-invalid-filter": "A label for an ivalid filter.",
 +      "rcfilters-invalid-filter": "A label for an invalid filter.",
 +      "rcfilters-empty-filter": "Placeholder for the filter list when no filters were chosen.",
        "rcfilters-filterlist-title": "Title for the filters list.\n{{Identical|Filter}}",
        "rcfilters-filterlist-noresults": "Message showing no results found for searching a filter.",
 +      "rcfilters-filtergroup-registration": "Title for the filter group for editor registration type.",
 +      "rcfilters-filter-registered-label": "Label for the filter for showing edits made by logged-in users.\n{{Identical|Registered}}",
 +      "rcfilters-filter-registered-description": "Description for the filter for showing edits made by logged-in users.",
 +      "rcfilters-filter-unregistered-label": "Label for the filter for showing edits made by logged-out users.",
 +      "rcfilters-filter-unregistered-description": " Description for the filter for showing edits made by logged-out users.",
        "rcfilters-filtergroup-authorship": "Title for the filter group for edit authorship. This filter group allows the user to choose between \"Your own edits\" and \"Edits by others\". More info: https://phabricator.wikimedia.org/T149859\n\n{{doc-important|This is another typical example of ambiguity in the English language. Only the documentation will reveal that this message means \"(filter by) authorship of these edits\", not \"edit the authorship\". That is, \"edit\" is a modifying noun, not a verb.}}",
        "rcfilters-filter-editsbyself-label": "Label for the filter for showing edits made by the current user.",
        "rcfilters-filter-editsbyself-description": "Description for the filter for showing edits made by the current user.",
        "rcfilters-filter-userExpLevel-learner-description": "Description for the filter for showing edits made by learning editors.",
        "rcfilters-filter-userExpLevel-experienced-label": "Label for the filter for showing edits made by experienced editors.",
        "rcfilters-filter-userExpLevel-experienced-description": "Description for the filter for showing edits made by experienced editors.",
 +      "rcfilters-filtergroup-automated": "Title for the filter group for editor automation type.",
 +      "rcfilters-filter-bots-label": "Label for the filter for showing edits made by automated tools.\n{{Identical|Bot}}",
 +      "rcfilters-filter-bots-description": "Description for the filter for showing edits made by automated tools.",
 +      "rcfilters-filter-humans-label": "Label for the filter for showing edits made by human editors.",
 +      "rcfilters-filter-humans-description": "Description for the filter for showing edits made by human editors.",
 +      "rcfilters-filtergroup-significance": "Title for the filter group for edit significance.\n{{Identical|Significance}}",
 +      "rcfilters-filter-minor-label": "Label for the filter for showing edits marked as minor.",
 +      "rcfilters-filter-minor-description": "Description for the filter for showing edits marked as minor.",
 +      "rcfilters-filter-major-label": "Label for the filter for showing edits not marked as minor.",
 +      "rcfilters-filter-major-description": " Description for the filter for showing edits not marked as minor.",
 +      "rcfilters-filtergroup-changetype": "Title for the filter group for edit type.",
 +      "rcfilters-filter-pageedits-label": "Label for the filter for showing edits to existing pages.",
 +      "rcfilters-filter-pageedits-description": "Description for the filter for showing edits to existing pages.",
 +      "rcfilters-filter-newpages-label": "Label for the filter for showing edits that create a page.",
 +      "rcfilters-filter-newpages-description": "Description for the filter for showing edits that create a page.",
 +      "rcfilters-filter-categorization-label": "Label for the filter for showing edits adding or removing pages to categories.",
 +      "rcfilters-filter-categorization-description": "Description for the filter for showing edits adding or removing pages to categories.",
 +      "rcfilters-filter-logactions-label": "Label for the filter for showing logged actions.",
 +      "rcfilters-filter-logactions-description": "Description for the filter for showing logged actions.",
        "rcnotefrom": "This message is displayed at [[Special:RecentChanges]] when viewing recentchanges from some specific time.\n\nThe corresponding message is {{msg-mw|Rclistfrom}}.\n\nParameters:\n* $1 - the maximum number of changes that are displayed\n* $2 - (Optional) a date and time\n* $3 - a date\n* $4 - a time\n* $5 - Number of changes are displayed, for use with PLURAL",
        "rclistfrom": "Used on [[Special:RecentChanges]]. Parameters:\n* $1 - (Currently not use) date and time. The date and the time adds to the rclistfrom description.\n* $2 - time. The time adds to the rclistfrom link description (with split of date and time).\n* $3 - date. The date adds to the rclistfrom link description (with split of date and time).\n\nThe corresponding message is {{msg-mw|Rcnotefrom}}.",
        "rcshowhideminor": "Option text in [[Special:RecentChanges]]. Parameters:\n* $1 - the \"show/hide\" command, with the text taken from either {{msg-mw|rcshowhideminor-show}} or {{msg-mw|rcshowhideminor-hide}}\n{{Identical|Minor edit}}",
        "upload-form-label-own-work-message-generic-foreign": "Message shown by default when a user affirms that they are allowed to upload a file to a remote wiki.",
        "upload-form-label-not-own-work-message-generic-foreign": "Message shown by default when a user cannot upload a file to a remote wiki.",
        "upload-form-label-not-own-work-local-generic-foreign": "Suggests uploading a file locally instead of to a remote wiki.",
 -      "backend-fail-stream": "Parameters:\n* $1 - a filename",
 -      "backend-fail-backup": "Parameters:\n* $1 - a filename",
 -      "backend-fail-notexists": "Parameters:\n* $1 - a filename",
 -      "backend-fail-hashes": "Definition of \"[[w:en:Hash_function|hashes]]\".",
 -      "backend-fail-notsame": "Parametreler:\n* $1 bir dosya ismi.",
 -      "backend-fail-invalidpath": "Parameters:\n* $1 - a storage path",
 -      "backend-fail-delete": "Parameters:\n* $1 - a file path",
 -      "backend-fail-describe": "Parameters:\n* $1 - a file path",
 -      "backend-fail-alreadyexists": "Parameters:\n* $1 - a filename",
 -      "backend-fail-store": "Parameters:\n* $1 - a filename\n* $2 - a storage path",
 -      "backend-fail-copy": "Parameters:\n* $1 - a file path\n* $2 - a file path",
 -      "backend-fail-move": "Parameters:\n* $1 - a file path\n* $2 - a file path",
 +      "backend-fail-stream": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
 +      "backend-fail-backup": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
 +      "backend-fail-notexists": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
 +      "backend-fail-hashes": "Definition of \"[[w:en:Hash_function|hashes]]\".\n{{Related|Backend-fail}}",
 +      "backend-fail-notsame": "Parameters:\n* $1 is a filename.\n{{Related|Backend-fail}}",
 +      "backend-fail-invalidpath": "Parameters:\n* $1 - a storage path\n{{Related|Backend-fail}}",
 +      "backend-fail-delete": "Parameters:\n* $1 - a file path\n{{Related|Backend-fail}}",
 +      "backend-fail-describe": "Parameters:\n* $1 - a file path\n{{Related|Backend-fail}}",
 +      "backend-fail-alreadyexists": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
 +      "backend-fail-store": "Parameters:\n* $1 - a filename\n* $2 - a storage path\n{{Related|Backend-fail}}",
 +      "backend-fail-copy": "Parameters:\n* $1 - a file path\n* $2 - a file path\n{{Related|Backend-fail}}",
 +      "backend-fail-move": "Parameters:\n* $1 - a file path\n* $2 - a file path\n{{Related|Backend-fail}}",
        "backend-fail-opentemp": "Used as error message.\n{{Related|Backend-fail}}",
        "backend-fail-writetemp": "Used as error message.\n{{Related|Backend-fail}}",
        "backend-fail-closetemp": "Used as error message.\n{{Related|Backend-fail}}",
        "backend-fail-read": "Used as error message. Parameters:\n* $1 - filename\n{{Related|Backend-fail}}",
 -      "backend-fail-create": "Parameters:\n* $1 - a filename",
 -      "backend-fail-maxsize": "Parameters:\n* $1 - destination storage path\n* $2 - max file size (in bytes)",
 -      "backend-fail-readonly": "A \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n\nParameters:\n* $1 - name\n* $2 - reason for being read-only",
 -      "backend-fail-synced": "Used as fatal error message.\n\nParameters:\n* $1 - file path\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
 -      "backend-fail-connect": "Used as fatal error message. Parameters:\n* $1 - backend name\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
 -      "backend-fail-internal": "Used as fatal error message. Parameters:\n* $1 - backend name\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
 -      "backend-fail-contenttype": "Used as fatal error message. Parameters:\n* $1 - a storage (file) path",
 -      "backend-fail-batchsize": "Error message when the limit of operations to be done at once in the file backend was reached.\nParameters:\n* $1 - the number of operations attempted at once in this case\n* $2 - the maximum number of operations that can be attempted at once\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
 -      "backend-fail-usable": "Parameters:\n* $1 - the file name, including the path, formatted for the storage backend used",
 +      "backend-fail-create": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
 +      "backend-fail-maxsize": "Parameters:\n* $1 - destination storage path\n* $2 - max file size (in bytes)\n{{Related|Backend-fail}}",
 +      "backend-fail-readonly": "A \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n\nParameters:\n* $1 - name\n* $2 - reason for being read-only\n{{Related|Backend-fail}}",
 +      "backend-fail-synced": "Used as fatal error message.\n\nParameters:\n* $1 - file path\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n{{Related|Backend-fail}}",
 +      "backend-fail-connect": "Used as fatal error message. Parameters:\n* $1 - backend name\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n{{Related|Backend-fail}}",
 +      "backend-fail-internal": "Used as fatal error message. Parameters:\n* $1 - backend name\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n{{Related|Backend-fail}}",
 +      "backend-fail-contenttype": "Used as fatal error message. Parameters:\n* $1 - a storage (file) path\n{{Related|Backend-fail}}",
 +      "backend-fail-batchsize": "Error message when the limit of operations to be done at once in the file backend was reached.\nParameters:\n* $1 - the number of operations attempted at once in this case\n* $2 - the maximum number of operations that can be attempted at once\nBoth parameters are PLURAL supported\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n{{Related|Backend-fail}}",
 +      "backend-fail-usable": "Parameters:\n* $1 - the file name, including the path, formatted for the storage backend used\n{{Related|Backend-fail}}",
        "filejournal-fail-dbconnect": "Parameters:\n* $1 is the name of the \"[[:wikipedia:Front and back ends|backend]]\" that the file journal logs changes for.",
        "filejournal-fail-dbquery": "Parameters:\n* $1 is the name of the \"[[:wikipedia:Front and back ends|backend]]\" that the file journal logs changes for.",
        "lockmanager-notlocked": "Parameters:\n* $1 is a resource path (e.g. \"mwstore://media-public/a/ab/file.jpg\").",
        "uncategorizedimages-summary": "{{notranslate}}\nused in [[Special:Uncategorizedimages]]. [[mw:Manual:Interface/Special pages summary|mw manual]].",
        "uncategorizedtemplates": "{{doc-special|UncategorizedTemplates}}",
        "uncategorizedtemplates-summary": "{{doc-specialpagesummary|uncategorizedtemplates}}",
 +      "uncategorized-categories-exceptionlist": "{{optional}}\nSystem message used as a list of exceptions for Special:UncategorizedCategories.",
        "unusedcategories": "{{doc-special|UnusedCategories}}",
        "unusedcategories-summary": "{{doc-specialpagesummary|unusedcategories}}",
        "unusedimages": "{{doc-special|UnusedImages}}",
        "apisandbox-sending-request": "JavaScript message displayed while the request is being sent.",
        "apisandbox-loading-results": "JavaScript message displayed while the response is being read.",
        "apisandbox-results-error": "Displayed as an error message from JavaScript when the request failed.\n\nParameters:\n* $1 - Error message",
 -      "apisandbox-request-params-json": "Label for text field display the request parameters as JSON.",
 -      "apisandbox-request-url-label": "Label for the text field displaying the URL used to make this request.",
 +      "apisandbox-request-selectformat-label": "Label for the format selector on the results page.",
 +      "apisandbox-request-format-url-label": "Label for the menu item to select URL format.\n\nSee also:\n* {{msg-mw|apisandbox-request-selectformat-label}}\n* {{msg-mw|apisandbox-request-url-label}}",
 +      "apisandbox-request-url-label": "Label for the text field displaying the URL used to make this request.\n\nSee also:\n* {{msg-mw|apisandbox-request-format-url-label}}",
 +      "apisandbox-request-format-json-label": "Label for the menu item to select JSON format.\n\nSee also:\n* {{msg-mw|apisandbox-request-selectformat-label}}\n* {{msg-mw|apisandbox-request-json-label}}",
 +      "apisandbox-request-json-label": "Label for text field display the request parameters as JSON.\n\nSee also:\n* {{msg-mw|apisandbox-request-format-json-label}}",
        "apisandbox-request-time": "Label and value for displaying the time taken by the request.\n\nParameters:\n* $1 - Time taken in milliseconds",
        "apisandbox-results-fixtoken": "JavaScript button label",
        "apisandbox-results-fixtoken-fail": "Displayed as an error message from JavaScript when a CSRF token could not be fetched.\n\nParameters:\n* $1 - Token type",
        "newuserlog-autocreate-entry": "This message is used in the [[:mw:Extension:Newuserlog|new user log]] to mark an account that was created by MediaWiki as part of a [[:mw:Extension:CentralAuth|CentralAuth]] global account.",
        "rightslogentry": "This message is displayed in the [[Special:Log/rights|User Rights Log]] when a bureaucrat changes the user groups for a user.\n\nParameters:\n* $1 - the username\n* $2 - list of user groups or {{msg-mw|Rightsnone}}\n* $3 - list of user groups or {{msg-mw|Rightsnone}}\n\nThe name of the bureaucrat who did this task appears before this message.\n\nSimilar to {{msg-mw|Gur-rightslog-entry}}",
        "rightslogentry-autopromote": "This message is displayed in the [[Special:Log/rights|User Rights Log]] when a user is automatically promoted to a user group.\n\nParameters:\n* $1 - (Unused)\n* $2 - a comma separated list of old user groups or {{msg-mw|Rightsnone}}\n* $3 - a comma separated list of new user groups",
 +      "rightslogentry-temporary-group": "This message is displayed in the [[Special:Log/rights|User Rights Log]] to show that a user group has been allocated temporarily.\n\nParameters:\n* $1 - group name\n* $2 - date and time of expiry\n* $3 - date of expiry\n* $4 - time of expiry",
        "feedback-adding": "Progress notice",
        "feedback-back": "Button to go back to the previous action in the feedback dialog.\n{{Identical|Back}}",
        "feedback-bugcheck": "Message that appears before the user submits a bug, reminding them to check for known bugs.\n\nParameters:\n* $1 - bug list page URL",
        "feedback-useragent": "A label denoting the user agent in the feedback that is posted to the feedback page.\n{{Identical|User agent}}",
        "searchsuggest-search": "Greyed out default text in the simple search box in the Vector skin. (It disappears and lets the user enter the requested search terms when the search box receives focus.)\n{{Identical|Search}}",
        "searchsuggest-containing": "Label used in the special item of the search suggestions list which gives the user an option to perform a full text search for the term.",
 -      "api-error-autoblocked": "API error message that can be used for client side localisation of API errors.\n\nCf. {{msg-mw|Autoblockedtext}}.",
 -      "api-error-badaccess-groups": "API error message that can be used for client side localisation of API errors.",
        "api-error-badtoken": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-blocked": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-copyuploaddisabled": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-duplicate": "API error message that can be used for client side localisation of API errors. Parameters:\n* $1 - a number of files",
 -      "api-error-duplicate-archive": "API error message that can be used for client side localisation of API errors. Parameters:\n* $1 - a number of files",
 -      "api-error-empty-file": "API error message that can be used for client side localisation of API errors.",
        "api-error-emptypage": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-fetchfileerror": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-fileexists-forbidden": "API error message that can be used for client side localisation of API errors.\n\nParameters:\n* $1 - filename\nSee also:\n* {{msg-mw|Api-error-fileexists-shared-forbidden}}",
 -      "api-error-fileexists-shared-forbidden": "API error message that can be used for client side localisation of API errors.\n\nParameters:\n* $1 - filename\nSee also:\n* {{msg-mw|Api-error-fileexists-forbidden}}",
 -      "api-error-file-too-large": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-filename-tooshort": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-filetype-banned": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-filetype-banned-type": "API error message that can be used for client side localisation of API errors.\n\n* $1 is the extension(s) of the file which cannot be uploaded\n* $2 is the list of file extensions that can be uploaded (Example: ''png, gif, jpg, jpeg, ogg, pdf, svg.'')\n* $3 is the number of allowed file formats (to be used for the PLURAL function)\n* $4 is the number of extensions that could not be uploaded (to be used for the PLURAL function)",
 -      "api-error-filetype-missing": "The word \"extension\" refers to the part behind the last dot in a file name, that by convention gives a hint about the kind of data format which a files contents are in.",
 -      "api-error-hookaborted": "The word \"extension\" here refers to a [[:mw:Manual:Extensions|MediaWiki Extension]] which extends the functionality of the basic wiki by adding something to its capabilities. \"… aborted by an extension\" implies that an operation could not be performed successfully or was not allowed to continue to its intended end.",
 -      "api-error-http": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-illegal-filename": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-internal-error": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-invalid-file-key": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-missingparam": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-missingresult": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-mustbeloggedin": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-mustbeposted": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-noimageinfo": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-nomodule": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-ok-but-empty": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-overwrite": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-ratelimited": "API error message that can be used for client side localisation of API errors.\n\nCf. {{msg-mw|Actionthrottledtext}}",
 -      "api-error-stashfailed": "API error message that can be used for client side localisation of API errors.",
        "api-error-publishfailed": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-stasherror": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-stashedfilenotfound": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-stashpathinvalid": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-stashfilestorage": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-stashzerolength": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-stashnotloggedin": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-stashwrongowner": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-stashnosuchfilekey": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-timeout": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-unclassified": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-unknown-code": "API error message that can be used for client side localisation of API errors.\n\nParameters:\n* $1 - may contain more error details\n{{Identical|Unknown error}}",
 -      "api-error-unknown-error": "API error message that can be used for client side localisation of API errors.",
 +      "api-error-stashfailed": "API error message that can be used for client side localisation of API errors.",
        "api-error-unknown-warning": "API error message that can be used for client side localisation of API errors. Parameters:\n* $1 is an unknown warning.",
        "api-error-unknownerror": "API error message that can be used for client side localisation of API errors.\n\nParameters:\n* $1 - an unknown error message\n{{Identical|Unknown error}}",
 -      "api-error-uploaddisabled": "API error message that can be used for client side localisation of API errors.",
 -      "api-error-verification-error": "The word \"extension\" refers to the part behind the last dot in a file name, that by convention gives a hint about the kind of data format which a files contents are in.",
 -      "api-error-was-deleted": "API error message that can be used for client side localisation of API errors.",
        "duration-seconds": "Used as duration. Parameters:\n* $1 - number of seconds\n{{Related|Duration}}\n{{Identical|Second}}",
        "duration-minutes": "Used as duration. Parameters:\n* $1 - number of minutes\n{{Related|Duration}}\n{{Identical|Minute}}",
        "duration-hours": "Used as duration. Parameters:\n* $1 - number of hours\n{{Related|Duration}}\n{{Identical|Hour}}",
        "mw-widgets-titleinput-description-new-page": "Description label for a new page in the title input widget.",
        "mw-widgets-titleinput-description-redirect": "Description label for a redirect in the title input widget.",
        "mw-widgets-categoryselector-add-category-placeholder": "Placeholder displayed in the category selector widget after the capsules of already added categories.",
+       "mw-widgets-usersmultiselect-placeholder": "Placeholder displayed in the input field, where new usernames are entered",
        "sessionmanager-tie": "Used as an error message when multiple session sources are tied in priority.\n\nParameters:\n* $1 - List of dession type descriptions, from messages like {{msg-mw|sessionprovider-mediawiki-session-cookiesessionprovider}}.",
        "sessionprovider-generic": "Used to create a generic session type description when one isn't provided via the proper message. Should be phrased to make sense when added to a message such as {{msg-mw|cannotloginnow-text}}.\n\nParameters:\n* $1 - PHP classname.",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "Description of the sessions provided by the CookieSessionProvider class, which use HTTP cookies. Should be phrased to make sense when added to a message such as {{msg-mw|cannotloginnow-text}}.",
diff --combined resources/Resources.php
@@@ -1060,6 -1060,7 +1060,6 @@@ return 
                        'resources/src/mediawiki/htmlform/autocomplete.js',
                        'resources/src/mediawiki/htmlform/autoinfuse.js',
                        'resources/src/mediawiki/htmlform/checkmatrix.js',
 -                      'resources/src/mediawiki/htmlform/datetime.js',
                        'resources/src/mediawiki/htmlform/cloner.js',
                        'resources/src/mediawiki/htmlform/hide-if.js',
                        'resources/src/mediawiki/htmlform/multiselect.js',
                        'upload-form-label-infoform-description-tooltip',
                        'upload-form-label-usage-title',
                        'upload-form-label-usage-filename',
 -                      'api-error-unknownerror',
 +                      'action-upload',
 +                      'apierror-mustbeloggedin',
 +                      'badaccess-groups',
 +                      'apierror-unknownerror',
                        'api-error-unknown-warning',
 -                      'api-error-autoblocked',
 -                      'api-error-blocked',
 -                      'api-error-badaccess-groups',
 -                      'api-error-badtoken',
 -                      'api-error-copyuploaddisabled',
 -                      'api-error-duplicate',
 -                      'api-error-duplicate-archive',
 -                      'api-error-empty-file',
 -                      'api-error-emptypage',
 -                      'api-error-fetchfileerror',
 -                      'api-error-fileexists-forbidden',
 -                      'api-error-fileexists-shared-forbidden',
 -                      'api-error-file-too-large',
 -                      'api-error-filename-tooshort',
 -                      'api-error-filetype-banned',
 -                      'api-error-filetype-banned-type',
 -                      'api-error-filetype-missing',
 -                      'api-error-hookaborted',
 -                      'api-error-http',
 -                      'api-error-illegal-filename',
 -                      'api-error-internal-error',
 -                      'api-error-invalid-file-key',
 -                      'api-error-missingparam',
 -                      'api-error-missingresult',
 -                      'api-error-mustbeloggedin',
 -                      'api-error-mustbeposted',
 -                      'api-error-noimageinfo',
 -                      'api-error-nomodule',
 -                      'api-error-ok-but-empty',
 -                      'api-error-overwrite',
 -                      'api-error-stashfailed',
 -                      'api-error-publishfailed',
 -                      'api-error-stasherror',
 -                      'api-error-stashedfilenotfound',
 -                      'api-error-stashpathinvalid',
 -                      'api-error-stashfilestorage',
 -                      'api-error-stashzerolength',
 -                      'api-error-stashnotloggedin',
 -                      'api-error-stashwrongowner',
 -                      'api-error-stashnosuchfilekey',
 -                      'api-error-timeout',
 -                      'api-error-unclassified',
 -                      'api-error-unknown-code',
 -                      'api-error-unknown-error',
 -                      'api-error-uploaddisabled',
 -                      'api-error-verification-error',
 -                      'api-error-was-deleted',
                        'fileexists',
                        'filepageexists',
 +                      'file-exists-duplicate',
 +                      'file-deleted-duplicate',
                        'filename-bad-prefix',
                        'filename-thumb-name',
 +                      'filewasdeleted',
                        'badfilename',
                        'protectedpagetext',
                ],
                        'resources/src/mediawiki.rcfilters/mw.rcfilters.init.js',
                ],
                'styles' => [
 -                      'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterGroupWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FiltersListWidget.less',
                ],
                'messages' => [
                        'rcfilters-activefilters',
 +                      'rcfilters-restore-default-filters',
 +                      'rcfilters-clear-all-filters',
                        'rcfilters-search-placeholder',
                        'rcfilters-invalid-filter',
 +                      'rcfilters-empty-filter',
                        'rcfilters-filterlist-title',
                        'rcfilters-filterlist-noresults',
 +                      'rcfilters-filtergroup-registration',
 +                      'rcfilters-filter-registered-label',
 +                      'rcfilters-filter-registered-description',
 +                      'rcfilters-filter-unregistered-label',
 +                      'rcfilters-filter-unregistered-description',
                        'rcfilters-filtergroup-authorship',
                        'rcfilters-filter-editsbyself-label',
                        'rcfilters-filter-editsbyself-description',
                        'rcfilters-filter-userExpLevel-learner-description',
                        'rcfilters-filter-userExpLevel-experienced-label',
                        'rcfilters-filter-userExpLevel-experienced-description',
 +                      'rcfilters-filtergroup-automated',
 +                      'rcfilters-filter-bots-label',
 +                      'rcfilters-filter-bots-description',
 +                      'rcfilters-filter-humans-label',
 +                      'rcfilters-filter-humans-description',
 +                      'rcfilters-filtergroup-significance',
 +                      'rcfilters-filter-minor-label',
 +                      'rcfilters-filter-minor-description',
 +                      'rcfilters-filter-major-label',
 +                      'rcfilters-filter-major-description',
 +                      'rcfilters-filtergroup-changetype',
 +                      'rcfilters-filter-pageedits-label',
 +                      'rcfilters-filter-pageedits-description',
 +                      'rcfilters-filter-newpages-label',
 +                      'rcfilters-filter-newpages-description',
 +                      'rcfilters-filter-categorization-label',
 +                      'rcfilters-filter-categorization-description',
 +                      'rcfilters-filter-logactions-label',
 +                      'rcfilters-filter-logactions-description',
                ],
                'dependencies' => [
                        'oojs-ui',
                        'mediawiki.Uri',
 +                      'oojs-ui.styles.icons-moderation'
                ],
        ],
        'mediawiki.special' => [
                        'apisandbox-sending-request',
                        'apisandbox-loading-results',
                        'apisandbox-results-error',
 -                      'apisandbox-request-params-json',
 +                      'apisandbox-request-selectformat-label',
 +                      'apisandbox-request-format-url-label',
                        'apisandbox-request-url-label',
 +                      'apisandbox-request-format-json-label',
 +                      'apisandbox-request-json-label',
                        'apisandbox-request-time',
                        'apisandbox-results-fixtoken',
                        'apisandbox-results-fixtoken-fail',
                ],
        ],
        'mediawiki.special.userrights' => [
 +              'styles' => 'resources/src/mediawiki.special/mediawiki.special.userrights.css',
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.userrights.js',
                'dependencies' => [
                        'mediawiki.notification.convertmessagebox',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
+       'mediawiki.widgets.UsersMultiselectWidget' => [
+               'scripts' => [
+                       'resources/src/mediawiki.widgets/mw.widgets.UsersMultiselectWidget.js',
+               ],
+               'dependencies' => [
+                       'oojs-ui-widgets',
+               ],
+               'targets' => [ 'desktop', 'mobile' ],
+       ],
        'mediawiki.widgets.SearchInputWidget' => [
                'scripts' => [
                        'resources/src/mediawiki.widgets/mw.widgets.SearchInputWidget.js',