Merge "Show a warning in edit preview when a template loop is detected"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 11 Sep 2017 18:26:11 +0000 (18:26 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 11 Sep 2017 18:26:11 +0000 (18:26 +0000)
1  2 
includes/parser/Parser.php
languages/i18n/en.json
languages/i18n/qqq.json

@@@ -227,7 -227,7 +227,7 @@@ class Parser 
         * @var string Deprecated accessor for the strip marker prefix.
         * @deprecated since 1.26; use Parser::MARKER_PREFIX instead.
         */
 -      public $mUniqPrefix = Parser::MARKER_PREFIX;
 +      public $mUniqPrefix = self::MARKER_PREFIX;
  
        /**
         * @var array Array with the language name of each language link (i.e. the
                        // Since we're not really outputting HTML, decode the entities and
                        // then re-encode the things that need hiding inside HTML comments.
                        $limitReport = htmlspecialchars_decode( $limitReport );
 -                      Hooks::run( 'ParserLimitReport', [ $this, &$limitReport ] );
 +                      // Run deprecated hook
 +                      Hooks::run( 'ParserLimitReport', [ $this, &$limitReport ], '1.22' );
  
                        // Sanitize for comment. Note '‐' in the replacement is U+2010,
                        // which looks much like the problematic '-'.
                return $text;
        }
  
 -      /**
 -       * Get a random string
 -       *
 -       * @return string
 -       * @deprecated since 1.26; use wfRandomString() instead.
 -       */
 -      public static function getRandomString() {
 -              wfDeprecated( __METHOD__, '1.26' );
 -              return wfRandomString( 16 );
 -      }
 -
        /**
         * Set the current user.
         * Should only be used when doing pre-save transform.
                $this->mUser = $user;
        }
  
 -      /**
 -       * Accessor for mUniqPrefix.
 -       *
 -       * @return string
 -       * @deprecated since 1.26; use Parser::MARKER_PREFIX instead.
 -       */
 -      public function uniqPrefix() {
 -              wfDeprecated( __METHOD__, '1.26' );
 -              return self::MARKER_PREFIX;
 -      }
 -
        /**
         * Set the context title
         *
         *
         * @param array $elements List of element names. Comments are always extracted.
         * @param string $text Source text string.
 -       * @param array $matches Out parameter, Array: extracted tags
 -       * @param string|null $uniq_prefix
 +       * @param array &$matches Out parameter, Array: extracted tags
         * @return string Stripped text
 -       * @since 1.26 The uniq_prefix argument is deprecated.
         */
 -      public static function extractTagsAndParams( $elements, $text, &$matches, $uniq_prefix = null ) {
 -              if ( $uniq_prefix !== null ) {
 -                      wfDeprecated( __METHOD__ . ' called with $prefix argument', '1.26' );
 -              }
 +      public static function extractTagsAndParams( $elements, $text, &$matches ) {
                static $n = 1;
                $stripped = '';
                $matches = [];
         * @return string
         */
        public function doTableStuff( $text ) {
 -
                $lines = StringUtils::explode( "\n", $text );
                $out = '';
                $td_history = []; # Is currently a td tag open?
         * @return string
         */
        public function internalParse( $text, $isMain = true, $frame = false ) {
 -
                $origText = $text;
  
                // Avoid PHP 7.1 warning from passing $this by reference
                        if ( !$frame->depth ) {
                                $flag = 0;
                        } else {
 -                              $flag = Parser::PTD_FOR_INCLUSION;
 +                              $flag = self::PTD_FOR_INCLUSION;
                        }
                        $dom = $this->preprocessToDom( $text, $flag );
                        $text = $frame->expand( $dom );
         * @return string
         */
        public function replaceExternalLinks( $text ) {
 -
                $bits = preg_split( $this->mExtLinkBracketedRegex, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
                if ( $bits === false ) {
                        throw new MWException( "PCRE needs to be compiled with "
  
        /**
         * Process [[ ]] wikilinks (RIL)
 -       * @param string $s
 +       * @param string &$s
         * @throws MWException
         * @return LinkHolderArray
         *
                                $link = $origLink;
                        }
  
 -                      $noforce = ( substr( $origLink, 0, 1 ) !== ':' );
 -                      if ( !$noforce ) {
 -                              # Strip off leading ':'
 -                              $link = substr( $link, 1 );
 -                      }
 -
                        $unstrip = $this->mStripState->unstripNoWiki( $link );
                        $nt = is_string( $unstrip ) ? Title::newFromText( $unstrip ) : null;
                        if ( $nt === null ) {
                        $ns = $nt->getNamespace();
                        $iw = $nt->getInterwiki();
  
 +                      $noforce = ( substr( $origLink, 0, 1 ) !== ':' );
 +
                        if ( $might_be_img ) { # if this is actually an invalid link
                                if ( $ns == NS_FILE && $noforce ) { # but might be an image
                                        $found = false;
                        $wasblank = ( $text == '' );
                        if ( $wasblank ) {
                                $text = $link;
 +                              if ( !$noforce ) {
 +                                      # Strip off leading ':'
 +                                      $text = substr( $text, 1 );
 +                              }
                        } else {
                                # T6598 madness. Handle the quotes only if they come from the alternate part
                                # [[Lista d''e paise d''o munno]] -> <a href="...">Lista d''e paise d''o munno</a>
                                        }
  
                                        $s = rtrim( $s . $prefix );
 -                                      $s .= trim( $trail, "\n" ) == '' ? '': $prefix . $trail;
 +                                      $s .= trim( $trail, "\n" ) == '' ? '' : $prefix . $trail;
                                        continue;
                                }
  
                                ) ) );
                                break;
                        case 'talkpagename':
 -                              if ( $this->mTitle->canTalk() ) {
 +                              if ( $this->mTitle->canHaveTalkPage() ) {
                                        $talkPage = $this->mTitle->getTalkPage();
                                        $value = wfEscapeWikiText( $talkPage->getPrefixedText() );
                                } else {
                                }
                                break;
                        case 'talkpagenamee':
 -                              if ( $this->mTitle->canTalk() ) {
 +                              if ( $this->mTitle->canHaveTalkPage() ) {
                                        $talkPage = $this->mTitle->getTalkPage();
                                        $value = wfEscapeWikiText( $talkPage->getPrefixedURL() );
                                } else {
                                $value = $this->mTitle->getNamespace();
                                break;
                        case 'talkspace':
 -                              $value = $this->mTitle->canTalk()
 +                              $value = $this->mTitle->canHaveTalkPage()
                                        ? str_replace( '_', ' ', $this->mTitle->getTalkNsText() )
                                        : '';
                                break;
                        case 'talkspacee':
 -                              $value = $this->mTitle->canTalk() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : '';
 +                              $value = $this->mTitle->canHaveTalkPage() ? wfUrlencode( $this->mTitle->getTalkNsText() ) : '';
                                break;
                        case 'subjectspace':
                                $value = str_replace( '_', ' ', $this->mTitle->getSubjectNsText() );
         * @return string The text of the template
         */
        public function braceSubstitution( $piece, $frame ) {
 -
                // Flags
  
                // $text has been filled
                                        . wfMessage( 'parser-template-loop-warning', $titleText )->inContentLanguage()->text()
                                        . '</span>';
                                $this->addTrackingCategory( 'template-loop-category' );
+                               $this->mOutput->addWarning( wfMessage( 'template-loop-warning',
+                                       wfEscapeWikiText( $titleText ) )->text() );
                                wfDebug( __METHOD__ . ": template loop broken at '$titleText'\n" );
                        }
                }
  
                list( $callback, $flags ) = $this->mFunctionHooks[$function];
  
 -              # Workaround for PHP bug 35229 and similar
 -              if ( !is_callable( $callback ) ) {
 -                      throw new MWException( "Tag hook for $function is not callable\n" );
 -              }
 -
                // Avoid PHP 7.1 warning from passing $this by reference
                $parser = $this;
  
                # string or an array containing the string and any flags. This mungs
                # things around to match what this method should return.
                if ( !is_array( $result ) ) {
 -                      $result =[
 +                      $result = [
                                'found' => true,
                                'text' => $result,
                        ];
         * @return array
         */
        public function argSubstitution( $piece, $frame ) {
 -
                $error = false;
                $parts = $piece['parts'];
                $nameWithSpaces = $frame->expand( $piece['title'] );
                        }
  
                        if ( isset( $this->mTagHooks[$name] ) ) {
 -                              # Workaround for PHP bug 35229 and similar
 -                              if ( !is_callable( $this->mTagHooks[$name] ) ) {
 -                                      throw new MWException( "Tag hook for $name is not callable\n" );
 -                              }
                                $output = call_user_func_array( $this->mTagHooks[$name],
                                        [ $content, $attributes, $this, $frame ] );
                        } elseif ( isset( $this->mFunctionTagHooks[$name] ) ) {
                                list( $callback, ) = $this->mFunctionTagHooks[$name];
 -                              if ( !is_callable( $callback ) ) {
 -                                      throw new MWException( "Tag hook for $name is not callable\n" );
 -                              }
  
                                // Avoid PHP 7.1 warning from passing $this by reference
                                $parser = $this;
         * @return string
         */
        public function doDoubleUnderscore( $text ) {
 -
                # The position of __TOC__ needs to be recorded
                $mw = MagicWord::get( 'toc' );
                if ( $mw->match( $text ) ) {
         * @private
         */
        public function formatHeadings( $text, $origText, $isMain = true ) {
 -              global $wgMaxTocLevel, $wgExperimentalHtmlIds;
 +              global $wgMaxTocLevel;
  
                # Inhibit editsection links if requested in the page
                if ( isset( $this->mDoubleUnderscores['noeditsection'] ) ) {
                        # Save headline for section edit hint before it's escaped
                        $headlineHint = $safeHeadline;
  
 -                      if ( $wgExperimentalHtmlIds ) {
 -                              # For reverse compatibility, provide an id that's
 -                              # HTML4-compatible, like we used to.
 -                              # It may be worth noting, academically, that it's possible for
 -                              # the legacy anchor to conflict with a non-legacy headline
 -                              # anchor on the page.  In this case likely the "correct" thing
 -                              # would be to either drop the legacy anchors or make sure
 -                              # they're numbered first.  However, this would require people
 -                              # to type in section names like "abc_.D7.93.D7.90.D7.A4"
 -                              # manually, so let's not bother worrying about it.
 -                              $legacyHeadline = Sanitizer::escapeId( $safeHeadline,
 -                                      [ 'noninitial', 'legacy' ] );
 -                              $safeHeadline = Sanitizer::escapeId( $safeHeadline );
 -
 -                              if ( $legacyHeadline == $safeHeadline ) {
 -                                      # No reason to have both (in fact, we can't)
 -                                      $legacyHeadline = false;
 -                              }
 -                      } else {
 -                              $legacyHeadline = false;
 -                              $safeHeadline = Sanitizer::escapeId( $safeHeadline,
 -                                      'noninitial' );
 +                      $fallbackHeadline = Sanitizer::escapeIdForAttribute( $safeHeadline, Sanitizer::ID_FALLBACK );
 +                      $linkAnchor = Sanitizer::escapeIdForLink( $safeHeadline );
 +                      $safeHeadline = Sanitizer::escapeIdForAttribute( $safeHeadline, Sanitizer::ID_PRIMARY );
 +                      if ( $fallbackHeadline === $safeHeadline ) {
 +                              # No reason to have both (in fact, we can't)
 +                              $fallbackHeadline = false;
                        }
  
 -                      # HTML names must be case-insensitively unique (T12721).
 -                      # This does not apply to Unicode characters per
 -                      # https://www.w3.org/TR/html5/infrastructure.html#case-sensitivity-and-string-comparison
 +                      # HTML IDs must be case-insensitively unique for IE compatibility (T12721).
                        # @todo FIXME: We may be changing them depending on the current locale.
                        $arrayKey = strtolower( $safeHeadline );
 -                      if ( $legacyHeadline === false ) {
 -                              $legacyArrayKey = false;
 +                      if ( $fallbackHeadline === false ) {
 +                              $fallbackArrayKey = false;
                        } else {
 -                              $legacyArrayKey = strtolower( $legacyHeadline );
 +                              $fallbackArrayKey = strtolower( $fallbackHeadline );
                        }
  
                        # Create the anchor for linking from the TOC to the section
                        $anchor = $safeHeadline;
 -                      $legacyAnchor = $legacyHeadline;
 +                      $fallbackAnchor = $fallbackHeadline;
                        if ( isset( $refers[$arrayKey] ) ) {
                                // @codingStandardsIgnoreStart
                                for ( $i = 2; isset( $refers["${arrayKey}_$i"] ); ++$i );
                                // @codingStandardsIgnoreEnd
                                $anchor .= "_$i";
 +                              $linkAnchor .= "_$i";
                                $refers["${arrayKey}_$i"] = true;
                        } else {
                                $refers[$arrayKey] = true;
                        }
 -                      if ( $legacyHeadline !== false && isset( $refers[$legacyArrayKey] ) ) {
 +                      if ( $fallbackHeadline !== false && isset( $refers[$fallbackArrayKey] ) ) {
                                // @codingStandardsIgnoreStart
 -                              for ( $i = 2; isset( $refers["${legacyArrayKey}_$i"] ); ++$i );
 +                              for ( $i = 2; isset( $refers["${fallbackArrayKey}_$i"] ); ++$i );
                                // @codingStandardsIgnoreEnd
 -                              $legacyAnchor .= "_$i";
 -                              $refers["${legacyArrayKey}_$i"] = true;
 +                              $fallbackAnchor .= "_$i";
 +                              $refers["${fallbackArrayKey}_$i"] = true;
                        } else {
 -                              $refers[$legacyArrayKey] = true;
 +                              $refers[$fallbackArrayKey] = true;
                        }
  
                        # Don't number the heading if it is the only one (looks silly)
                        }
  
                        if ( $enoughToc && ( !isset( $wgMaxTocLevel ) || $toclevel < $wgMaxTocLevel ) ) {
 -                              $toc .= Linker::tocLine( $anchor, $tocline,
 +                              $toc .= Linker::tocLine( $linkAnchor, $tocline,
                                        $numbering, $toclevel, ( $isTemplate ? false : $sectionIndex ) );
                        }
  
                        }
                        $head[$headlineCount] = Linker::makeHeadline( $level,
                                $matches['attrib'][$headlineCount], $anchor, $headline,
 -                              $editlink, $legacyAnchor );
 +                              $editlink, $fallbackAnchor );
  
                        $headlineCount++;
                }
                # which may corrupt this parser instance via its wfMessage()->text() call-
  
                # Signatures
 -              $sigText = $this->getUserSig( $user );
 -              $text = strtr( $text, [
 -                      '~~~~~' => $d,
 -                      '~~~~' => "$sigText $d",
 -                      '~~~' => $sigText
 -              ] );
 +              if ( strpos( $text, '~~~' ) !== false ) {
 +                      $sigText = $this->getUserSig( $user );
 +                      $text = strtr( $text, [
 +                              '~~~~~' => $d,
 +                              '~~~~' => "$sigText $d",
 +                              '~~~' => $sigText
 +                      ] );
 +                      # The main two signature forms used above are time-sensitive
 +                      $this->mOutput->setFlag( 'user-signature' );
 +              }
  
                # Context links ("pipe tricks"): [[|name]] and [[name (context)|]]
                $tc = '[' . Title::legalChars() . ']';
         * Do not reuse this parser instance after calling getUserSig(),
         * as it may have changed if it's the $wgParser.
         *
 -       * @param User $user
 +       * @param User &$user
         * @param string|bool $nickname Nickname to use or false to use user's default nickname
         * @param bool|null $fancySig whether the nicknname is the complete signature
         *    or null to use default value
         * @throws MWException
         * @return callable|null The old value of the mTagHooks array associated with the hook
         */
 -      public function setHook( $tag, $callback ) {
 +      public function setHook( $tag, callable $callback ) {
                $tag = strtolower( $tag );
                if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
                        throw new MWException( "Invalid character {$m[0]} in setHook('$tag', ...) call" );
         * @throws MWException
         * @return callable|null The old value of the mTagHooks array associated with the hook
         */
 -      public function setTransparentTagHook( $tag, $callback ) {
 +      public function setTransparentTagHook( $tag, callable $callback ) {
                $tag = strtolower( $tag );
                if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
                        throw new MWException( "Invalid character {$m[0]} in setTransparentHook('$tag', ...) call" );
         * @throws MWException
         * @return string|callable The old callback function for this name, if any
         */
 -      public function setFunctionHook( $id, $callback, $flags = 0 ) {
 +      public function setFunctionHook( $id, callable $callback, $flags = 0 ) {
                global $wgContLang;
  
                $oldVal = isset( $this->mFunctionHooks[$id] ) ? $this->mFunctionHooks[$id][0] : null;
         * @throws MWException
         * @return null
         */
 -      public function setFunctionTagHook( $tag, $callback, $flags ) {
 +      public function setFunctionTagHook( $tag, callable $callback, $flags ) {
                $tag = strtolower( $tag );
                if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
                        throw new MWException( "Invalid character {$m[0]} in setFunctionTagHook('$tag', ...) call" );
         * Replace "<!--LINK-->" link placeholders with actual links, in the buffer
         * Placeholders created in Linker::link()
         *
 -       * @param string $text
 +       * @param string &$text
         * @param int $options
         */
        public function replaceLinkHolders( &$text, $options = 0 ) {
         * @return string HTML
         */
        public function renderImageGallery( $text, $params ) {
 -
                $mode = false;
                if ( isset( $params['mode'] ) ) {
                        $mode = $params['mode'];
         * Callback from the Sanitizer for expanding items found in HTML attribute
         * values, so they can be safely tested and escaped.
         *
 -       * @param string $text
 +       * @param string &$text
         * @param bool|PPFrame $frame
         * @return string
         */
                # Strip out wikitext links(they break the anchor)
                $text = $this->stripSectionName( $text );
                $text = Sanitizer::normalizeSectionNameWhitespace( $text );
 -              return '#' . Sanitizer::escapeId( $text, 'noninitial' );
 +              return '#' . Sanitizer::escapeIdForLink( $text );
        }
  
        /**
         * Same as guessSectionNameFromWikiText(), but produces legacy anchors
 -       * instead.  For use in redirects, since IE6 interprets Redirect: headers
 -       * as something other than UTF-8 (apparently?), resulting in breakage.
 +       * instead, if possible. For use in redirects, since various versions
 +       * of Microsoft browsers interpret Location: headers as something other
 +       * than UTF-8, resulting in breakage.
         *
         * @param string $text The section name
         * @return string An anchor
         */
        public function guessLegacySectionNameFromWikiText( $text ) {
 +              global $wgFragmentMode;
 +
                # Strip out wikitext links(they break the anchor)
                $text = $this->stripSectionName( $text );
                $text = Sanitizer::normalizeSectionNameWhitespace( $text );
 -              return '#' . Sanitizer::escapeId( $text, [ 'noninitial', 'legacy' ] );
 +
 +              if ( isset( $wgFragmentMode[1] ) && $wgFragmentMode[1] === 'legacy' ) {
 +                      // ForAttribute() and ForLink() are the same for legacy encoding
 +                      $id = Sanitizer::escapeIdForAttribute( $text, Sanitizer::ID_FALLBACK );
 +              } else {
 +                      $id = Sanitizer::escapeIdForLink( $text );
 +              }
 +
 +              return "#$id";
        }
  
        /**
                $e = new Exception;
                $this->mInParse = $e->getTraceAsString();
  
 -              $recursiveCheck = new ScopedCallback( function() {
 +              $recursiveCheck = new ScopedCallback( function () {
                        $this->mInParse = false;
                } );
  
diff --combined languages/i18n/en.json
        "tog-shownumberswatching": "Show the number of watching users",
        "tog-oldsig": "Your existing signature:",
        "tog-fancysig": "Treat signature as wikitext (without an automatic link)",
 -      "tog-uselivepreview": "Use live preview",
 +      "tog-uselivepreview": "Show previews without reloading the page",
        "tog-forceeditsummary": "Prompt me when entering a blank edit summary",
        "tog-watchlisthideown": "Hide my edits from the watchlist",
        "tog-watchlisthidebots": "Hide bot edits from the watchlist",
        "tog-watchlisthideminor": "Hide minor edits from the watchlist",
        "tog-watchlisthideliu": "Hide edits by logged in users from the watchlist",
        "tog-watchlistreloadautomatically": "Reload the watchlist automatically whenever a filter is changed (JavaScript required)",
 +      "tog-watchlistunwatchlinks": "Add direct unwatch/watch links to watchlist entries (JavaScript required for toggle functionality)",
        "tog-watchlisthideanons": "Hide edits by anonymous users from the watchlist",
        "tog-watchlisthidepatrolled": "Hide patrolled edits from the watchlist",
        "tog-watchlisthidecategorization": "Hide categorization of pages",
        "permissionserrorstext-withaction": "You do not have permission to $2, for the following {{PLURAL:$1|reason|reasons}}:",
        "contentmodelediterror": "You cannot edit this revision because its content model is <code>$1</code>, which differs from the current content model of the page <code>$2</code>.",
        "recreate-moveddeleted-warn": "<strong>Warning: You are recreating a page that was previously deleted.</strong>\n\nYou should consider whether it is appropriate to continue editing this page.\nThe deletion and move log for this page are provided here for convenience:",
 -      "moveddeleted-notice": "This page has been deleted.\nThe deletion and move log for the page are provided below for reference.",
 -      "moveddeleted-notice-recent": "Sorry, this page was recently deleted (within the last 24 hours).\nThe deletion and move log for the page are provided below for reference.",
 +      "moveddeleted-notice": "This page has been deleted.\nThe deletion, protection, and move log for the page are provided below for reference.",
 +      "moveddeleted-notice-recent": "Sorry, this page was recently deleted (within the last 24 hours).\nThe deletion, protection, and move log for the page are provided below for reference.",
        "log-fulllog": "View full log",
        "edit-hook-aborted": "Edit aborted by hook.\nIt gave no explanation.",
        "edit-gone-missing": "Could not update the page.\nIt appears to have been deleted.",
        "parser-template-loop-warning": "Template loop detected: [[$1]]",
        "template-loop-category": "Pages with template loops",
        "template-loop-category-desc": "The page contains a template loop, ie. a template which calls itself recursively.",
+       "template-loop-warning": "<strong>Warning:</strong> This page calls [[:$1]] which causes a template loop (an infinite recursive call).",
        "parser-template-recursion-depth-warning": "Template recursion depth limit exceeded ($1)",
        "language-converter-depth-warning": "Language converter depth limit exceeded ($1)",
        "node-count-exceeded-category": "Pages where node count is exceeded",
        "prefs-editwatchlist-clear": "Clear your watchlist",
        "prefs-watchlist-days": "Days to show in watchlist:",
        "prefs-watchlist-days-max": "Maximum $1 {{PLURAL:$1|day|days}}",
 -      "prefs-watchlist-edits": "Maximum number of changes to show in expanded watchlist:",
 +      "prefs-watchlist-edits": "Maximum number of changes to show in watchlist:",
        "prefs-watchlist-edits-max": "Maximum number: 1000",
        "prefs-watchlist-token": "Watchlist token:",
        "prefs-misc": "Misc",
        "action-deletechangetags": "delete tags from the database",
        "action-purge": "purge this page",
        "nchanges": "$1 {{PLURAL:$1|change|changes}}",
 +      "ntimes": "$1×",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|since last visit}}",
        "enhancedrc-history": "history",
        "recentchanges": "Recent changes",
        "recentchanges-legend-unpatrolled": "{{int:recentchanges-label-unpatrolled}}",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Show",
 +      "rcfilters-tag-remove": "Remove '$1'",
 +      "rcfilters-legend-heading": "<strong>List of abbreviations:</strong>",
 +      "rcfilters-other-review-tools": "<strong>Other review tools</strong>",
 +      "rcfilters-group-results-by-page": "Group results by page",
 +      "rcfilters-grouping-title": "Grouping",
        "rcfilters-activefilters": "Active filters",
 -      "rcfilters-quickfilters": "Saved filter settings",
 +      "rcfilters-advancedfilters": "Advanced filters",
 +      "rcfilters-limit-title": "Changes to show",
 +      "rcfilters-limit-shownum": "Show last {{PLURAL:$1|change|$1 changes}}",
 +      "rcfilters-days-title": "Recent days",
 +      "rcfilters-hours-title": "Recent hours",
 +      "rcfilters-days-show-days": "$1 {{PLURAL:$1|day|days}}",
 +      "rcfilters-days-show-hours": "$1 {{PLURAL:$1|hour|hours}}",
 +      "rcfilters-highlighted-filters-list": "Highlighted: $1",
 +      "rcfilters-quickfilters": "Saved filters",
        "rcfilters-quickfilters-placeholder-title": "No links saved yet",
        "rcfilters-quickfilters-placeholder-description": "To save your filter settings and reuse them later, click the bookmark icon in the Active Filter area, below.",
        "rcfilters-savedqueries-defaultlabel": "Saved filters",
        "rcfilters-savedqueries-unsetdefault": "Remove as default",
        "rcfilters-savedqueries-remove": "Remove",
        "rcfilters-savedqueries-new-name-label": "Name",
 -      "rcfilters-savedqueries-apply-label": "Save settings",
 +      "rcfilters-savedqueries-new-name-placeholder": "Describe the purpose of the filter",
 +      "rcfilters-savedqueries-apply-label": "Create filter",
 +      "rcfilters-savedqueries-apply-and-setdefault-label": "Create default filter",
        "rcfilters-savedqueries-cancel-label": "Cancel",
        "rcfilters-savedqueries-add-new-title": "Save current filter settings",
        "rcfilters-restore-default-filters": "Restore default filters",
        "rcfilters-clear-all-filters": "Clear all filters",
 +      "rcfilters-show-new-changes": "View newest changes",
        "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-whatsthis": "What's this?",
 -      "rcfilters-filterlist-feedbacklink": "Provide feedback on the new (beta) filters",
 +      "rcfilters-filterlist-whatsthis": "How do these work?",
 +      "rcfilters-filterlist-feedbacklink": "Tell us what you think about these (new) filtering tools",
        "rcfilters-highlightbutton-title": "Highlight results",
        "rcfilters-highlightmenu-title": "Select a color",
        "rcfilters-highlightmenu-help": "Select a color to highlight this property",
        "rcfilters-filterlist-noresults": "No filters found",
        "rcfilters-noresults-conflict": "No results found because the search criteria are in conflict",
        "rcfilters-state-message-subset": "This filter has no effect because its results are included with those of the following, broader {{PLURAL:$2|filter|filters}} (try highlighting to distinguish it): $1",
 -      "rcfilters-state-message-fullcoverage": "Selecting all filters in a group is the same as selecting none, so this filter has no effect. Group includes: $1",
 -      "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-filter-unregistered-conflicts-user-experience-level": "This filter conflicts with the following Experience {{PLURAL:$2|filter|filters}}, which {{PLURAL:$2|finds|find}} only registered users: $1",
 +      "rcfilters-state-message-fullcoverage": "Selecting all filters in this group is the same as selecting none, so this filter has no effect. Group includes: $1",
        "rcfilters-filtergroup-authorship": "Contribution authorship",
        "rcfilters-filter-editsbyself-label": "Changes by you",
        "rcfilters-filter-editsbyself-description": "Your own contributions.",
        "rcfilters-filter-editsbyother-label": "Changes by others",
        "rcfilters-filter-editsbyother-description": "All changes except your own.",
 -      "rcfilters-filtergroup-userExpLevel": "Experience level (for registered users only)",
 -      "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "Experience filters find only registered users, so this filter conflicts with the “Unregistered” filter.",
 -      "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "The \"Unregistered\" filter conflicts with one or more Experience filters, which find registered users only. The conflicting filters are marked in the Active Filters area, above.",
 +      "rcfilters-filtergroup-userExpLevel": "User registration and experience",
 +      "rcfilters-filter-user-experience-level-registered-label": "Registered",
 +      "rcfilters-filter-user-experience-level-registered-description": "Logged-in editors.",
 +      "rcfilters-filter-user-experience-level-unregistered-label": "Unregistered",
 +      "rcfilters-filter-user-experience-level-unregistered-description": "Editors who aren't logged-in.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Newcomers",
 -      "rcfilters-filter-user-experience-level-newcomer-description": "Fewer than 10 edits and 4 days of activity.",
 +      "rcfilters-filter-user-experience-level-newcomer-description": "Registered editors with fewer than 10 edits and 4 days of activity.",
        "rcfilters-filter-user-experience-level-learner-label": "Learners",
 -      "rcfilters-filter-user-experience-level-learner-description": "More experience than \"Newcomers\" but less than \"Experienced users\".",
 +      "rcfilters-filter-user-experience-level-learner-description": "Registered editors whose experience falls between \"Newcomers\" and \"Experienced users.\"",
        "rcfilters-filter-user-experience-level-experienced-label": "Experienced users",
 -      "rcfilters-filter-user-experience-level-experienced-description": "More than 30 days of activity and 500 edits.",
 +      "rcfilters-filter-user-experience-level-experienced-description": "Registered editors with more than 500 edits and 30 days of activity.",
        "rcfilters-filtergroup-automated": "Automated contributions",
        "rcfilters-filter-bots-label": "Bot",
        "rcfilters-filter-bots-description": "Edits made by automated tools.",
        "rcfilters-filter-watchlist-watchednew-description": "Changes to Watchlisted pages you haven't visited since the changes occurred.",
        "rcfilters-filter-watchlist-notwatched-label": "Not on Watchlist",
        "rcfilters-filter-watchlist-notwatched-description": "Everything except changes to your Watchlisted pages.",
 +      "rcfilters-filtergroup-watchlistactivity": "Watchlist activity",
 +      "rcfilters-filter-watchlistactivity-unseen-label": "Unseen changes",
 +      "rcfilters-filter-watchlistactivity-unseen-description": "Changes to pages you haven't visited since the changes occurred.",
 +      "rcfilters-filter-watchlistactivity-seen-label": "Seen changes",
 +      "rcfilters-filter-watchlistactivity-seen-description": "Changes to pages you have visited since the changes occurred.",
        "rcfilters-filtergroup-changetype": "Type of change",
        "rcfilters-filter-pageedits-label": "Page edits",
        "rcfilters-filter-pageedits-description": "Edits to wiki content, discussions, category descriptions…",
        "rcfilters-hideminor-conflicts-typeofchange-global": "The \"Minor edits\" filter conflicts with one or more Type of change filters, because certain types of change cannot be designated as \"minor\". The conflicting filters are marked in the Active filters area, above.",
        "rcfilters-hideminor-conflicts-typeofchange": "Certain types of change cannot be designated as \"minor\", so this filter conflicts with the following Type of Change filters: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "This Type of change filter conflicts with the \"Minor edits\" filter. Certain types of change cannot be designated as \"minor\".",
 -      "rcfilters-filtergroup-lastRevision": "Last revision",
 -      "rcfilters-filter-lastrevision-label": "Last revision",
 -      "rcfilters-filter-lastrevision-description": "The most recent change to a page.",
 -      "rcfilters-filter-previousrevision-label": "Earlier revisions",
 -      "rcfilters-filter-previousrevision-description": "All changes that are not the most recent change to a page.",
 +      "rcfilters-filtergroup-lastRevision": "Latest revisions",
 +      "rcfilters-filter-lastrevision-label": "Latest revision",
 +      "rcfilters-filter-lastrevision-description": "Only the most recent change to a page.",
 +      "rcfilters-filter-previousrevision-label": "Not the latest revision",
 +      "rcfilters-filter-previousrevision-description": "All changes that are not the \"latest revision\".",
        "rcfilters-filter-excluded": "Excluded",
        "rcfilters-tag-prefix-namespace": ":$1",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:not</strong> $1",
        "rcfilters-tag-prefix-tags": "#$1",
 -      "rcfilters-view-tags": "Tags",
 +      "rcfilters-exclude-button-off": "Exclude selected",
 +      "rcfilters-exclude-button-on": "Excluding selected",
 +      "rcfilters-view-advanced-filters-label": "Advanced filters",
 +      "rcfilters-view-tags": "Tagged edits",
 +      "rcfilters-view-namespaces-tooltip": "Filter results by namespace",
 +      "rcfilters-view-tags-tooltip": "Filter results using edit tags",
 +      "rcfilters-view-return-to-default-tooltip": "Return to main filter menu",
 +      "rcfilters-liveupdates-button": "Live updates",
 +      "rcfilters-liveupdates-button-title-on": "Turn off live updates",
 +      "rcfilters-liveupdates-button-title-off": "Display new changes as they happen",
 +      "rcfilters-watchlist-markseen-button": "Mark all changes as seen",
 +      "rcfilters-watchlist-edit-watchlist-button": "Edit your list of watched pages",
 +      "rcfilters-watchlist-showupdated": "Changes to pages you haven't visited since the changes occurred are in <strong>bold</strong>, with solid markers.",
        "rcnotefrom": "Below {{PLURAL:$5|is the change|are the changes}} since <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
        "rclistfromreset": "Reset date selection",
        "rclistfrom": "Show new changes starting from $2, $3",
        "pageswithprop-legend": "Pages with a page property",
        "pageswithprop-text": "This page lists pages that use a particular page property.",
        "pageswithprop-prop": "Property name:",
 +      "pageswithprop-reverse": "Sort in reverse order",
 +      "pageswithprop-sortbyvalue": "Sort by property value",
        "pageswithprop-submit": "Go",
        "pageswithprop-prophidden-long": "long text property value hidden ($1)",
        "pageswithprop-prophidden-binary": "binary property value hidden ($1)",
        "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-results-login-suppressed": "This request has been processed as a logged-out user as it could be used to bypass browser Same-Origin security. Note that the API sandbox's automatic token handling does not work properly with such requests, please fill them in manually.",
        "apisandbox-request-selectformat-label": "Show request data as:",
        "apisandbox-request-format-url-label": "URL query string",
        "apisandbox-request-url-label": "Request URL:",
        "unwatchthispage": "Stop watching",
        "notanarticle": "Not a content page",
        "notvisiblerev": "The last revision by a different user has been deleted",
 -      "watchlist-details": "{{PLURAL:$1|$1 page|$1 pages}} on your watchlist, not separately counting talk pages.",
 +      "watchlist-details": "{{PLURAL:$1|$1 page is|$1 pages are}} on your Watchlist (plus talk pages).",
        "wlheader-enotif": "Email notification is enabled.",
        "wlheader-showupdated": "Pages that have been changed since you last visited them are shown in <strong>bold</strong>.",
        "wlnote": "Below {{PLURAL:$1|is the last change|are the last <strong>$1</strong> changes}} in the last {{PLURAL:$2|hour|<strong>$2</strong> hours}}, as of $3, $4.",
        "watching": "Watching...",
        "unwatching": "Unwatching...",
        "watcherrortext": "An error occurred while changing your watchlist settings for \"$1\".",
 +      "watchlist-unwatch": "×",
 +      "watchlist-unwatch-undo": "+",
        "enotif_reset": "Mark all pages visited",
        "enotif_impersonal_salutation": "{{SITENAME}} user",
        "enotif_subject_deleted": "{{SITENAME}} page $1 has been {{GENDER:$2|deleted}} by $2",
        "enotif_lastdiff": "To view this change, see $1",
        "enotif_anon_editor": "anonymous user $1",
        "enotif_body": "Dear $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nEditor's summary: $PAGESUMMARY $PAGEMINOREDIT\n\nContact the editor:\nmail: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nThere will be no other notifications in case of further activity unless you visit this page while logged in. You could also reset the notification flags for all your watched pages on your watchlist.\n\nYour friendly {{SITENAME}} notification system\n\n--\nTo change your email notification settings, visit\n{{canonicalurl:{{#special:Preferences}}}}\n\nTo change your watchlist settings, visit\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nTo delete the page from your watchlist, visit\n$UNWATCHURL\n\nFeedback and further assistance:\n$HELPPAGE",
 +      "enotif_minoredit": "This is a minor edit",
        "created": "created",
        "changed": "changed",
        "deletepage": "Delete page",
        "delete-warning-toobig": "This page has a large edit history, over $1 {{PLURAL:$1|revision|revisions}}.\nDeleting it may disrupt database operations of {{SITENAME}};\nproceed with caution.",
        "deleteprotected": "You cannot delete this page because it has been protected.",
        "deleting-backlinks-warning": "<strong>Warning:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|Other pages]] link to or transclude the page you are about to delete.",
 +      "deleting-subpages-warning": "<strong>Warning:</strong> The page you are about to delete has [[Special:PrefixIndex/{{FULLPAGENAME}}/|{{PLURAL:$1|a subpage|$1 subpages|51=over 50 subpages}}]].",
        "rollback": "Roll back edits",
        "rollbacklink": "rollback",
        "rollbacklinkcount": "rollback $1 {{PLURAL:$1|edit|edits}}",
        "undelete-search-title": "Search deleted pages",
        "undelete-search-box": "Search deleted pages",
        "undelete-search-prefix": "Show pages starting with:",
 +      "undelete-search-full": "Show page titles containing:",
        "undelete-search-submit": "Search",
        "undelete-no-results": "No matching pages found in the deletion archive.",
        "undelete-filename-mismatch": "Cannot undelete file revision with timestamp $1: Filename mismatch.",
        "sp-contributions-explain": "",
        "sp-contributions-footer": "-",
        "sp-contributions-footer-anon": "-",
 +      "sp-contributions-footer-anon-range": "-",
        "sp-contributions-footer-newbies": "-",
 +      "sp-contributions-outofrange": "Unable to show any results. The requested IP range is larger than the CIDR limit of /$1.",
        "whatlinkshere": "What links here",
        "whatlinkshere-title": "Pages that link to \"$1\"",
        "whatlinkshere-summary": "",
        "import-nonewrevisions": "No revisions imported (all were either already present, or skipped due to errors).",
        "xml-error-string": "$1 at line $2, col $3 (byte $4): $5",
        "import-upload": "Upload XML data",
 -      "import-token-mismatch": "Loss of session data.\n\nYou might have been logged out. <strong>Please verify that you're still logged in and try again</strong>.\nIf it still does not work, try [[Special:UserLogout|logging out]] and logging back in, and check that your browser allows cookies from this site.",
 +      "import-token-mismatch": "Loss of session data.\n\nYou might have been logged out. '''Please verify that you're still logged in and try again'''.\nIf it still does not work, try [[Special:UserLogout|logging out]] and logging back in, and check that your browser allows cookies from this site.",
        "import-invalid-interwiki": "Cannot import from the specified wiki.",
        "import-error-edit": "Page \"$1\" was not imported because you are not allowed to edit it.",
        "import-error-create": "Page \"$1\" was not imported because you are not allowed to create it.",
        "specialpages": "Special pages",
        "specialpages-summary": "",
        "specialpages-note-top": "Legend",
 -      "specialpages-note": "* Normal special pages.\n* <span class=\"mw-specialpagerestricted\">Restricted special pages.</span>",
 +      "specialpages-note-restricted": "* Normal special pages.\n* <span class=\"mw-specialpagerestricted\">Restricted special pages.</span>",
 +      "specialpages-note-cached": "-",
        "specialpages-group-maintenance": "Maintenance reports",
        "specialpages-group-other": "Other special pages",
        "specialpages-group-login": "Login / create account",
        "compare-invalid-title": "The title you specified is invalid.",
        "compare-title-not-exists": "The title you specified does not exist.",
        "compare-revision-not-exists": "The revision you specified does not exist.",
 +      "diff-form": "Differences",
 +      "diff-form-oldid": "Old revision ID (optional)",
 +      "diff-form-revid": "Revision ID of difference",
 +      "diff-form-submit": "Show differences",
 +      "diff-form-summary": "",
 +      "permanentlink": "Permanent link",
 +      "permanentlink-revid": "Revision ID",
 +      "permanentlink-submit": "Go to revision",
 +      "permanentlink-summary": "",
        "dberr-problems": "Sorry! This site is experiencing technical difficulties.",
        "dberr-again": "Try waiting a few minutes and reloading.",
        "dberr-info": "(Cannot access the database: $1)",
        "log-description-pagelang": "This is a log of changes in page languages.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|changed}} the language of $3 from $4 to $5",
        "default-skin-not-found": "Whoops! The default skin for your wiki, defined in <code dir=\"ltr\">$wgDefaultSkin</code> as <code>$1</code>, is not available.\n\nYour installation seems to include the following {{PLURAL:$4|skin|skins}}. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable {{PLURAL:$4|it|them and choose the default}}.\n\n$2\n\n; If you have just installed MediaWiki:\n: You probably installed from git, or directly from the source code using some other method. This is expected. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by:\n:* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it.\n:* Downloading individual skin tarballs from [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Using Git to download skins].\n: Doing this should not interfere with your git repository if you're a MediaWiki developer.\n\n; If you have just upgraded MediaWiki:\n: MediaWiki 1.24 and newer no longer automatically enables installed skins (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). You can paste the following {{PLURAL:$5|line|lines}} into <code>LocalSettings.php</code> to enable {{PLURAL:$5|the|all}} installed {{PLURAL:$5|skin|skins}}:\n\n<pre dir=\"ltr\">$3</pre>\n\n; If you have just modified <code>LocalSettings.php</code>:\n: Double-check the skin names for typos.",
 -      "default-skin-not-found-no-skins": "Whoops! The default skin for your wiki, defined in <code>$wgDefaultSkin</code> as <code>$1</code>, is not available.\n\nYou have no installed skins.\n\n; If you have just installed or upgraded MediaWiki:\n: You probably installed from git, or directly from the source code using some other method. This is expected. MediaWiki 1.24 and newer doesn't include any skins in the main repository. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by:\n:* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it.\n:* Downloading individual skin tarballs from [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Using Git to download skins].\n: Doing this should not interfere with your git repository if you're a MediaWiki developer. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable skins and choose the default.\n",
 +      "default-skin-not-found-no-skins": "Whoops! The default skin for your wiki, defined in <code>$wgDefaultSkin</code> as <code>$1</code>, is not available.\n\nYou have no installed skins.\n\n; If you have just installed or upgraded MediaWiki:\n: You probably installed from git, or directly from the source code using some other method. This is expected. MediaWiki 1.24 and newer doesn't include any skins in the main repository. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by:\n:* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it.\n:* Downloading individual skin tarballs from [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins Using Git to download skins].\n: Doing this should not interfere with your git repository if you're a MediaWiki developer. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable skins and choose the default.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (enabled)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>disabled</strong>)",
        "mediastatistics": "Media statistics",
        "mediastatistics-header-text": "Textual",
        "mediastatistics-header-executable": "Executables",
        "mediastatistics-header-archive": "Compressed formats",
 +      "mediastatistics-header-3d": "3D",
        "mediastatistics-header-total": "All files",
        "json-warn-trailing-comma": "$1 trailing {{PLURAL:$1|comma was|commas were}} removed from JSON",
        "json-error-unknown": "There was a problem with the JSON. Error: $1",
        "undelete-cantedit": "You cannot undelete this page as you are not allowed to edit this page.",
        "undelete-cantcreate": "You cannot undelete this page as there is no existing page with this name and you are not allowed to create this page.",
        "pagedata-title": "Page data",
 -      "pagedata-text": "This page provides a data interface to pages. Please provide the page title in the URL, using subpage syntax.\n* Content negotiation applies based on you client's Accept header. This means that the page data will be provided in the format preferred by your client.",
 +      "pagedata-text": "This page provides a data interface to pages. Please provide the page title in the URL, using subpage syntax.\n* Content negotiation applies based on your client's Accept header. This means that the page data will be provided in the format preferred by your client.",
        "pagedata-not-acceptable": "No matching format found. Supported MIME types: $1",
        "pagedata-bad-title": "Invalid title: $1."
  }
diff --combined languages/i18n/qqq.json
@@@ -91,7 -91,6 +91,7 @@@
                        "Mormegil",
                        "Mpradeep",
                        "Murma174",
 +                      "MusikAnimal",
                        "Najami",
                        "Naudefj",
                        "Nemo bis",
        "tog-watchlisthidebots": "[[Special:Preferences]], tab 'Watchlist'. Offers user to hide bot edits from watchlist. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
        "tog-watchlisthideminor": "[[Special:Preferences]], tab 'Watchlist'. Offers user to hide minor edits from watchlist. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
        "tog-watchlisthideliu": "Option in tab 'Watchlist' of [[Special:Preferences]]. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
 -      "tog-watchlistreloadautomatically": "[[Special:Preferences]], tab 'Watchlist'. Offers user to to automatically refresh the watchlist page, when a filter is changed.",
 +      "tog-watchlistreloadautomatically": "[[Special:Preferences]], tab 'Watchlist'. Offers user to automatically refresh the watchlist page, when a filter is changed.",
 +      "tog-watchlistunwatchlinks": "[[Special:Preferences]], tab 'Watchlist'. Offers user to add an unwatch/watch toggle link to watchlist entries.",
        "tog-watchlisthideanons": "Option in tab 'Watchlist' of [[Special:Preferences]]. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
        "tog-watchlisthidepatrolled": "Option in Watchlist tab of [[Special:Preferences]]. {{Gender}}\n\n{{Related|Preferences-watchlistrc-toggle}}",
        "tog-watchlisthidecategorization": "Option in Watchlist tab of [[Special:Preferences]]. Offers user to hide/show categorization of pages. Appears next to checkboxes with labels such as {{msg-mw|tog-watchlisthideminor}}.",
        "parser-template-loop-warning": "Parameters:\n* $1 - page title",
        "template-loop-category": "This message is used as a category name for a [[mw:Special:MyLanguage/Help:Tracking categories|tracking category]] where pages with template loops will be listed.",
        "template-loop-category-desc": "Pages with template loops category description. Shown on [[Special:TrackingCategories]].\n\nSee also:\n* {{msg-mw|Template-loop-category}}",
+       "template-loop-warning": "This message is displayed in edit preview when a template loop is detected on the previewed page.\n\nParameters:\n* $1 - the full title of template which causes the template loop.",
        "parser-template-recursion-depth-warning": "Parameters:\n* $1 - limit value of recursion depth",
        "language-converter-depth-warning": "Error message shown when a page uses too deeply nested language conversion syntax. Parameters:\n* $1 - the value of the depth limit",
        "node-count-exceeded-category": "This message is used as a category name for a [[mw:Help:Tracking categories|tracking category]] where pages are placed automatically if the node-count of the preprocessor exceeds the limit.\n\nSee also:\n* {{msg-mw|Node-count-exceeded-warning}}",
        "action-deletechangetags": "{{doc-action|deletechangetags}}",
        "action-purge": "{{doc-action|purge}}",
        "nchanges": "Appears on enhanced watchlist and recent changes when page has more than one change on given date, linking to a diff of the changes.\n\nParameters:\n* $1 - the number of changes on that day (2 or more)\nThree messages are shown side-by-side: ({{msg-mw|Nchanges}} | {{msg-mw|Enhancedrc-since-last-visit}} | {{msg-mw|Enhancedrc-history}}).",
 +      "ntimes": "Used to indicate how many times an event occurred (eg. on enhanced recent change when a user did more than one change to the page). Parameters:\n* $1 - number (integer)",
        "enhancedrc-since-last-visit": "Appears on enhanced watchlist and recent changes when page has more than one change on given date and at least one that the user hasn't seen yet, linking to a diff of the unviewed changes.\n\nParameters:\n* $1 - the number of unviewed changes (1 or more)\nThree messages are shown side-by-side: ({{msg-mw|nchanges}} | {{msg-mw|enhancedrc-since-last-visit}} | {{msg-mw|enhancedrc-history}}).",
        "enhancedrc-history": "Appears on enhanced watchlist and recent changes when page has more than one change on given date, linking to its history.\n\nThis is the same as {{msg-mw|hist}}, but not abbreviated.\n\nThree messages are shown side-by-side: ({{msg-mw|nchanges}} | {{msg-mw|enhancedrc-since-last-visit}} | {{msg-mw|enhancedrc-history}}).\n{{Identical|History}}",
        "recentchanges": "The text of the link in sidebar going to the special page [[Special:RecentChanges]]. Also the page title of that special page.\n\nSee also:\n* {{msg-mw|Recentchanges}}\n* {{msg-mw|Accesskey-n-recentchanges}}\n* {{msg-mw|Tooltip-n-recentchanges}}\n{{Identical|Recent changes}}",
        "recentchanges-legend-unpatrolled": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-unpatrolled}}.",
        "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-tag-remove": "A tooltip for the button that removes a filter from the active filters area in [[Special:RecentChanges]] and [[Special:Watchlist]] when RCFilters are enabled. \n\nParameters: $1 - Tag label",
 +      "rcfilters-legend-heading": "Used as a heading for legend box on [[Special:RecentChanges]] and [[Special:Watchlist]] when RCFilters are enabled.",
 +      "rcfilters-other-review-tools": "Used as a heading for the community collection of other links on [[Special:RecentChanges]] when RCFilters are enabled.",
 +      "rcfilters-group-results-by-page": "A label for the checkbox describing whether the results in [[Special:RecentChanges]] are grouped by page when RCFilters are enabled.",
 +      "rcfilters-grouping-title": "Title for the section showing display options for grouping results in [[Special:RecentChanges]] when RCFilters are enabled.",
        "rcfilters-activefilters": "Title for the filters selection showing the active filters.",
 +      "rcfilters-advancedfilters": "Title for the buttons allowing the user to switch to the various advanced filters views.",
 +      "rcfilters-limit-title": "Title for the options to change the number of results shown.",
 +      "rcfilters-limit-shownum": "Title for the button that opens the operation to control how many results are shown. \n\nParameters: $1 - Number of results shown",
 +      "rcfilters-days-title": "Title for the options to change the number of days for the results shown.",
 +      "rcfilters-hours-title": "Title for the options to change the number of hours for the results shown.",
 +      "rcfilters-days-show-days": "Title for the button that opens the operation to control the day range for the results. \n\nParameters: $1 - Number of days shown\n{{Identical|Day}}",
 +      "rcfilters-days-show-hours": "Title for the button that opens the operation to control the hour range for the results. \n\nParameters: $1 - Number of hours shown\n{{Identical|Hour}}",
 +      "rcfilters-highlighted-filters-list": "Text for the tooltip that is displayed over highlighted results, specifying which filters the result matches in [[Special:RecentChanges]] when RCFilters are enabled. \n\nParameters: $1 - A comma separated list of matching filter names.",
        "rcfilters-quickfilters": "Label for the button that opens the saved filter settings menu in [[Special:RecentChanges]]",
        "rcfilters-quickfilters-placeholder-title": "Title for the text shown in the quick filters menu on [[Special:RecentChanges]] if the user has not saved any quick filters.",
        "rcfilters-quickfilters-placeholder-description": "Description for the text shown in the quick filters menu on [[Special:RecentChanges]] if the user has not saved any quick filters.",
        "rcfilters-savedqueries-unsetdefault": "Label for the menu option that unsets a quick filter as default in [[Special:RecentChanges]]",
        "rcfilters-savedqueries-remove": "Label for the menu option that removes a quick filter as default in [[Special:RecentChanges]]\n{{Identical|Remove}}",
        "rcfilters-savedqueries-new-name-label": "Label for the input that holds the name of the new saved filters in [[Special:RecentChanges]]\n{{Identical|Name}}",
 -      "rcfilters-savedqueries-apply-label": "Label for the button to apply saving a new filter setting in [[Special:RecentChanges]]",
 +      "rcfilters-savedqueries-new-name-placeholder": "Placeholder for the input that holds the name of the new saved filters in [[Special:RecentChanges]]",
 +      "rcfilters-savedqueries-apply-label": "Label for the button to apply saving a new filter setting in [[Special:RecentChanges]]. This is for a small popup, please try to use a short string.",
 +      "rcfilters-savedqueries-apply-and-setdefault-label": "Label for the button to apply saving a new filter setting and set it as default in [[Special:RecentChanges]]. This is for a small popup, please try to use a short string.",
        "rcfilters-savedqueries-cancel-label": "Label for the button to cancel the saving of a new quick link in [[Special:RecentChanges]]\n{{Identical|Cancel}}",
 -      "rcfilters-savedqueries-add-new-title": "Title for the popup to add new quick link in [[Special:RecentChanges]]",
 +      "rcfilters-savedqueries-add-new-title": "Title for the popup to add new quick link in [[Special:RecentChanges]]. This is for a small popup, please try to use a short string.",
        "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-show-new-changes": "Label for the button to show new changes.",
        "rcfilters-search-placeholder": "Placeholder for the filter search input.",
        "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-whatsthis": "Caption for the link that opens a popup with explanations about this filter group.",
 +      "rcfilters-filterlist-whatsthis": "Caption for the link that opens a popup with explanations about this filter group, explaining what it is and how it works.",
        "rcfilters-filterlist-feedbacklink": "Caption for the link to the feedback page about the filters beta feature.",
        "rcfilters-highlightbutton-title": "Title for the highlight button used to toggle the highlight feature on and off.",
        "rcfilters-highlightmenu-title": "Title for the highlight menu used to select the highlight color for an individual filter.",
        "rcfilters-noresults-conflict": "A message displayed in the results area when no results found because there are filters in conflict with one another.",
        "rcfilters-state-message-subset": "Tooltip shown when hovering over a filter tag when one or more broader filters that contain the hovered filter are also selected. This indicates that the hovered filter has no effect because all the results it matches are also matched by the broader filter(s).  Parameters:\n* $1 - Comma-separated string of selected broader filters that this filter is a subset of\n* $2 - Count of filters in $1, for PLURAL",
        "rcfilters-state-message-fullcoverage": "Tooltip shown when hovering over a filter tag when all the filters in its group are selected. This indicates that the hovered filter has no effect because the selected filters in the group cover all changes. Parameters:\n* $1 - Comma-separated string of selected filters in the group\n* $2 - Count of filters in $1, for PLURAL",
 -      "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-filter-unregistered-conflicts-user-experience-level": "Tooltip shown when hovering over a Unregistered filter tag, when a User Experience Level filter is also selected.\n\n\"Unregistered\" is {{msg-mw|Rcfilters-filter-unregistered-label}}.\n\n\"Experience\" is based on {{msg-mw|Rcfilters-filtergroup-userExpLevel}}.\n\nThis indicates that no results will be shown, because users matched by the User Experience Level groups are never unregistered.  Parameters:\n* $1 - Comma-separated string of selected User Experience Level filters, e.g. \"Newcomer, Experienced\"\n* $2 - Count of selected User Experience Level filters, for PLURAL",
        "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",
        "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-editsbyother-label": "Label for the filter for showing edits made by anyone other than the current user.",
        "rcfilters-filter-editsbyother-description": "Description for the filter for showing edits made by anyone other than the current user.",
        "rcfilters-filtergroup-userExpLevel": "Title for the filter group for user experience levels.",
 -      "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "Tooltip shown when hovering over a User Experience Level filter tag, when only Unregistered users are being shown.  This indicates that no results will be shown, because users matched by the User Experience Level groups are never unregistered.\n\n\"Unregistered\" is {{msg-mw|Rcfilters-filter-unregistered-label}}.",
 -      "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "Message shown in the result area when both a User Experience Level filter and the Unregistered filter are selected.  This indicates that no results will be shown because users selected by the User Experience Filter are never unregistered.\n\n\"Unregistered\" is {{msg-mw|Rcfilters-filter-unregistered-label}}.\n\n\"Experience\" is based on {{msg-mw|Rcfilters-filtergroup-userExpLevel}}.",
 +      "rcfilters-filter-user-experience-level-registered-label": "Label for the filter for showing edits made by logged-in editors.",
 +      "rcfilters-filter-user-experience-level-registered-description": "Description for the filter for showing edits made by logged-in editors.",
 +      "rcfilters-filter-user-experience-level-unregistered-label": "Label for the filter for showing edits made by anonymous editors.",
 +      "rcfilters-filter-user-experience-level-unregistered-description": "Description for the filter for showing edits made by anonymous editors.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Label for the filter for showing edits made by new editors.",
        "rcfilters-filter-user-experience-level-newcomer-description": "Description for the filter for showing edits made by new editors.",
        "rcfilters-filter-user-experience-level-learner-label": "Label for the filter for showing edits made by learning editors.",
        "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-watchlist": "Title for the watchlist filter group",
 +      "rcfilters-filtergroup-watchlist": "Title for the watchlist filter group (only available on [[Special:Recentchanges]])",
        "rcfilters-filter-watchlist-watched-label": "Label for the filter for showing changes to pages on your watchlist.",
        "rcfilters-filter-watchlist-watched-description": "Description for the filter for showing changes to pages on your watchlist.",
        "rcfilters-filter-watchlist-watchednew-label": "Label for the filter for showing new changes to pages on your watchlist.",
        "rcfilters-filter-watchlist-watchednew-description": "Description for the filter for showing new changes to pages on your watchlist.",
        "rcfilters-filter-watchlist-notwatched-label": "Label for the filter for showing changes to pages not on your watchlist.",
        "rcfilters-filter-watchlist-notwatched-description": "Description for the filter for showing changes to pages not on your watchlist.",
 +      "rcfilters-filtergroup-watchlistactivity": "Title for the watchlist activity filter group (only available on [[Special:Watchlist]])",
 +      "rcfilters-filter-watchlistactivity-unseen-label": "Label for unseen changes in the watchlist activity filter group.",
 +      "rcfilters-filter-watchlistactivity-unseen-description": "Description for unseen changes in the watchlist activity filter group.",
 +      "rcfilters-filter-watchlistactivity-seen-label": "Label for seen changes in the watchlist activity filter group.",
 +      "rcfilters-filter-watchlistactivity-seen-description": "Description for seen changes in the watchlist activity filter group.",
        "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-previousrevision-description": "Description for the filter for showing changes on previous revisions of a page.",
        "rcfilters-filter-excluded": "Label for a menu item in [[Special:RecentChanges]] noting that the item is being excluded from the results.",
        "rcfilters-tag-prefix-namespace": "Prefix for the namespace tags in [[Special:RecentChanges]]. Namespace tags use a colon (:) as prefix. Please keep this format.\n\nParameters:\n* $1 - Filter name.",
 -      "rcfilters-tag-prefix-namespace-inverted": "Prefix for the namespace inverted tags in [[Special:RecentChanges]]. Namespace tags use a colon (:) as prefix. Please keep this format.\n\nParameters:\n* $1 - Filter name.",
 +      "rcfilters-tag-prefix-namespace-inverted": "Prefix for the namespace inverted tags in [[Special:RecentChanges]]. Namespace tags use a colon (:) as prefix. Please keep this format.\n\nParameters:\n* $1 - Filter name.\n{{Identical|Not}}",
        "rcfilters-tag-prefix-tags": "Prefix for the edit tags in [[Special:RecentChanges]]. Edit tags use a hash (#) as prefix. Please keep this format.\n\nParameters:\n* $1 - Tag display name.",
 -      "rcfilters-view-tags": "Title for the tags view in [[Special:RecentChanges]]",
 +      "rcfilters-exclude-button-off": "Title for the button that excludes selected namespaces, when it is not yet active.",
 +      "rcfilters-exclude-button-on": "Title for the button that excludes selected namespaces, when it is not yet active.",
 +      "rcfilters-view-advanced-filters-label": "Label for the view switch that changes between advanced filters in [[Special:RecentChanges]]",
 +      "rcfilters-view-tags": "Title for the tags view in [[Special:RecentChanges]]\n{{Identical|Tag}}",
 +      "rcfilters-view-namespaces-tooltip": "Tooltip for the button that loads the namespace view in [[Special:RecentChanges]]",
 +      "rcfilters-view-tags-tooltip": "Tooltip for the button that loads the tags view in [[Special:RecentChanges]]",
 +      "rcfilters-view-return-to-default-tooltip": "Tooltip for the button that returns to the default filter view in [[Special:RecentChanges]]",
 +      "rcfilters-liveupdates-button": "Label for the button to enable or disable live updates on [[Special:RecentChanges]]",
 +      "rcfilters-liveupdates-button-title-on": "Title for the button to enable or disable live updates on [[Special:RecentChanges]] when the feature is ON.",
 +      "rcfilters-liveupdates-button-title-off": "Title for the button to enable or disable live updates on [[Special:RecentChanges]] when the feature is OFF.",
 +      "rcfilters-watchlist-markseen-button": "Label for the button to mark all changes as seen on [[Special:Watchlist]] when using the structured filters interface.",
 +      "rcfilters-watchlist-edit-watchlist-button": "Label for the button to edit the watched pages on [[Special:Watchlist]] when using the structured filters interface.\n\nCf. {{msg-mw|watchlisttools-edit}}.",
 +      "rcfilters-watchlist-showupdated": "Message at the top of [[Special:Watchlist]] when the Structured filters are enabled that describes what unseen changes look like.\n\nCf. {{msg-mw|wlheader-showupdated}}",
        "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",
        "rclistfromreset": "Used on [[Special:RecentChanges]] to reset a selection of a certain date range.",
        "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}}.",
        "pageswithprop-legend": "Legend for the input form on [[Special:PagesWithProp]].\n{{Identical|Page with page property}}",
        "pageswithprop-text": "Introductory text for the input form on [[Special:PagesWithProp]]",
        "pageswithprop-prop": "Label for the property name input field on [[Special:PagesWithProp]].\n{{Identical|Property name}}",
 +      "pageswithprop-reverse": "Label for the reverse checkmark field on [[Special:PagesWithProp]].",
 +      "pageswithprop-sortbyvalue": "Label for the sort by value checkmark field on [[Special:PagesWithProp]].",
        "pageswithprop-submit": "Label for the submit button on [[Special:PagesWithProp]].\n{{Identical|Go}}",
        "pageswithprop-prophidden-long": "Information shown on [[Special:PagesWithProp]] when property value is longer than 1 kilobyte.\n\nParameters:\n* $1 - size of property value in kilobytes\nSee also:\n* {{msg-mw|pageswithprop-prophidden-binary}}",
        "pageswithprop-prophidden-binary": "Information shown on [[Special:PagesWithProp]] when property value contains binary data.\n\nParameters:\n* $1 - size of property value in kilobytes\nSee also:\n* {{msg-mw|pageswithprop-prophidden-long}}",
        "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-results-login-suppressed": "Displayed as a warning when a request was processed as a logged-out user to avoid Same-Origin security bypass.",
        "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}}",
        "watching": "Text displayed when clicked on the watch tab: {{msg-mw|Watch}}. It means the wiki is adding that page to your watchlist.",
        "unwatching": "Text displayed when clicked on the unwatch tab: {{msg-mw|Unwatch}}. It means the wiki is removing that page from your watchlist.",
        "watcherrortext": "When a user clicked the watch/unwatch tab and the action did not succeed, this message is displayed.\n\nThis message is used raw and should not contain wikitext.\n\nParameters:\n* $1 - ...\nSee also:\n* {{msg-mw|Addedwatchtext}}",
 +      "watchlist-unwatch": "Symbol used for the link to unwatch a page from the watchlist.",
 +      "watchlist-unwatch-undo": "Symbol used for the link to re-watch a page that has been unwatched from the watchlist.",
        "enotif_reset": "Used in [[Special:Watchlist]].\n\nThis should be translated as \"Mark all pages '''as''' visited\".\n\nSee also:\n* {{msg-mw|Watchlist-options|fieldset}}\n* {{msg-mw|Watchlist-details|watchlist header}}\n* {{msg-mw|Wlheader-enotif|watchlist header}}",
 -      "enotif_impersonal_salutation": "Used for impersonal e-mail notifications, suitable for bulk mailing.",
 +      "enotif_impersonal_salutation": "Used for impersonal e-mail notifications, suitable for bulk mailing.\n{{Identical|User}}",
        "enotif_subject_deleted": "Email notification subject for deleted pages. Parameters:\n* $1 - page title\n* $2 - username who has deleted the page, can be used for GENDER",
        "enotif_subject_created": "Email notification subject for new pages. Parameters:\n* $1 - page title\n* $2 - username who has created the page, can be used for GENDER",
        "enotif_subject_moved": "Email notification subject for pages that get moved. Parameters:\n* $1 - page title\n* $2 - username who has moved the page, can be used for GENDER",
        "enotif_lastdiff": "Email notification text to the latest page differences. Parameters:\n* $1 - a link which points to a diff, shown as a plain link\nSee also:\n* {{msg-mw|Enotif lastvisited}}",
        "enotif_anon_editor": "User name in an email notification when referring to an anonymous user. Parameters:\n* $1 - the anonymous user name (i.e. an IP address).",
        "enotif_body": "Text of a notification email sent when a watched page has been edited or deleted.\n[[File:Screenshot_MediaWiki_e-mail_notifier.PNG|150px|right]]\n\nRefers to {{msg-mw|Helppage}}.\n\nParameters:\n*$WATCHINGUSERNAME is the username of the user receiving the notification.\n*$PAGEINTRO is the first line of the message, saying what happened. It currently can be either of:\n**{{msg-mw|Enotif body intro deleted}}\n**{{msg-mw|Enotif body intro created}}\n**{{msg-mw|Enotif body intro moved}}\n**{{msg-mw|Enotif body intro restored}}\n**{{msg-mw|Enotif body intro changed}} (for all the other cases).\n*$NEWPAGE consists of either\n**if the page is new (in older releases), {{msg-mw|Enotif newpagetext}}\n**if the page has a previous revision,\n***{{msg-mw|Enotif lastdiff}}\n***a newline\n***{{msg-mw|Enotif lastvisited}}\n*$PAGEEDITOR_EMAIL and $PAGEEDITOR_WIKI are links respectively to the email user special page and user page for the user who performed the action.\n*$PAGEEDITOR is the username of the user who performed the action.\n*$HELPPAGE is the full URL to the help page, defined by {{msg-mw|helppage}}.\n\nThe subject of the email is one of the following messages:\n*{{msg-mw|Enotif subject deleted}}\n*{{msg-mw|Enotif subject created}}\n*{{msg-mw|Enotif subject moved}}\n*{{msg-mw|Enotif subject restored}}\n*{{msg-mw|Enotif subject changed}}",
 +      "enotif_minoredit": "Possible value (it's empty string for non-minor edits) in the {{msg-mw|Enotif body|notext=1}} message.  This can use magic words like <nowiki>{{GRAMMAR}}</nowiki>.  However, it will not be parsed, so you can not use wikitext (e.g. links) that generates HTML.\n{{Identical|minoredit}}",
        "created": "{{Optional}}\nPossible value for $CHANGEDORCREATED in the following messages:\n* {{msg-mw|enotif_subject}}\n* {{msg-mw|enotif_body}}\n{{Identical|Created}}",
        "changed": "{{Optional}}\nPossible value for $CHANGEDORCREATED in the following messages:\n* {{msg-mw|Enotif subject}}\n* {{msg-mw|Enotif body}}",
        "deletepage": "Used as Submit button text.\n{{Identical|Delete page}}",
        "delete-warning-toobig": "Parameters:\n* $1 - the upper limit of number of revisions\nSee also:\n* {{msg-mw|Delete-toobig}}",
        "deleteprotected": "Used as error message when deleting the page.\n\n\"If protection keeps them from editing, they shouldn't be able to delete.\"",
        "deleting-backlinks-warning": "A warning shown when a page that is being deleted has at least one link to it or is transcluded in at least one page.",
 +      "deleting-subpages-warning": "A warning shown when a page that is being deleted has at least one subpage. $1 is the number of subpages of the page. For any number of subpages over 50, $1 will be 51.\nSee also:\n* {{msg-mw|Deleting-backlinks-warning}}",
        "rollback": "{{Identical|Rollback}}",
        "rollbacklink": "{{Doc-actionlink}}\nThis link text appears on the recent changes page to users who have the \"rollback\" right.\nThis message has a tooltip {{msg-mw|tooltip-rollback}}\n{{Identical|Rollback}}",
        "rollbacklinkcount": "{{doc-actionlink}}\nText of the rollback link showing the number of edits to be rolled back. See also {{msg-mw|rollbacklink}}.\n\nParameters:\n* $1 - the number of edits that will be rolled back. If $1 is over the value of <code>$wgShowRollbackEditCount</code> (default: 10) {{msg-mw|rollbacklinkcount-morethan}} is used.\n\nThe rollback link is displayed with a tooltip {{msg-mw|Tooltip-rollback}}",
        "cannotundelete": "Message shown when undeletion failed for some reason. Parameters:\n* $1 - the combined wikitext of messages for all errors that caused the failure",
        "undeletedpage": "Used as success message. Parameters:\n* $1 - page title, with link",
        "undelete-header": "Used in [[Special:Undelete]].",
 -      "undelete-search-title": "Page title when showing the search form in [[Special:Undelete]].\n\nSee also:\n* {{msg-mw|undelete-search-box}}\n* {{msg-mw|undelete-search-prefix}}\n* {{msg-mw|undelete-search-submit}}",
 -      "undelete-search-box": "Used as legend for the Search form in [[Special:Undelete]].\n\nSee also:\n* {{msg-mw|undelete-search-title}}\n* {{msg-mw|undelete-search-prefix}}\n* {{msg-mw|undelete-search-submit}}",
 -      "undelete-search-prefix": "Used as label for the input box in [[Special:Undelete]].\n\nSee also:\n* {{msg-mw|undelete-search-title}}\n* {{msg-mw|undelete-search-box}}\n* {{msg-mw|undelete-search-submit}}",
 -      "undelete-search-submit": "Used as Submit button text in Search form on [[Special:Undelete]].\n\nSee also:\n* {{msg-mw|undelete-search-title}}\n* {{msg-mw|undelete-search-box}}\n* {{msg-mw|undelete-search-prefix}}\n{{Identical|Search}}",
 +      "undelete-search-title": "Page title when showing the search form in [[Special:Undelete]].\n\nSee also:\n* {{msg-mw|undelete-search-box}}\n* {{msg-mw|undelete-search-prefix}}\n* {{msg-mw|undelete-search-full}}\n* {{msg-mw|undelete-search-submit}}",
 +      "undelete-search-box": "Used as legend for the Search form in [[Special:Undelete]].\n\nSee also:\n* {{msg-mw|undelete-search-title}}\n* {{msg-mw|undelete-search-prefix}}\n* {{msg-mw|undelete-search-full}}\n* {{msg-mw|undelete-search-submit}}",
 +      "undelete-search-prefix": "Used as label for the input box in [[Special:Undelete]].\n\nSee also:\n* {{msg-mw|undelete-search-title}}\n* {{msg-mw|undelete-search-box}}\n* {{msg-mw|undelete-search-submit}}\n* {{msg-mw|undelete-search-full}}",
 +      "undelete-search-full": "Used as label for the input box in [[Special:Undelete]] when full-text search is used.\n\nSee also:\n* {{msg-mw|undelete-search-title}}\n* {{msg-mw|undelete-search-box}}\n* {{msg-mw|undelete-search-submit}}\n* {{msg-mw|undelete-search-prefix}}",
 +      "undelete-search-submit": "Used as Submit button text in Search form on [[Special:Undelete]].\n\nSee also:\n* {{msg-mw|undelete-search-title}}\n* {{msg-mw|undelete-search-box}}\n* {{msg-mw|undelete-search-prefix}}\n* {{msg-mw|undelete-search-full}}\n{{Identical|Search}}",
        "undelete-no-results": "Used as Search result in [[Special:Undelete]] if no results.\n\nSee also:\n* {{msg-mw|Undeletepagetext}}",
        "undelete-filename-mismatch": "Used as error message. Parameters:\n* $1 - timestamp (date and time)",
        "undelete-bad-store-key": "Used as error message. Parameters:\n* $1 - timestamp (date and time)",
        "sp-contributions-explain": "{{optional}}",
        "sp-contributions-footer": "{{ignored}}This is the footer for users that are not anonymous or newbie on [[Special:Contributions]].",
        "sp-contributions-footer-anon": "{{ignored}}This is the footer for anonymous users on [[Special:Contributions]].",
 +      "sp-contributions-footer-anon-range": "{{ignored}}This is the footer for IP ranges on [[Special:Contributions]].",
        "sp-contributions-footer-newbies": "{{ignored}}This is the footer for newbie users on [[Special:Contributions]].",
 +      "sp-contributions-outofrange": "Message shown when a user tries to view contributions of an IP range that's too large. $1 is the numerical limit imposed on the CIDR range.",
        "whatlinkshere": "The text of the link in the toolbox (on the left, below the search menu) going to [[Special:WhatLinksHere]].\n\nSee also:\n* {{msg-mw|Whatlinkshere}}\n* {{msg-mw|Accesskey-t-whatlinkshere}}\n* {{msg-mw|Tooltip-t-whatlinkshere}}",
        "whatlinkshere-title": "Title of the special page [[Special:WhatLinksHere]]. This page appears when you click on the 'What links here' button in the toolbox. $1 is the name of the page concerned.",
        "whatlinkshere-summary": "{{doc-specialpagesummary|whatlinkshere}}",
        "whatlinkshere-links": "Used on [[Special:WhatLinksHere]]. It is a link to the WhatLinksHere page of that page.\n\nExample line:\n* [[Main Page]] ([[Special:WhatLinksHere/Main Page|{{int:whatlinkshere-links}}]])\n{{Identical|Link}}",
        "whatlinkshere-hideredirs": "Filter option in [[Special:WhatLinksHere]].\n\nParameters:\n* $1 - {{msg-mw|hide}}/{{msg-mw|show}}",
        "whatlinkshere-hidetrans": "First filter option in [[Special:WhatLinksHere]]. Parameters:\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}",
 -      "whatlinkshere-hidelinks": "Filter option in [[Special:WhatLinksHere]].",
 +      "whatlinkshere-hidelinks": "Filter option in [[Special:WhatLinksHere]].\n* $1 is the {{msg-mw|hide}} or {{msg-mw|show}}",
        "whatlinkshere-hideimages": "Filter option in [[Special:WhatLinksHere]].\n\nSee also:\n*{{msg-mw|Isimage}}\n*{{msg-mw|Media tip}}",
        "whatlinkshere-filters": "{{Identical|Filter}}",
        "whatlinkshere-submit": "Label for submit button in [[Special:WhatLinksHere]]\n{{Identical|Go}}",
        "import-nonewrevisions": "Used in [[Special:Import]].",
        "xml-error-string": "Parameters:\n* $1 - Some kind of message, perhaps name of the error?\n* $2 - line number\n* $3 - column number\n* $4 - ?? $this->mByte . $this->mContext\n* $5 - error description\nExample:\n* Import failed: XML import parse failure at line 1, col 1 (byte 3; \"- <mediawiki xml\"): Empty document",
        "import-upload": "Used on [[Special:Import]].\n\nRelated messages:\n* {{msg-mw|right-importupload}} (the user right for this)",
 -      "import-token-mismatch": "Used as error message in [[Special:Import]].\n\nSee also:\n* {{msg-mw|import-token-mismatch}}\n* {{msg-mw|import-invalid-interwiki}}\n* {{msg-mw|Importunknownsource}}\n\n{{Identical|Loss of session data}}",
 +      "import-token-mismatch": "Used as error message in [[Special:Import]].\n\nSee also:\n* {{msg-mw|import-invalid-interwiki}}\n* {{msg-mw|Importunknownsource}}\n\n{{Identical|Loss of session data}}",
        "import-invalid-interwiki": "Used as error message in [[Special:Import]].\n\nSee also:\n* {{msg-mw|import-token-mismatch}}\n* {{msg-mw|import-invalid-interwiki}}\n* {{msg-mw|Importunknownsource}}",
        "import-error-edit": "Import error message displayed when importing user has no edit rights for a page.\n\nParameters:\n* $1 - a page name\n{{Related|Import-error}}",
        "import-error-create": "Import error message displayed when importing user has no create rights for a page.\n\nParameters:\n* $1 - a page name\n{{Related|Import-error}}",
        "specialpages": "{{doc-special|SpecialPages|unlisted=1}}\nDisplay name of link to [[Special:SpecialPages]] shown on all pages in the toolbox.\n\nSee also:\n* {{msg-mw|Specialpages}}\n* {{msg-mw|Accesskey-t-specialpages}}\n* {{msg-mw|Tooltip-t-specialpages}}\n{{Identical|Special page}}",
        "specialpages-summary": "{{doc-specialpagesummary|specialpages}}",
        "specialpages-note-top": "Heading for {{msg-mw|specialpages-note}}.\n{{Identical|Legend}}",
 -      "specialpages-note": "Footer note for the [[Special:SpecialPages]] page",
 +      "specialpages-note-restricted": "Footer note for the [[Special:SpecialPages]] page\n\nCompare {{msg-mw|Mw-core-1.18-specialpages-note}}",
 +      "specialpages-note-cached": "{{ignore}}\nFooter note for the [[Special:SpecialPages]] page",
        "specialpages-group-maintenance": "{{doc-special-group|like=[[Special:DoubleRedirects]], [[Special:LonelyPages]] and [[Special:WantedPages]]}}",
        "specialpages-group-other": "{{doc-special-group|like=[[Special:AdminLinks]] and [[Special:BookSources]]}}",
        "specialpages-group-login": "{{doc-special-group|like=[[Special:UserLogin]]}}",
        "compare-invalid-title": "Used as error message in [[Special:ComparePages]].",
        "compare-title-not-exists": "Used as error message in [[Special:ComparePages]].",
        "compare-revision-not-exists": "Used as error message in [[Special:ComparePages]].",
 +      "diff-form": "The title of [[Special:Diff]]\n{{Identical|Difference}}",
 +      "diff-form-oldid": "Label for the field of the old revision in the comparison for [[Special:Diff]]",
 +      "diff-form-revid": "Label for the field of the new revision in the comparison for [[Special:Diff]]",
 +      "diff-form-submit": "Submit button on [[Special:Diff]]",
 +      "diff-form-summary": "{{doc-specialpagesummary|diff}}",
 +      "permanentlink": "The title of [[Special:PermanentLink]]\n{{Identical|Permalink}}",
 +      "permanentlink-revid": "Label for the field for the revision ID in [[Special:PermanentLink]]\n{{Identical|Revision ID}}",
 +      "permanentlink-submit": "Submit button on [[Special:PermanentLink]]",
 +      "permanentlink-summary": "{{doc-specialpagesummary|permanentlink}}",
        "dberr-problems": "This message does not allow any wiki nor html markup.",
        "dberr-again": "This message does not allow any wiki nor html markup.",
        "dberr-info": "This message does not allow any wiki nor html markup. Parameters:\n* $1 - database server name\nSee also:\n* {{msg-mw|Dberr-info-hidden}} - hides database server name",
        "mediastatistics-header-text": "Header on [[Special:MediaStatistics]] for file types that are in the text category. This includes simple text formats, including plain text formats, json, csv, and xml. Source code of compiled programming languages may be included here in the future, but isn't currently.",
        "mediastatistics-header-executable": "Header on [[Special:MediaStatistics]] for file types that are in the executable category. This includes things like source files for interpreted programming language (Shell scripts, javascript, etc).",
        "mediastatistics-header-archive": "Header on [[Special:MediaStatistics]] for file types that are in the archive category. Includes things like tar, zip, gzip etc.",
 +      "mediastatistics-header-3d": "Header on [[Special:MediaStatistics]] for file types that are in the 3D category. Includes STL files.",
        "mediastatistics-header-total": "Header on [[Special:MediaStatistics]] for a summary of all file types.",
        "json-warn-trailing-comma": "A warning message notifying that JSON text was automatically corrected by removing erroneous commas.\n\nParameters:\n* $1 - number of commas that were removed\n{{Related|Json-error}}",
        "json-error-unknown": "User error message when there’s an unknown error.\n\nThis error is shown if we received an unexpected value from PHP. See http://php.net/manual/en/function.json-last-error.php\n\nParameters:\n* $1 - integer error code\n{{Related|Json-error}}",