Merge "Drop wgPasswordSalt, deprecated since 1.24"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 23 Jul 2019 19:13:11 +0000 (19:13 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 23 Jul 2019 19:13:11 +0000 (19:13 +0000)
220 files changed:
RELEASE-NOTES-1.34
autoload.php
composer.json
docs/hooks.txt
includes/DevelopmentSettings.php
includes/EditPage.php
includes/FeedUtils.php
includes/Linker.php
includes/Title.php
includes/actions/InfoAction.php
includes/actions/RollbackAction.php
includes/actions/pagers/HistoryPager.php
includes/api/ApiCSPReport.php
includes/api/ApiEditPage.php
includes/api/ApiParse.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQuerySearch.php
includes/cache/MessageCache.php
includes/changes/CategoryMembershipChange.php
includes/changes/ChangesFeed.php
includes/changes/ChangesList.php
includes/changes/EnhancedChangesList.php
includes/changes/RCCacheEntryFactory.php
includes/changes/RecentChange.php
includes/changetags/ChangeTagsLogItem.php
includes/content/ContentHandler.php
includes/diff/DifferenceEngine.php
includes/export/WikiExporter.php
includes/export/XmlDumpWriter.php
includes/filebackend/lockmanager/LockManagerGroup.php
includes/filerepo/ForeignAPIRepo.php
includes/filerepo/file/LocalFileDeleteBatch.php
includes/installer/Installer.php
includes/installer/i18n/ar.json
includes/installer/i18n/bg.json
includes/installer/i18n/ca.json
includes/installer/i18n/pl.json
includes/installer/i18n/sh.json
includes/installer/i18n/sl.json
includes/installer/i18n/sv.json
includes/installer/i18n/tt-cyrl.json
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/CachedBagOStuff.php
includes/libs/objectcache/IStoreKeyEncoder.php
includes/libs/objectcache/MediumSpecificBagOStuff.php
includes/libs/objectcache/MultiWriteBagOStuff.php
includes/libs/objectcache/ReplicatedBagOStuff.php
includes/libs/objectcache/WANObjectCache.php
includes/logging/DeleteLogFormatter.php
includes/page/Article.php
includes/page/WikiPage.php
includes/resourceloader/MessageBlobStore.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevDelArchivedFileItem.php
includes/revisiondelete/RevDelFileItem.php
includes/revisiondelete/RevDelList.php
includes/revisiondelete/RevDelLogItem.php
includes/revisiondelete/RevDelLogList.php
includes/revisiondelete/RevDelRevisionItem.php
includes/revisiondelete/RevDelRevisionList.php
includes/revisiondelete/RevisionDeleteUser.php
includes/revisiondelete/RevisionDeleter.php
includes/revisionlist/RevisionItem.php
includes/search/AugmentPageProps.php
includes/search/ISearchResultSet.php [new file with mode: 0644]
includes/search/PaginatingSearchEngine.php
includes/search/PerRowAugmentor.php
includes/search/ResultSetAugmentor.php
includes/search/SearchDatabase.php
includes/search/SearchEngine.php
includes/search/SearchNearMatchResultSet.php
includes/search/SearchNearMatcher.php
includes/search/SearchResult.php
includes/search/SearchResultSet.php
includes/search/SqlSearchResultSet.php
includes/shell/Command.php
includes/specials/SpecialFewestrevisions.php
includes/specials/SpecialMergeHistory.php
includes/specials/SpecialRevisionDelete.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUndelete.php
includes/specials/pagers/ContribsPager.php
includes/specials/pagers/DeletedContribsPager.php
includes/watcheditem/WatchedItemQueryService.php
includes/widget/search/BasicSearchResultSetWidget.php
includes/widget/search/DidYouMeanWidget.php
includes/widget/search/InterwikiSearchResultSetWidget.php
includes/widget/search/SearchResultSetWidget.php
includes/widget/search/SimpleSearchResultSetWidget.php
languages/LanguageConverter.php
languages/classes/LanguageTr.php
languages/i18n/ar.json
languages/i18n/az.json
languages/i18n/bcc.json
languages/i18n/be-tarask.json
languages/i18n/bg.json
languages/i18n/ca.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/exif/bg.json
languages/i18n/exif/sdc.json
languages/i18n/exif/sh.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/hyw.json
languages/i18n/ia.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/ko.json
languages/i18n/lrc.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/my.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sd.json
languages/i18n/sdc.json
languages/i18n/sh.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sq.json
languages/i18n/sv.json
languages/i18n/te.json
languages/i18n/tg-cyrl.json
languages/i18n/th.json
languages/i18n/tly.json
languages/i18n/tt-cyrl.json
languages/i18n/tyv.json
languages/i18n/ur.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/cleanupSpam.php
maintenance/clearInterwikiCache.php
maintenance/copyJobQueue.php
maintenance/dictionary/mediawiki.dic
maintenance/fixDefaultJsonContentPages.php
maintenance/generateSitemap.php
maintenance/getText.php
maintenance/includes/TextPassDumper.php
maintenance/namespaceDupes.php
maintenance/populateRevisionLength.php
maintenance/preprocessDump.php
maintenance/refreshLinks.php
maintenance/storage/checkStorage.php
maintenance/storage/recompressTracked.php
maintenance/userDupes.inc
maintenance/userOptions.php
maintenance/view.php
resources/Resources.php
resources/lib/foreign-resources.yaml
resources/lib/ooui/History.md
resources/lib/ooui/oojs-ui-apex.js
resources/lib/ooui/oojs-ui-core-apex.css
resources/lib/ooui/oojs-ui-core-wikimediaui.css
resources/lib/ooui/oojs-ui-core.js
resources/lib/ooui/oojs-ui-toolbars-apex.css
resources/lib/ooui/oojs-ui-toolbars-wikimediaui.css
resources/lib/ooui/oojs-ui-toolbars.js
resources/lib/ooui/oojs-ui-widgets-apex.css
resources/lib/ooui/oojs-ui-widgets-wikimediaui.css
resources/lib/ooui/oojs-ui-widgets.js
resources/lib/ooui/oojs-ui-wikimediaui.js
resources/lib/ooui/oojs-ui-windows-apex.css
resources/lib/ooui/oojs-ui-windows-wikimediaui.css
resources/lib/ooui/oojs-ui-windows.js
resources/lib/ooui/themes/apex/icons-alerts.json
resources/lib/ooui/themes/apex/icons-user.json
resources/lib/ooui/themes/wikimediaui/icons-alerts.json
resources/lib/ooui/themes/wikimediaui/icons-user.json
resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/search-invert.png
resources/lib/ooui/themes/wikimediaui/images/icons/search-invert.svg
resources/lib/ooui/themes/wikimediaui/images/icons/search-progressive.png
resources/lib/ooui/themes/wikimediaui/images/icons/search-progressive.svg
resources/lib/ooui/themes/wikimediaui/images/icons/search.png
resources/lib/ooui/themes/wikimediaui/images/icons/search.svg
resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.svg [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.png [new file with mode: 0644]
resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.svg [new file with mode: 0644]
resources/src/mediawiki.interface.helpers.styles.less
tests/phpunit/includes/RevisionDbTestBase.php
tests/phpunit/includes/api/ApiCSPReportTest.php [new file with mode: 0644]
tests/phpunit/includes/api/ApiQuerySearchTest.php
tests/phpunit/includes/block/BlockManagerTest.php
tests/phpunit/includes/cache/MessageCacheTest.php
tests/phpunit/includes/libs/objectcache/CachedBagOStuffTest.php
tests/phpunit/includes/libs/objectcache/MultiWriteBagOStuffTest.php
tests/phpunit/includes/libs/objectcache/WANObjectCacheTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderFilePathTest.php [deleted file]
tests/phpunit/includes/search/SearchEngineTest.php
tests/phpunit/includes/watcheditem/WatchedItemStoreUnitTest.php
tests/phpunit/maintenance/backup_PageTest.php
tests/phpunit/mocks/search/MockSearchEngine.php
tests/phpunit/mocks/search/MockSearchResultSet.php
tests/phpunit/unit/includes/objectcache/RedisBagOStuffTest.php
tests/phpunit/unit/includes/resourceloader/ResourceLoaderFilePathTest.php [new file with mode: 0644]
tests/selenium/specs/rollback.js

index 2809d38..7a24818 100644 (file)
@@ -84,6 +84,8 @@ For notes on 1.33.x and older releases, see HISTORY.
   strings like "5 days ago" instead of "5 days 13 hours ago".
 * (T220163) Added SpecialMuteModifyFormFields hook to allow extensions
   to add fields to Special:Mute.
+* (T100896) Skin authors can define custom OOUI themes using OOUIThemePaths.
+  See <https://www.mediawiki.org/wiki/OOUI/Themes> for details.
 
 === External library changes in 1.34 ===
 
@@ -92,7 +94,7 @@ For notes on 1.33.x and older releases, see HISTORY.
 
 ==== Changed external libraries ====
 * Updated Mustache from 1.0.0 to v3.0.1.
-* Updated OOUI from v0.31.3 to v0.33.2.
+* Updated OOUI from v0.31.3 to v0.33.4.
 * Updated composer/semver from 1.4.2 to 1.5.0.
 * Updated composer/spdx-licenses from 1.4.0 to 1.5.1 (dev-only).
 * Updated mediawiki/codesniffer from 25.0.0 to 26.0.0 (dev-only).
@@ -380,6 +382,7 @@ because of Phabricator reports.
   and should no longer be passed. Search engine implemenations should be
   responsible for carrying relevant information needed for highlighting with
   their own SearchResultSet/SearchResult sub-classes.
+* SearchResultSet::free() method is deprecated.
 * SearchEngine::$searchTerms protected field is deprecated. Moved to
   SearchDatabase.
 * The use of the $terms param in the ShowSearchHit and ShowSearchHitTitle
index 5410bb8..e6e6504 100644 (file)
@@ -659,6 +659,7 @@ $wgAutoloadLocalClasses = [
        'IP' => __DIR__ . '/includes/libs/IP.php',
        'IPTC' => __DIR__ . '/includes/media/IPTC.php',
        'IRCColourfulRCFeedFormatter' => __DIR__ . '/includes/rcfeed/IRCColourfulRCFeedFormatter.php',
+       'ISearchResultSet' => __DIR__ . '/includes/search/ISearchResultSet.php',
        'IStoreKeyEncoder' => __DIR__ . '/includes/libs/objectcache/IStoreKeyEncoder.php',
        'IcuCollation' => __DIR__ . '/includes/collation/IcuCollation.php',
        'IdentityCollation' => __DIR__ . '/includes/collation/IdentityCollation.php',
index dc6d091..98e7ebf 100644 (file)
@@ -27,7 +27,7 @@
                "ext-xml": "*",
                "guzzlehttp/guzzle": "6.3.3",
                "liuggio/statsd-php-client": "1.0.18",
-               "oojs/oojs-ui": "0.33.3",
+               "oojs/oojs-ui": "0.33.4",
                "pear/mail": "1.4.1",
                "pear/mail_mime": "1.10.2",
                "pear/net_smtp": "1.8.1",
index 8e274ed..d832012 100644 (file)
@@ -1527,6 +1527,7 @@ $user: User the list is being fetched for
 &$skin: Skin object to be used with the list
 &$list: List object (defaults to NULL, change it to an object instance and
   return false override the list derivative used)
+$groups Array of ChangesListFilterGroup objects (added in 1.34)
 
 'FileDeleteComplete': When a file is deleted.
 &$file: reference to the deleted file
@@ -3304,8 +3305,8 @@ $opts: Array: key => value of hidden options for inclusion in custom forms
 
 'SpecialSearchResults': Called before search result display
 $term: string of search term
-&$titleMatches: empty or SearchResultSet object
-&$textMatches: empty or SearchResultSet object
+&$titleMatches: empty or ISearchResultSet object
+&$textMatches: empty or ISearchResultSet object
 
 'SpecialSearchResultsPrepend': Called immediately before returning HTML
 on the search results page.  Useful for including an external search
index d2f26b3..103ff45 100644 (file)
@@ -57,3 +57,6 @@ unset( $logDir );
 // Disable rate-limiting to allow integration tests to run unthrottled
 // in CI and for devs locally (T225796)
 $wgRateLimits = [];
+
+// Disable legacy javascript globals in CI and for devs (T72470)
+$wgLegacyJavaScriptGlobals = false;
index d27ef9c..f288327 100644 (file)
@@ -25,6 +25,7 @@ use MediaWiki\EditPage\TextboxBuilder;
 use MediaWiki\EditPage\TextConflictHelper;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\ScopedCallback;
 
 /**
@@ -1222,8 +1223,8 @@ class EditPage {
                                # the revisions exist and they were not deleted.
                                # Otherwise, $content will be left as-is.
                                if ( !is_null( $undorev ) && !is_null( $oldrev ) &&
-                                       !$undorev->isDeleted( Revision::DELETED_TEXT ) &&
-                                       !$oldrev->isDeleted( Revision::DELETED_TEXT )
+                                       !$undorev->isDeleted( RevisionRecord::DELETED_TEXT ) &&
+                                       !$oldrev->isDeleted( RevisionRecord::DELETED_TEXT )
                                ) {
                                        if ( WikiPage::hasDifferencesOutsideMainSlot( $undorev, $oldrev )
                                                || !$this->isSupportedContentModel( $oldrev->getContentModel() )
@@ -1245,7 +1246,7 @@ class EditPage {
                                        }
 
                                        if ( $undoMsg === null ) {
-                                               $oldContent = $this->page->getContent( Revision::RAW );
+                                               $oldContent = $this->page->getContent( RevisionRecord::RAW );
                                                $popts = ParserOptions::newFromUserAndLang(
                                                        $user, MediaWikiServices::getInstance()->getContentLanguage() );
                                                $newContent = $content->preSaveTransform( $this->mTitle, $user, $popts );
@@ -1371,7 +1372,7 @@ class EditPage {
                        $handler = ContentHandler::getForModelID( $this->contentModel );
                        return $handler->makeEmptyContent();
                }
-               $content = $revision->getContent( Revision::FOR_THIS_USER, $user );
+               $content = $revision->getContent( RevisionRecord::FOR_THIS_USER, $user );
                return $content;
        }
 
@@ -1405,7 +1406,7 @@ class EditPage {
         */
        protected function getCurrentContent() {
                $rev = $this->page->getRevision();
-               $content = $rev ? $rev->getContent( Revision::RAW ) : null;
+               $content = $rev ? $rev->getContent( RevisionRecord::RAW ) : null;
 
                if ( $content === false || $content === null ) {
                        $handler = ContentHandler::getForModelID( $this->contentModel );
@@ -1496,7 +1497,7 @@ class EditPage {
                }
 
                $parserOptions = ParserOptions::newFromUser( $user );
-               $content = $page->getContent( Revision::RAW );
+               $content = $page->getContent( RevisionRecord::RAW );
 
                if ( !$content ) {
                        // TODO: somehow show a warning to the user!
@@ -3139,12 +3140,12 @@ ERROR;
                                if ( $revision ) {
                                        // Let sysop know that this will make private content public if saved
 
-                                       if ( !$revision->userCan( Revision::DELETED_TEXT, $user ) ) {
+                                       if ( !$revision->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                                                $out->wrapWikiMsg(
                                                        "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                                        'rev-deleted-text-permission'
                                                );
-                                       } elseif ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
+                                       } elseif ( $revision->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                                                $out->wrapWikiMsg(
                                                        "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                                        'rev-deleted-text-view'
index 59efc98..8efae4f 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Feed
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Helper functions for feeds
  *
@@ -68,7 +70,7 @@ class FeedUtils {
                return self::formatDiffRow( $titleObj,
                        $row->rc_last_oldid, $row->rc_this_oldid,
                        $timestamp,
-                       $row->rc_deleted & Revision::DELETED_COMMENT
+                       $row->rc_deleted & RevisionRecord::DELETED_COMMENT
                                ? wfMessage( 'rev-deleted-comment' )->escaped()
                                : CommentStore::getStore()->getComment( 'rc_comment', $row )->text,
                        $actiontext
index f20795d..db3e2f5 100644 (file)
@@ -21,6 +21,7 @@
  */
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 
 /**
  * Some internal bits split of from Skin.php. These functions are used
@@ -1093,15 +1094,15 @@ class Linker {
         * @return string HTML fragment
         */
        public static function revUserLink( $rev, $isPublic = false ) {
-               if ( $rev->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_USER ) && $isPublic ) {
                        $link = wfMessage( 'rev-deleted-user' )->escaped();
-               } elseif ( $rev->userCan( Revision::DELETED_USER ) ) {
-                       $link = self::userLink( $rev->getUser( Revision::FOR_THIS_USER ),
-                               $rev->getUserText( Revision::FOR_THIS_USER ) );
+               } elseif ( $rev->userCan( RevisionRecord::DELETED_USER ) ) {
+                       $link = self::userLink( $rev->getUser( RevisionRecord::FOR_THIS_USER ),
+                               $rev->getUserText( RevisionRecord::FOR_THIS_USER ) );
                } else {
                        $link = wfMessage( 'rev-deleted-user' )->escaped();
                }
-               if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_USER ) ) {
                        return '<span class="history-deleted">' . $link . '</span>';
                }
                return $link;
@@ -1116,11 +1117,11 @@ class Linker {
         * @return string HTML
         */
        public static function revUserTools( $rev, $isPublic = false, $useParentheses = true ) {
-               if ( $rev->userCan( Revision::DELETED_USER ) &&
-                       ( !$rev->isDeleted( Revision::DELETED_USER ) || !$isPublic )
+               if ( $rev->userCan( RevisionRecord::DELETED_USER ) &&
+                       ( !$rev->isDeleted( RevisionRecord::DELETED_USER ) || !$isPublic )
                ) {
-                       $userId = $rev->getUser( Revision::FOR_THIS_USER );
-                       $userText = $rev->getUserText( Revision::FOR_THIS_USER );
+                       $userId = $rev->getUser( RevisionRecord::FOR_THIS_USER );
+                       $userText = $rev->getUserText( RevisionRecord::FOR_THIS_USER );
                        if ( $userId || (string)$userText !== '' ) {
                                $link = self::userLink( $userId, $userText )
                                        . self::userToolLinks( $userId, $userText, false, 0, null,
@@ -1132,7 +1133,7 @@ class Linker {
                        $link = wfMessage( 'rev-deleted-user' )->escaped();
                }
 
-               if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_USER ) ) {
                        return ' <span class="history-deleted mw-userlink">' . $link . '</span>';
                }
                return $link;
@@ -1571,18 +1572,18 @@ class Linker {
        public static function revComment( Revision $rev, $local = false, $isPublic = false,
                $useParentheses = true
        ) {
-               if ( $rev->getComment( Revision::RAW ) == "" ) {
+               if ( $rev->getComment( RevisionRecord::RAW ) == "" ) {
                        return "";
                }
-               if ( $rev->isDeleted( Revision::DELETED_COMMENT ) && $isPublic ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_COMMENT ) && $isPublic ) {
                        $block = " <span class=\"comment\">" . wfMessage( 'rev-deleted-comment' )->escaped() . "</span>";
-               } elseif ( $rev->userCan( Revision::DELETED_COMMENT ) ) {
-                       $block = self::commentBlock( $rev->getComment( Revision::FOR_THIS_USER ),
+               } elseif ( $rev->userCan( RevisionRecord::DELETED_COMMENT ) ) {
+                       $block = self::commentBlock( $rev->getComment( RevisionRecord::FOR_THIS_USER ),
                                $rev->getTitle(), $local, null, $useParentheses );
                } else {
                        $block = " <span class=\"comment\">" . wfMessage( 'rev-deleted-comment' )->escaped() . "</span>";
                }
-               if ( $rev->isDeleted( Revision::DELETED_COMMENT ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_COMMENT ) ) {
                        return " <span class=\"history-deleted comment\">$block</span>";
                }
                return $block;
@@ -1875,10 +1876,10 @@ class Linker {
                $editCount = 0;
                $moreRevs = false;
                foreach ( $res as $row ) {
-                       if ( $rev->getUserText( Revision::RAW ) != $row->rev_user_text ) {
+                       if ( $rev->getUserText( RevisionRecord::RAW ) != $row->rev_user_text ) {
                                if ( $verify &&
-                                       ( $row->rev_deleted & Revision::DELETED_TEXT
-                                               || $row->rev_deleted & Revision::DELETED_USER
+                                       ( $row->rev_deleted & RevisionRecord::DELETED_TEXT
+                                               || $row->rev_deleted & RevisionRecord::DELETED_USER
                                ) ) {
                                        // If the user or the text of the revision we might rollback
                                        // to is deleted in some way we can't rollback. Similar to
@@ -2107,7 +2108,7 @@ class Linker {
                        return '';
                }
 
-               if ( !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
+               if ( !$rev->userCan( RevisionRecord::DELETED_RESTRICTED, $user ) ) {
                        return self::revDeleteLinkDisabled( $canHide ); // revision was hidden from sysops
                }
                $prefixedDbKey = MediaWikiServices::getInstance()->getTitleFormatter()->
@@ -2130,7 +2131,7 @@ class Linker {
                        ];
                }
                return self::revDeleteLink( $query,
-                       $rev->isDeleted( Revision::DELETED_RESTRICTED ), $canHide );
+                       $rev->isDeleted( RevisionRecord::DELETED_RESTRICTED ), $canHide );
        }
 
        /**
index 95ccd9a..12d6641 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use MediaWiki\Permissions\PermissionManager;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Assert\Assert;
 use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
@@ -3947,17 +3948,18 @@ class Title implements LinkTarget, IDBAccessObject {
                if ( $old->getId() === $new->getId() ) {
                        return ( $old_cmp === '>' && $new_cmp === '<' ) ?
                                [] :
-                               [ $old->getUserText( Revision::RAW ) ];
+                               [ $old->getUserText( RevisionRecord::RAW ) ];
                } elseif ( $old->getId() === $new->getParentId() ) {
                        if ( $old_cmp === '>=' && $new_cmp === '<=' ) {
-                               $authors[] = $old->getUserText( Revision::RAW );
-                               if ( $old->getUserText( Revision::RAW ) != $new->getUserText( Revision::RAW ) ) {
-                                       $authors[] = $new->getUserText( Revision::RAW );
+                               $authors[] = $oldUserText = $old->getUserText( RevisionRecord::RAW );
+                               $newUserText = $new->getUserText( RevisionRecord::RAW );
+                               if ( $oldUserText != $newUserText ) {
+                                       $authors[] = $newUserText;
                                }
                        } elseif ( $old_cmp === '>=' ) {
-                               $authors[] = $old->getUserText( Revision::RAW );
+                               $authors[] = $old->getUserText( RevisionRecord::RAW );
                        } elseif ( $new_cmp === '<=' ) {
-                               $authors[] = $new->getUserText( Revision::RAW );
+                               $authors[] = $new->getUserText( RevisionRecord::RAW );
                        }
                        return $authors;
                }
index f8ba08c..279c13b 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\Database;
 
 /**
@@ -543,7 +544,7 @@ class InfoAction extends FormlessAction {
                $batch = new LinkBatch;
 
                if ( $firstRev ) {
-                       $firstRevUser = $firstRev->getUserText( Revision::FOR_THIS_USER );
+                       $firstRevUser = $firstRev->getUserText( RevisionRecord::FOR_THIS_USER );
                        if ( $firstRevUser !== '' ) {
                                $firstRevUserTitle = Title::makeTitle( NS_USER, $firstRevUser );
                                $batch->addObj( $firstRevUserTitle );
@@ -552,7 +553,7 @@ class InfoAction extends FormlessAction {
                }
 
                if ( $lastRev ) {
-                       $lastRevUser = $lastRev->getUserText( Revision::FOR_THIS_USER );
+                       $lastRevUser = $lastRev->getUserText( RevisionRecord::FOR_THIS_USER );
                        if ( $lastRevUser !== '' ) {
                                $lastRevUserTitle = Title::makeTitle( NS_USER, $lastRevUser );
                                $batch->addObj( $lastRevUserTitle );
index e2fc265..519da61 100644 (file)
@@ -20,6 +20,8 @@
  * @ingroup Actions
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * User interface for the rollback action
  *
@@ -167,8 +169,8 @@ class RollbackAction extends FormAction {
                $this->getOutput()->addHTML(
                        $this->msg( 'rollback-success' )
                                ->rawParams( $old, $new )
-                               ->params( $current->getUserText( Revision::FOR_THIS_USER, $user ) )
-                               ->params( $target->getUserText( Revision::FOR_THIS_USER, $user ) )
+                               ->params( $current->getUserText( RevisionRecord::FOR_THIS_USER, $user ) )
+                               ->params( $target->getUserText( RevisionRecord::FOR_THIS_USER, $user ) )
                                ->parseAsBlock()
                );
 
index 99c57e1..c5c090d 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\RevisionRecord;
 
 /**
  * @ingroup Pager
@@ -338,7 +339,9 @@ class HistoryPager extends ReverseChronologicalPager {
                        $this->preventClickjacking();
                        // If revision was hidden from sysops and we don't need the checkbox
                        // for anything else, disable it
-                       if ( !$this->showTagEditUI && !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
+                       if ( !$this->showTagEditUI
+                               && !$rev->userCan( RevisionRecord::DELETED_RESTRICTED, $user )
+                       ) {
                                $del = Xml::check( 'deleterevisions', false, [ 'disabled' => 'disabled' ] );
                        // Otherwise, enable the checkbox...
                        } else {
@@ -348,14 +351,14 @@ class HistoryPager extends ReverseChronologicalPager {
                // User can only view deleted revisions...
                } elseif ( $rev->getVisibility() && $user->isAllowed( 'deletedhistory' ) ) {
                        // If revision was hidden from sysops, disable the link
-                       if ( !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
+                       if ( !$rev->userCan( RevisionRecord::DELETED_RESTRICTED, $user ) ) {
                                $del = Linker::revDeleteLinkDisabled( false );
                        // Otherwise, show the link...
                        } else {
                                $query = [ 'type' => 'revision',
                                        'target' => $this->getTitle()->getPrefixedDBkey(), 'ids' => $rev->getId() ];
                                $del .= Linker::revDeleteLink( $query,
-                                       $rev->isDeleted( Revision::DELETED_RESTRICTED ), false );
+                                       $rev->isDeleted( RevisionRecord::DELETED_RESTRICTED ), false );
                        }
                }
                if ( $del ) {
@@ -409,8 +412,8 @@ class HistoryPager extends ReverseChronologicalPager {
                                }
                        }
 
-                       if ( !$rev->isDeleted( Revision::DELETED_TEXT )
-                               && !$prevRev->isDeleted( Revision::DELETED_TEXT )
+                       if ( !$rev->isDeleted( RevisionRecord::DELETED_TEXT )
+                               && !$prevRev->isDeleted( RevisionRecord::DELETED_TEXT )
                        ) {
                                # Create undo tooltip for the first (=latest) line only
                                $undoTooltip = $latest
@@ -491,7 +494,9 @@ class HistoryPager extends ReverseChronologicalPager {
        function curLink( $rev ) {
                $cur = $this->historyPage->message['cur'];
                $latest = $this->getWikiPage()->getLatest();
-               if ( $latest === $rev->getId() || !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
+               if ( $latest === $rev->getId()
+                       || !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() )
+               ) {
                        return $cur;
                } else {
                        return MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
@@ -539,8 +544,8 @@ class HistoryPager extends ReverseChronologicalPager {
 
                $nextRev = new Revision( $next, 0, $this->getTitle() );
 
-               if ( !$prevRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
-                       || !$nextRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
+               if ( !$prevRev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() )
+                       || !$nextRev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() )
                ) {
                        return $last;
                }
@@ -579,7 +584,7 @@ class HistoryPager extends ReverseChronologicalPager {
                                $checkmark = [ 'checked' => 'checked' ];
                        } else {
                                # Check visibility of old revisions
-                               if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
+                               if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() ) ) {
                                        $radio['disabled'] = 'disabled';
                                        $checkmark = []; // We will check the next possible one
                                } elseif ( !$this->oldIdChecked ) {
index f53d2b9..be2da34 100644 (file)
@@ -54,7 +54,7 @@ class ApiCSPReport extends ApiBase {
                        // XXX Is it ok to put untrusted data into log??
                        'csp-report' => $report,
                        'method' => __METHOD__,
-                       'user_id' => $this->getUser()->getId() || 'logged-out',
+                       'user_id' => $this->getUser()->getId() ?: 'logged-out',
                        'user-agent' => $userAgent,
                        'source' => $this->getParameter( 'source' ),
                ] );
index 96aea04..3f63a00 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * A module that allows for editing and creating pages.
  *
@@ -52,7 +54,7 @@ class ApiEditPage extends ApiBase {
                                $oldTitle = $titleObj;
 
                                $titles = Revision::newFromTitle( $oldTitle, false, Revision::READ_LATEST )
-                                       ->getContent( Revision::FOR_THIS_USER, $user )
+                                       ->getContent( RevisionRecord::FOR_THIS_USER, $user )
                                        ->getRedirectChain();
                                // array_shift( $titles );
 
@@ -193,14 +195,14 @@ class ApiEditPage extends ApiBase {
                                $undoafterRev = Revision::newFromId( $params['undoafter'] );
                        }
                        $undoRev = Revision::newFromId( $params['undo'] );
-                       if ( is_null( $undoRev ) || $undoRev->isDeleted( Revision::DELETED_TEXT ) ) {
+                       if ( is_null( $undoRev ) || $undoRev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                                $this->dieWithError( [ 'apierror-nosuchrevid', $params['undo'] ] );
                        }
 
                        if ( $params['undoafter'] == 0 ) {
                                $undoafterRev = $undoRev->getPrevious();
                        }
-                       if ( is_null( $undoafterRev ) || $undoafterRev->isDeleted( Revision::DELETED_TEXT ) ) {
+                       if ( is_null( $undoafterRev ) || $undoafterRev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                                $this->dieWithError( [ 'apierror-nosuchrevid', $params['undoafter'] ] );
                        }
 
index 84fff96..a7390e6 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 
 /**
  * @ingroup API
@@ -105,7 +106,7 @@ class ApiParse extends ApiBase {
                                }
 
                                $this->checkTitleUserPermissions( $rev->getTitle(), 'read' );
-                               if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
+                               if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() ) ) {
                                        $this->dieWithError(
                                                [ 'apierror-permissiondenied', $this->msg( 'action-deletedtext' ) ]
                                        );
@@ -562,23 +563,23 @@ class ApiParse extends ApiBase {
                WikiPage $page, $popts, $suppressCache, $pageId, $rev, $getContent
        ) {
                $revId = $rev ? $rev->getId() : null;
-               $isDeleted = $rev && $rev->isDeleted( Revision::DELETED_TEXT );
+               $isDeleted = $rev && $rev->isDeleted( RevisionRecord::DELETED_TEXT );
 
                if ( $getContent || $this->section !== false || $isDeleted ) {
                        if ( $rev ) {
-                               $this->content = $rev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+                               $this->content = $rev->getContent( RevisionRecord::FOR_THIS_USER, $this->getUser() );
                                if ( !$this->content ) {
                                        $this->dieWithError( [ 'apierror-missingcontent-revid', $revId ] );
                                }
                        } else {
-                               $this->content = $page->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+                               $this->content = $page->getContent( RevisionRecord::FOR_THIS_USER, $this->getUser() );
                                if ( !$this->content ) {
                                        $this->dieWithError( [ 'apierror-missingcontent-pageid', $page->getId() ] );
                                }
                        }
                        $this->contentIsDeleted = $isDeleted;
                        $this->contentIsSuppressed = $rev &&
-                               $rev->isDeleted( Revision::DELETED_TEXT | Revision::DELETED_RESTRICTED );
+                               $rev->isDeleted( RevisionRecord::DELETED_TEXT | RevisionRecord::DELETED_RESTRICTED );
                }
 
                if ( $this->section !== false ) {
index 4fbc157..a6366f2 100644 (file)
@@ -22,6 +22,7 @@
 
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Storage\NameTableAccessException;
+use MediaWiki\Storage\RevisionRecord;
 
 /**
  * Query module to enumerate all deleted revisions.
@@ -197,9 +198,9 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        // (shouldn't be able to get here without 'deletedhistory', but
                        // check it again just in case)
                        if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                               $bitmask = Revision::DELETED_USER;
+                               $bitmask = RevisionRecord::DELETED_USER;
                        } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                               $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+                               $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
                        } else {
                                $bitmask = 0;
                        }
@@ -288,11 +289,11 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                                $rev['parentid'] = (int)$row->ar_parent_id;
                        }
                        if ( $fld_user || $fld_userid ) {
-                               if ( $row->ar_deleted & Revision::DELETED_USER ) {
+                               if ( $row->ar_deleted & RevisionRecord::DELETED_USER ) {
                                        $rev['userhidden'] = true;
                                        $anyHidden = true;
                                }
-                               if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_USER, $user ) ) {
+                               if ( Revision::userCanBitfield( $row->ar_deleted, RevisionRecord::DELETED_USER, $user ) ) {
                                        if ( $fld_user ) {
                                                $rev['user'] = $row->ar_user_text;
                                        }
@@ -303,11 +304,11 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        }
 
                        if ( $fld_comment || $fld_parsedcomment ) {
-                               if ( $row->ar_deleted & Revision::DELETED_COMMENT ) {
+                               if ( $row->ar_deleted & RevisionRecord::DELETED_COMMENT ) {
                                        $rev['commenthidden'] = true;
                                        $anyHidden = true;
                                }
-                               if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_COMMENT, $user ) ) {
+                               if ( Revision::userCanBitfield( $row->ar_deleted, RevisionRecord::DELETED_COMMENT, $user ) ) {
                                        $comment = $commentStore->getComment( 'ar_comment', $row )->text;
                                        if ( $fld_comment ) {
                                                $rev['comment'] = $comment;
@@ -326,11 +327,11 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                                $rev['len'] = $row->ar_len;
                        }
                        if ( $fld_sha1 ) {
-                               if ( $row->ar_deleted & Revision::DELETED_TEXT ) {
+                               if ( $row->ar_deleted & RevisionRecord::DELETED_TEXT ) {
                                        $rev['sha1hidden'] = true;
                                        $anyHidden = true;
                                }
-                               if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_TEXT, $user ) ) {
+                               if ( Revision::userCanBitfield( $row->ar_deleted, RevisionRecord::DELETED_TEXT, $user ) ) {
                                        if ( $row->ar_sha1 != '' ) {
                                                $rev['sha1'] = Wikimedia\base_convert( $row->ar_sha1, 36, 16, 40 );
                                        } else {
@@ -339,11 +340,11 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                                }
                        }
                        if ( $fld_content ) {
-                               if ( $row->ar_deleted & Revision::DELETED_TEXT ) {
+                               if ( $row->ar_deleted & RevisionRecord::DELETED_TEXT ) {
                                        $rev['texthidden'] = true;
                                        $anyHidden = true;
                                }
-                               if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_TEXT, $user ) ) {
+                               if ( Revision::userCanBitfield( $row->ar_deleted, RevisionRecord::DELETED_TEXT, $user ) ) {
                                        ApiResult::setContentValue( $rev, 'text', Revision::getRevisionText( $row, 'ar_' ) );
                                }
                        }
@@ -358,7 +359,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                                }
                        }
 
-                       if ( $anyHidden && ( $row->ar_deleted & Revision::DELETED_RESTRICTED ) ) {
+                       if ( $anyHidden && ( $row->ar_deleted & RevisionRecord::DELETED_RESTRICTED ) ) {
                                $rev['suppressed'] = true;
                        }
 
index 23f702c..9228d9a 100644 (file)
@@ -180,13 +180,13 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                $canAddInterwiki = (bool)$params['enablerewrites'] && ( $resultPageSet === null );
                if ( $canAddInterwiki ) {
                        $this->addInterwikiResults( $matches, $apiResult, $prop, 'additional',
-                               SearchResultSet::INLINE_RESULTS );
+                               ISearchResultSet::INLINE_RESULTS );
                }
 
                // Interwiki results outside main result set
                if ( $interwiki && $resultPageSet === null ) {
                        $this->addInterwikiResults( $matches, $apiResult, $prop, 'interwiki',
-                               SearchResultSet::SECONDARY_RESULTS );
+                               ISearchResultSet::SECONDARY_RESULTS );
                }
 
                if ( $resultPageSet === null ) {
@@ -278,7 +278,7 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
 
        /**
         * Add interwiki results as a section in query results.
-        * @param SearchResultSet $matches
+        * @param ISearchResultSet $matches
         * @param ApiResult       $apiResult
         * @param array           $prop Props to extract (as keys)
         * @param string          $section Section name where results would go
@@ -286,7 +286,7 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
         * @return int|null Number of total hits in the data or null if none was produced
         */
        private function addInterwikiResults(
-               SearchResultSet $matches, ApiResult $apiResult, $prop,
+               ISearchResultSet $matches, ApiResult $apiResult, $prop,
                $section, $type
        ) {
                $totalhits = null;
index b0716b1..a8bcfc6 100644 (file)
@@ -525,9 +525,8 @@ class MessageCache {
                        __METHOD__ . "($code)-big"
                );
                foreach ( $res as $row ) {
-                       $name = $this->contLang->lcfirst( $row->page_title );
                        // Include entries/stubs for all keys in $mostused in adaptive mode
-                       if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $name, $overridable ) ) {
+                       if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $row->page_title, $overridable ) ) {
                                $cache[$row->page_title] = '!TOO BIG';
                        }
                        // At least include revision ID so page changes are reflected in the hash
@@ -549,9 +548,8 @@ class MessageCache {
                        $revQuery['joins']
                );
                foreach ( $res as $row ) {
-                       $name = $this->contLang->lcfirst( $row->page_title );
                        // Include entries/stubs for all keys in $mostused in adaptive mode
-                       if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $name, $overridable ) ) {
+                       if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $row->page_title, $overridable ) ) {
                                try {
                                        $rev = $revisionStore->newRevisionFromRow( $row );
                                        $content = $rev->getContent( MediaWiki\Revision\SlotRecord::MAIN );
@@ -592,14 +590,17 @@ class MessageCache {
        }
 
        /**
-        * @param string $name Message name with lowercase first letter
+        * @param string $name Message name (possibly with /code suffix)
         * @param array $overridable Map of (key => unused) for software-defined messages
         * @return bool
         */
        private function isMainCacheable( $name, array $overridable ) {
+               // Convert first letter to lowercase, and strip /code suffix
+               $name = $this->contLang->lcfirst( $name );
+               $msg = preg_replace( '/\/[a-z0-9-]{2,}$/', '', $name );
                // Include common conversion table pages. This also avoids problems with
                // Installer::parse() bailing out due to disallowed DB queries (T207979).
-               return ( isset( $overridable[$name] ) || strpos( $name, 'conversiontable/' ) === 0 );
+               return ( isset( $overridable[$msg] ) || strpos( $name, 'conversiontable/' ) === 0 );
        }
 
        /**
@@ -1069,8 +1070,7 @@ class MessageCache {
                        );
                } else {
                        // Message page either does not exist or does not override a software message
-                       $name = $this->contLang->lcfirst( $title );
-                       if ( !$this->isMainCacheable( $name, $this->overridable ) ) {
+                       if ( !$this->isMainCacheable( $title, $this->overridable ) ) {
                                // Message page does not override any software-defined message. A custom
                                // message might be defined to have content or settings specific to the wiki.
                                // Load the message page, utilizing the individual message cache as needed.
index f1e61bb..2ef9c9f 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Helper class for category membership changes
  *
@@ -158,7 +161,7 @@ class CategoryMembershipChange {
                $revision,
                $added
        ) {
-               $deleted = $revision ? $revision->getVisibility() & Revision::SUPPRESSED_USER : 0;
+               $deleted = $revision ? $revision->getVisibility() & RevisionRecord::SUPPRESSED_USER : 0;
                $newRevId = $revision ? $revision->getId() : 0;
 
                /**
@@ -214,9 +217,9 @@ class CategoryMembershipChange {
         */
        private function getUser() {
                if ( $this->revision ) {
-                       $userId = $this->revision->getUser( Revision::RAW );
+                       $userId = $this->revision->getUser( RevisionRecord::RAW );
                        if ( $userId === 0 ) {
-                               return User::newFromName( $this->revision->getUserText( Revision::RAW ), false );
+                               return User::newFromName( $this->revision->getUserText( RevisionRecord::RAW ), false );
                        } else {
                                return User::newFromId( $userId );
                        }
index 69c709c..79092ee 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 
 /**
  * Feed to Special:RecentChanges and Special:RecentChangesLinked.
@@ -117,7 +118,7 @@ class ChangesFeed {
                                FeedUtils::formatDiff( $obj ),
                                $url,
                                $obj->rc_timestamp,
-                               ( $obj->rc_deleted & Revision::DELETED_USER )
+                               ( $obj->rc_deleted & RevisionRecord::DELETED_USER )
                                        ? wfMessage( 'rev-deleted-user' )->escaped() : $obj->rc_user_text,
                                $talkpage
                        );
index 34adea9..d97abca 100644 (file)
@@ -23,6 +23,7 @@
  */
 use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IResultWrapper;
 
 class ChangesList extends ContextSource {
@@ -87,7 +88,7 @@ class ChangesList extends ContextSource {
                $user = $context->getUser();
                $sk = $context->getSkin();
                $list = null;
-               if ( Hooks::run( 'FetchChangesList', [ $user, &$sk, &$list ] ) ) {
+               if ( Hooks::run( 'FetchChangesList', [ $user, &$sk, &$list, $groups ] ) ) {
                        $new = $context->getRequest()->getBool( 'enhanced', $user->getOption( 'usenewrc' ) );
 
                        return $new ?
@@ -409,7 +410,7 @@ class ChangesList extends ContextSource {
        public static function revDateLink( Revision $rev, User $user, Language $lang, $title = null ) {
                $ts = $rev->getTimestamp();
                $date = $lang->userTimeAndDate( $ts, $user );
-               if ( $rev->userCan( Revision::DELETED_TEXT, $user ) ) {
+               if ( $rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                        $link = MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
                                $title ?? $rev->getTitle(),
                                $date,
@@ -419,7 +420,7 @@ class ChangesList extends ContextSource {
                } else {
                        $link = htmlspecialchars( $date );
                }
-               if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                        $link = "<span class=\"history-deleted mw-changeslist-date\">$link</span>";
                }
                return $link;
@@ -468,7 +469,7 @@ class ChangesList extends ContextSource {
                        $rc->mAttribs['rc_type'] == RC_CATEGORIZE
                ) {
                        $diffLink = $this->message['diff'];
-               } elseif ( !self::userCan( $rc, Revision::DELETED_TEXT, $this->getUser() ) ) {
+               } elseif ( !self::userCan( $rc, RevisionRecord::DELETED_TEXT, $this->getUser() ) ) {
                        $diffLink = $this->message['diff'];
                } else {
                        $query = [
@@ -524,7 +525,7 @@ class ChangesList extends ContextSource {
                        [ 'class' => 'mw-changeslist-title' ],
                        $params
                );
-               if ( $this->isDeleted( $rc, Revision::DELETED_TEXT ) ) {
+               if ( $this->isDeleted( $rc, RevisionRecord::DELETED_TEXT ) ) {
                        $articlelink = '<span class="history-deleted">' . $articlelink . '</span>';
                }
                # To allow for boldening pages watched by this user
@@ -576,7 +577,7 @@ class ChangesList extends ContextSource {
         * @param RecentChange &$rc
         */
        public function insertUserRelatedLinks( &$s, &$rc ) {
-               if ( $this->isDeleted( $rc, Revision::DELETED_USER ) ) {
+               if ( $this->isDeleted( $rc, RevisionRecord::DELETED_USER ) ) {
                        $s .= ' <span class="history-deleted">' .
                                $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
                } else {
@@ -613,7 +614,7 @@ class ChangesList extends ContextSource {
         * @return string
         */
        public function insertComment( $rc ) {
-               if ( $this->isDeleted( $rc, Revision::DELETED_COMMENT ) ) {
+               if ( $this->isDeleted( $rc, RevisionRecord::DELETED_COMMENT ) ) {
                        return ' <span class="history-deleted">' .
                                $this->msg( 'rev-deleted-comment' )->escaped() . '</span>';
                } else {
@@ -709,7 +710,8 @@ class ChangesList extends ContextSource {
                                        'actor' => $rc->mAttribs['rc_actor'] ?? null,
                                        'deleted' => $rc->mAttribs['rc_deleted']
                                ] );
-                               $s .= ' ' . Linker::generateRollback( $rev, $this->getContext() );
+                               $s .= ' ' . Linker::generateRollback( $rev, $this->getContext(),
+                                       [ 'noBrackets' ] );
                        }
                }
        }
index 8f32ba2..62cf39e 100644 (file)
@@ -1,4 +1,7 @@
 <?php
+
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Generates a list of changes using an Enhanced system (uses javascript).
  *
@@ -409,7 +412,7 @@ class EnhancedChangesList extends ChangesList {
                if ( $type == RC_LOG ) {
                        $link = htmlspecialchars( $rcObj->timestamp );
                        # Revision link
-               } elseif ( !ChangesList::userCan( $rcObj, Revision::DELETED_TEXT, $this->getUser() ) ) {
+               } elseif ( !ChangesList::userCan( $rcObj, RevisionRecord::DELETED_TEXT, $this->getUser() ) ) {
                        $link = Html::element( 'span', [ 'class' => 'history-deleted' ], $rcObj->timestamp );
                } else {
                        $link = $this->linkRenderer->makeKnownLink(
@@ -418,7 +421,7 @@ class EnhancedChangesList extends ChangesList {
                                [],
                                $params
                        );
-                       if ( static::isDeleted( $rcObj, Revision::DELETED_TEXT ) ) {
+                       if ( static::isDeleted( $rcObj, RevisionRecord::DELETED_TEXT ) ) {
                                $link = '<span class="history-deleted">' . $link . '</span> ';
                        }
                }
@@ -552,7 +555,7 @@ class EnhancedChangesList extends ChangesList {
                        if (
                                $isnew ||
                                $rcObj->mAttribs['rc_type'] == RC_CATEGORIZE ||
-                               !ChangesList::userCan( $rcObj, Revision::DELETED_TEXT, $this->getUser() )
+                               !ChangesList::userCan( $rcObj, RevisionRecord::DELETED_TEXT, $this->getUser() )
                        ) {
                                $links['total-changes'] = Html::rawElement( 'span', [], $nchanges[$n] );
                        } else {
index 2d60ca2..d448eae 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 use MediaWiki\Linker\LinkRenderer;
+use MediaWiki\Storage\RevisionRecord;
 
 class RCCacheEntryFactory {
 
@@ -79,7 +80,7 @@ class RCCacheEntryFactory {
                // Make user links
                $cacheEntry->userlink = $this->getUserLink( $cacheEntry );
 
-               if ( !ChangesList::isDeleted( $cacheEntry, Revision::DELETED_USER ) ) {
+               if ( !ChangesList::isDeleted( $cacheEntry, RevisionRecord::DELETED_USER ) ) {
                        $cacheEntry->usertalklink = Linker::userToolLinks(
                                $cacheEntry->mAttribs['rc_user'],
                                $cacheEntry->mAttribs['rc_user_text'],
@@ -104,7 +105,7 @@ class RCCacheEntryFactory {
         * @return bool
         */
        private function showDiffLinks( RecentChange $cacheEntry, User $user ) {
-               return ChangesList::userCan( $cacheEntry, Revision::DELETED_TEXT, $user );
+               return ChangesList::userCan( $cacheEntry, RevisionRecord::DELETED_TEXT, $user );
        }
 
        /**
@@ -281,7 +282,7 @@ class RCCacheEntryFactory {
         * @return string
         */
        private function getUserLink( RecentChange $cacheEntry ) {
-               if ( ChangesList::isDeleted( $cacheEntry, Revision::DELETED_USER ) ) {
+               if ( ChangesList::isDeleted( $cacheEntry, RevisionRecord::DELETED_USER ) ) {
                        $userLink = ' <span class="history-deleted">' .
                                $this->context->msg( 'rev-deleted-user' )->escaped() . '</span>';
                } else {
index eed159d..95c9fa6 100644 (file)
@@ -369,13 +369,6 @@ class RecentChange implements Taggable {
        public function save( $send = self::SEND_FEED ) {
                global $wgPutIPinRC, $wgUseEnotif, $wgShowUpdatedMarker;
 
-               if ( is_string( $send ) ) {
-                       // Callers used to pass undocumented strings like 'noudp'
-                       // or 'pleasedontudp' instead of self::SEND_NONE (true).
-                       // @deprecated since 1.31 Use SEND_NONE instead.
-                       $send = self::SEND_NONE;
-               }
-
                $dbw = wfGetDB( DB_MASTER );
                if ( !is_array( $this->mExtra ) ) {
                        $this->mExtra = [];
index 2bac909..1827aab 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 
 /**
  * Item class for a logging table row with its associated change tags.
@@ -49,7 +50,9 @@ class ChangeTagsLogItem extends RevisionItemBase {
        }
 
        public function canView() {
-               return LogEventsList::userCan( $this->row, Revision::SUPPRESSED_ALL, $this->list->getUser() );
+               return LogEventsList::userCan(
+                       $this->row, RevisionRecord::SUPPRESSED_ALL, $this->list->getUser()
+               );
        }
 
        public function canViewContent() {
index 65a7b7d..48dfc70 100644 (file)
@@ -26,6 +26,7 @@
  * @author Daniel Kinzler
  */
 
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Assert\Assert;
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
@@ -1025,7 +1026,7 @@ abstract class ContentHandler {
                        [ 'rev_user_text' => $revQuery['fields']['rev_user_text'] ],
                        [
                                'rev_page' => $title->getArticleID(),
-                               $dbr->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0'
+                               $dbr->bitAnd( 'rev_deleted', RevisionRecord::DELETED_USER ) . ' = 0'
                        ],
                        __METHOD__,
                        [ 'LIMIT' => 20 ],
index 86d1a43..54cd9ca 100644 (file)
@@ -508,7 +508,7 @@ class DifferenceEngine extends ContextSource {
 
                # Check if one of the revisions is deleted/suppressed
                $deleted = $suppressed = false;
-               $allowed = $this->mNewRev->userCan( Revision::DELETED_TEXT, $user );
+               $allowed = $this->mNewRev->userCan( RevisionRecord::DELETED_TEXT, $user );
 
                $revisionTools = [];
 
@@ -554,8 +554,8 @@ class DifferenceEngine extends ContextSource {
                                        }
                                }
 
-                               if ( !$this->mOldRev->isDeleted( Revision::DELETED_TEXT ) &&
-                                       !$this->mNewRev->isDeleted( Revision::DELETED_TEXT )
+                               if ( !$this->mOldRev->isDeleted( RevisionRecord::DELETED_TEXT ) &&
+                                       !$this->mNewRev->isDeleted( RevisionRecord::DELETED_TEXT )
                                ) {
                                        $undoLink = Html::element( 'a', [
                                                        'href' => $this->mNewPage->getLocalURL( [
@@ -605,15 +605,15 @@ class DifferenceEngine extends ContextSource {
                        Hooks::run( 'DifferenceEngineOldHeader', [ $this, &$oldHeader, $prevlink, $oldminor,
                                $diffOnly, $ldel, $this->unhide ] );
 
-                       if ( $this->mOldRev->isDeleted( Revision::DELETED_TEXT ) ) {
+                       if ( $this->mOldRev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                                $deleted = true; // old revisions text is hidden
-                               if ( $this->mOldRev->isDeleted( Revision::DELETED_RESTRICTED ) ) {
+                               if ( $this->mOldRev->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ) {
                                        $suppressed = true; // also suppressed
                                }
                        }
 
                        # Check if this user can see the revisions
-                       if ( !$this->mOldRev->userCan( Revision::DELETED_TEXT, $user ) ) {
+                       if ( !$this->mOldRev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                                $allowed = false;
                        }
                }
@@ -675,9 +675,9 @@ class DifferenceEngine extends ContextSource {
                Hooks::run( 'DifferenceEngineNewHeader', [ $this, &$newHeader, $formattedRevisionTools,
                        $nextlink, $rollback, $newminor, $diffOnly, $rdel, $this->unhide ] );
 
-               if ( $this->mNewRev->isDeleted( Revision::DELETED_TEXT ) ) {
+               if ( $this->mNewRev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                        $deleted = true; // new revisions text is hidden
-                       if ( $this->mNewRev->isDeleted( Revision::DELETED_RESTRICTED ) ) {
+                       if ( $this->mNewRev->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ) {
                                $suppressed = true; // also suppressed
                        }
                }
@@ -1011,11 +1011,11 @@ class DifferenceEngine extends ContextSource {
                        if ( !$this->loadRevisionData() ) {
                                return false;
                        } elseif ( $this->mOldRev &&
-                               !$this->mOldRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
+                               !$this->mOldRev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() )
                        ) {
                                return false;
                        } elseif ( $this->mNewRev &&
-                               !$this->mNewRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
+                               !$this->mNewRev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() )
                        ) {
                                return false;
                        }
@@ -1465,7 +1465,7 @@ class DifferenceEngine extends ContextSource {
                        $users = $this->mNewPage->getAuthorsBetween( $oldRev, $newRev, $limit );
                        $numUsers = count( $users );
 
-                       if ( $numUsers == 1 && $users[0] == $newRev->getUserText( Revision::RAW ) ) {
+                       if ( $numUsers == 1 && $users[0] == $newRev->getUserText( RevisionRecord::RAW ) ) {
                                $numUsers = 0; // special case to say "by the same user" instead of "by one other user"
                        }
 
@@ -1530,7 +1530,7 @@ class DifferenceEngine extends ContextSource {
                $header = Linker::linkKnown( $title, $header, [],
                        [ 'oldid' => $rev->getId() ] );
 
-               if ( $rev->userCan( Revision::DELETED_TEXT, $user ) ) {
+               if ( $rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                        $editQuery = [ 'action' => 'edit' ];
                        if ( !$rev->isCurrent() ) {
                                $editQuery['oldid'] = $rev->getId();
@@ -1545,7 +1545,7 @@ class DifferenceEngine extends ContextSource {
                                [ 'class' => 'mw-diff-edit' ],
                                $editLink
                        );
-                       if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+                       if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                                $header = Html::rawElement(
                                        'span',
                                        [ 'class' => 'history-deleted' ],
@@ -1869,13 +1869,17 @@ class DifferenceEngine extends ContextSource {
                }
 
                if ( $this->mOldRev ) {
-                       $this->mOldContent = $this->mOldRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+                       $this->mOldContent = $this->mOldRev->getContent(
+                               RevisionRecord::FOR_THIS_USER, $this->getUser()
+                       );
                        if ( $this->mOldContent === null ) {
                                return false;
                        }
                }
 
-               $this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+               $this->mNewContent = $this->mNewRev->getContent(
+                       RevisionRecord::FOR_THIS_USER, $this->getUser()
+               );
                Hooks::run( 'DifferenceEngineLoadTextAfterNewContentIsLoaded', [ $this ] );
                if ( $this->mNewContent === null ) {
                        return false;
@@ -1900,7 +1904,9 @@ class DifferenceEngine extends ContextSource {
                        return false;
                }
 
-               $this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+               $this->mNewContent = $this->mNewRev->getContent(
+                       RevisionRecord::FOR_THIS_USER, $this->getUser()
+               );
 
                Hooks::run( 'DifferenceEngineAfterLoadNewText', [ $this ] );
 
index 8b0ed00..fe6dadf 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 use MediaWiki\MediaWikiServices as MediaWikiServicesAlias;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\IDatabase;
 
@@ -253,7 +254,7 @@ class WikiExporter {
                                'rev_user' => $revQuery['fields']['rev_user'],
                        ],
                        [
-                               $this->db->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0',
+                               $this->db->bitAnd( 'rev_deleted', RevisionRecord::DELETED_USER ) . ' = 0',
                                $cond,
                        ],
                        __METHOD__,
index f71b0d5..f34b3bd 100644 (file)
@@ -291,6 +291,34 @@ class XmlDumpWriter {
                return MediaWikiServices::getInstance()->getBlobStore();
        }
 
+       /**
+        * Invokes the given method on the given object, catching and logging any storage related
+        * exceptions.
+        *
+        * @param object $obj
+        * @param string $method
+        * @param array $args
+        * @param string $warning The warning to output in case of a storage related exception.
+        *
+        * @return mixed Returns the method's return value,
+        *         or null in case of a storage related exception.
+        * @throws Exception
+        */
+       private function invokeLenient( $obj, $method, $args = [], $warning ) {
+               try {
+                       return call_user_func_array( [ $obj, $method ], $args );
+               } catch ( SuppressedDataException $ex ) {
+                       return null;
+               } catch ( Exception $ex ) {
+                       if ( $ex instanceof MWException || $ex instanceof RuntimeException ) {
+                               MWDebug::warning( $warning . ': ' . $ex->getMessage() );
+                               return null;
+                       } else {
+                               throw $ex;
+                       }
+               }
+       }
+
        /**
         * Dumps a "<revision>" section on the output stream, with
         * data filled in from the given database row.
@@ -320,7 +348,7 @@ class XmlDumpWriter {
 
                $out .= $this->writeTimestamp( $rev->getTimestamp() );
 
-               if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_USER ) ) {
                        $out .= "      " . Xml::element( 'contributor', [ 'deleted' => 'deleted' ] ) . "\n";
                } else {
                        // empty values get written out as uid 0, see T224221
@@ -334,7 +362,7 @@ class XmlDumpWriter {
                if ( $rev->isMinor() ) {
                        $out .= "      <minor/>\n";
                }
-               if ( $rev->isDeleted( Revision::DELETED_COMMENT ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_COMMENT ) ) {
                        $out .= "      " . Xml::element( 'comment', [ 'deleted' => 'deleted' ] ) . "\n";
                } else {
                        if ( $rev->getComment()->text != '' ) {
@@ -344,22 +372,39 @@ class XmlDumpWriter {
                        }
                }
 
-               $contentMode = $rev->isDeleted( Revision::DELETED_TEXT ) ? self::WRITE_STUB_DELETED
+               $contentMode = $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ? self::WRITE_STUB_DELETED
                        : $this->contentMode;
 
                foreach ( $rev->getSlots()->getSlots() as $slot ) {
                        $out .= $this->writeSlot( $slot, $contentMode );
                }
 
-               if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                        $out .= "      <sha1/>\n";
                } else {
-                       $out .= "      " . Xml::element( 'sha1', null, strval( $rev->getSha1() ) ) . "\n";
+                       $sha1 = $this->invokeLenient(
+                               $rev,
+                               'getSha1',
+                               [],
+                               'failed to determine sha1 for revision ' . $rev->getId()
+                       );
+                       $out .= "      " . Xml::element( 'sha1', null, strval( $sha1 ) ) . "\n";
                }
 
                // Avoid PHP 7.1 warning from passing $this by reference
                $writer = $this;
-               $text = $rev->getContent( SlotRecord::MAIN, RevisionRecord::RAW );
+               $text = '';
+               if ( $contentMode === self::WRITE_CONTENT ) {
+                       /** @var Content $content */
+                       $content = $this->invokeLenient(
+                               $rev,
+                               'getContent',
+                               [ SlotRecord::MAIN, RevisionRecord::RAW ],
+                               'Failed to load main slot content of revision ' . $rev->getId()
+                       );
+
+                       $text = $content ? $content->serialize() : '';
+               }
                Hooks::run( 'XmlDumpWriterWriteRevision', [ &$writer, &$out, $row, $text, $rev ] );
 
                $out .= "    </revision>\n";
@@ -407,37 +452,38 @@ class XmlDumpWriter {
 
                $textAttributes = [
                        'xml:space' => 'preserve',
-                       'bytes' => $slot->getSize(),
+                       'bytes' => $this->invokeLenient(
+                               $slot,
+                               'getSize',
+                               [],
+                               'failed to determine size for slot ' . $slot->getRole() . ' of revision '
+                               . $slot->getRevision()
+                       ) ?: '0'
                ];
 
                if ( $isV11 ) {
-                       $textAttributes['sha1'] = $slot->getSha1();
+                       $textAttributes['sha1'] = $this->invokeLenient(
+                               $slot,
+                               'getSha1',
+                               [],
+                               'failed to determine sha1 for slot ' . $slot->getRole() . ' of revision '
+                               . $slot->getRevision()
+                       ) ?: '';
                }
 
                if ( $contentMode === self::WRITE_CONTENT ) {
-                       try {
-                               // write <text> tag
-                               $out .= $this->writeText( $slot->getContent(), $textAttributes, $indent );
-                       } catch ( SuppressedDataException $ex ) {
-                               // NOTE: this shouldn't happen, since the caller is supposed to have checked
-                               // for suppressed content!
-                               // write <text> placeholder tag
-                               $textAttributes['deleted'] = 'deleted';
+                       $content = $this->invokeLenient(
+                               $slot,
+                               'getContent',
+                               [],
+                               'failed to load content for slot ' . $slot->getRole() . ' of revision '
+                               . $slot->getRevision()
+                       );
+
+                       if ( $content === null ) {
                                $out .= $indent . Xml::element( 'text', $textAttributes ) . "\n";
-                       }
-                       catch ( Exception $ex ) {
-                               if ( $ex instanceof MWException || $ex instanceof RuntimeException ) {
-                                       // there's no provision in the schema for an attribute that will let
-                                       // the user know this element was unavailable due to error; an empty
-                                       // tag is the best we can do
-                                       $out .= $indent . Xml::element( 'text' ) . "\n";
-                                       wfLogWarning(
-                                               'failed to load content slot ' . $slot->getRole() . ' for revision '
-                                               . $slot->getRevision() . "\n"
-                                       );
-                               } else {
-                                       throw $ex;
-                               }
+                       } else {
+                               $out .= $this->writeText( $content, $textAttributes, $indent );
                        }
                } elseif ( $contentMode === self::WRITE_STUB_DELETED ) {
                        // write <text> placeholder tag
@@ -452,14 +498,21 @@ class XmlDumpWriter {
                        // Output the numerical text ID if possible, for backwards compatibility.
                        // Note that this is currently the ONLY reason we have a BlobStore here at all.
                        // When removing this line, check whether the BlobStore has become unused.
-                       $textId = $this->getBlobStore()->getTextIdFromAddress( $slot->getAddress() );
+                       try {
+                               // NOTE: this will only work for addresses of the form "tt:12345".
+                               // If we want to support other kinds of addresses in the future,
+                               // we will have to silently ignore failures here.
+                               // For now, this fails for "tt:0", which is present in the WMF production
+                               // database of of Juli 2019, due to data corruption.
+                               $textId = $this->getBlobStore()->getTextIdFromAddress( $slot->getAddress() );
+                       } catch ( InvalidArgumentException $ex ) {
+                               MWDebug::warning( 'Bad content address for slot ' . $slot->getRole()
+                                       . ' of revision ' . $slot->getRevision() . ': ' . $ex->getMessage() );
+                               $textId = 0;
+                       }
+
                        if ( $textId ) {
                                $textAttributes['id'] = $textId;
-                       } elseif ( !$isV11 ) {
-                               throw new InvalidArgumentException(
-                                       'Cannot produce stubs for non-text-table content blobs with schema version '
-                                       . $this->schemaVersion
-                               );
                        }
 
                        $out .= $indent . Xml::element( 'text', $textAttributes ) . "\n";
index 43f6010..957af3e 100644 (file)
@@ -121,10 +121,13 @@ class LockManagerGroup {
                        $config = $this->managers[$name]['config'];
                        if ( $class === DBLockManager::class ) {
                                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-                               $lb = $lbFactory->newMainLB( $config['domain'] );
-                               $dbw = $lb->getLazyConnectionRef( DB_MASTER, [], $config['domain'] );
-
-                               $config['dbServers']['localDBMaster'] = $dbw;
+                               $lb = $lbFactory->getMainLB( $config['domain'] );
+                               $config['dbServers']['localDBMaster'] = $lb->getLazyConnectionRef(
+                                       DB_MASTER,
+                                       [],
+                                       $config['domain'],
+                                       $lb::CONN_TRX_AUTOCOMMIT
+                               );
                                $config['srvCache'] = ObjectCache::getLocalServerInstance( 'hash' );
                        }
                        $config['logger'] = LoggerFactory::getInstance( 'LockManager' );
index 8ff8143..314c4c3 100644 (file)
@@ -580,7 +580,7 @@ class ForeignAPIRepo extends FileRepo {
 
                                return $html;
                        },
-                       [ 'pcTTL' => WANObjectCache::TTL_PROC_LONG ]
+                       [ 'pcGroup' => 'http-get:3', 'pcTTL' => WANObjectCache::TTL_PROC_LONG ]
                );
        }
 
index d447945..61faa09 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 
 /**
  * Helper class for file deletion
@@ -195,7 +196,7 @@ class LocalFileDeleteBatch {
 
                // Bitfields to further suppress the content
                if ( $this->suppress ) {
-                       $bitfield = Revision::SUPPRESSED_ALL;
+                       $bitfield = RevisionRecord::SUPPRESSED_ALL;
                } else {
                        $bitfield = 'oi_deleted';
                }
index 33d4fcc..f6a5c41 100644 (file)
@@ -1764,7 +1764,9 @@ abstract class Installer {
        public static function overrideConfig() {
                // Use PHP's built-in session handling, since MediaWiki's
                // SessionHandler can't work before we have an object cache set up.
-               define( 'MW_NO_SESSION_HANDLER', 1 );
+               if ( !defined( 'MW_NO_SESSION_HANDLER' ) ) {
+                       define( 'MW_NO_SESSION_HANDLER', 1 );
+               }
 
                // Don't access the database
                $GLOBALS['wgUseDatabaseMessages'] = false;
index c901ab0..78f0c09 100644 (file)
@@ -51,7 +51,7 @@
        "config-help-restart": "هل تريد إزالة البيانات المحفوظة التي قد قمت بإدخالها وإعادة تشغيل عملية التثبيت؟",
        "config-restart": "نعم، إعادة التشغيل",
        "config-welcome": "=== التحقق من البيئة ===\nسوف يتم الآن التحقق من أن البيئة مناسبة لتنصيب ميديا ويكي.\nتذكر تضمين هذه المعلومات اذا اردت طلب المساعدة عن كيفية إكمال التنصيب.",
-       "config-welcome-section-copyright": "=== حقوق النسخ والشروط ===\n\n$1\n\nهذا البرنامج هو برنامج حر؛ يمكنك إعادة توزيعه و/أو تعديله تحت شروط رخصة جنو العامة على أن هذا البرنامج قد نُشر من قِبل مؤسسة البرمجيات الحرة؛ إما النسخة 2 من الرخصة، أو أي نسخة أخرى بعدها (من اختيارك).\n\nتم توزيع هذا البرنامج على أمل ان يكون مفيدًا ولكن <strong>دون أية ضمانات</strong>؛ دون حتى أية ضمانات مفهومة ضمنيًا أو رواجات أو أية أسباب محددة.\nانظر رخصة جنو العامة لمزيد من المعلومات.\n\nمن المفترض أنك استملت [$2  نسخة عن رخصة جنو العامة ] مع هذا البرنامج؛ إذا لم تقعل اكتب رسالة إلى مؤسسة البرمجيات الحرة المحدودة، شارع 51 فرانكلين الطابق الخامس، بوسطن  MA 02110-1301 الولايات المتخدة أو [https://www.gnu.org/copyleft/gpl.html read it online].",
+       "config-welcome-section-copyright": "=== حقوق النسخ والشروط ===\n\n$1\n\nهذا البرنامج هو برنامج حر؛ يمكنك إعادة توزيعه و/أو تعديله تحت شروط رخصة جنو العامة على أن هذا البرنامج قد نُشر من قِبل مؤسسة البرمجيات الحرة؛ إما النسخة 2 من الرخصة، أو أي نسخة أخرى بعدها (من اختيارك).\n\nتم توزيع هذا البرنامج على أمل ان يكون مفيدًا ولكن <strong>دون أية ضمانات</strong>؛ دون حتى أية ضمانات مفهومة ضمنيًا أو رواجات أو أية أسباب محددة.\nانظر رخصة جنو العامة لمزيد من المعلومات.\n\nمن المفترض أنك استملت [$2  نسخة عن رخصة جنو العامة] مع هذا البرنامج؛ إذا لم تقعل اكتب رسالة إلى مؤسسة البرمجيات الحرة المحدودة، شارع 51 فرانكلين الطابق الخامس، بوسطن  MA 02110-1301 الولايات المتخدة أو [https://www.gnu.org/copyleft/gpl.html read it online].",
        "config-sidebar": "* [https://www.mediawiki.org موقع ميدياويكي]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents دليل المستخدم]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents دليل الإداري]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ الأسئلة المتكررة]",
        "config-sidebar-readme": "اقرأني",
        "config-sidebar-relnotes": "ملاحظات الإصدار",
index 24dd4f0..e7e59a8 100644 (file)
        "config-welcome": "=== Проверка на условията ===\nЩе бъдат извършени основни проверки, които да установят дали условията са подходящи за инсталиране на МедияУики.\nАко е необходима помощ по време на инсталацията, резултатите от направените проверки трябва също да бъдат предоставени.",
        "config-welcome-section-copyright": "=== Авторски права и условия ===\n\n$1\n\nТази програма е свободен софтуер, който може да се променя и/или разпространява според Общия публичен лиценз на GNU, както е публикуван от Free Software Foundation във версия на Лиценза 2 или по-късна версия.\n\nТази програма се разпространява с надеждата, че ще е полезна, но <strong>без каквито и да е гаранции</strong>; без дори косвена гаранция за <strong>продаваемост</strong>  или <strong>пригодност за конкретна употреба</strong> .\nЗа повече подробности се препоръчва преглеждането на Общия публичен лиценз на GNU.\n\nКъм програмата трябва да е приложено [$2 копие на Общия публичен лиценз на GNU]; ако не, можете да пишете на Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, или да [https://www.gnu.org/copyleft/gpl.html го прочетете онлайн].",
        "config-sidebar": "* [https://www.mediawiki.org Сайт на МедияУики]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Наръчник на потребителя]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Наръчник на администратора]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ ЧЗВ]",
+       "config-sidebar-readme": "Прочети ме",
+       "config-sidebar-relnotes": "Бележки за версията",
+       "config-sidebar-license": "Копиране",
+       "config-sidebar-upgrade": "Надграждане",
        "config-env-good": "Средата беше проверена.\nИнсталирането на МедияУики е възможно.",
        "config-env-bad": "Средата беше проверена.\nНе е възможна инсталация на МедияУики.",
        "config-env-php": "PHP $1 е инсталирано.",
        "config-install-done": "<strong>Поздравления!</strong>\nИнсталирането на МедияУики приключи успешно.\n\nИнсталаторът създаде файл <code>LocalSettings.php</code>.\nТой съдържа всичката необходима основна конфигурация на уикито.\n\nНеобходимо е той да бъде изтеглен и поставен в основната директория на уикито (директорията, в която е и index.php). Изтеглянето би трябвало да започне автоматично.\n\nАко изтеглянето не започне автоматично или е било прекратено, файлът може да бъде изтеглен чрез щракване на препратката по-долу:\n\n$3\n\n<strong>Забележка:</strong> Ако това не бъде извършено сега, генерираният конфигурационен файл няма да е достъпен на по-късен етап ако не бъде изтеглен сега или инсталацията приключи без изтеглянето му.\n\nКогато файлът вече е в основната директория, <strong>[$2 уикито ще е достъпно на този адрес]</strong>.",
        "config-install-done-path": "<strong>Поздравления!</strong>\nИнсталирането на МедияУики приключи успешно.\n\nИнсталаторът създаде файл <code>LocalSettings.php</code>.\nТой съдържа всички ваши настройки.\n\nНеобходимо е той да бъде изтеглен и поставен в <code>$4</code>. Изтеглянето би трябвало да започне автоматично.\n\nАко изтеглянето не започне автоматично или е било прекратено, файлът може да бъде изтеглен чрез щракване на препратката по-долу:\n\n$3\n\n<strong>Забележка:</strong> Ако това не бъде направено сега, генерираният конфигурационен файл няма да е достъпен на по-късен етап ако не бъде изтеглен сега или инсталацията приключи без изтеглянето му.\n\nКогато файлът вече е в основната директория, <strong>[$2 уикито ще е достъпно на този адрес]</strong>.",
        "config-install-success": "МедияУики беше успешно инсталиран. Можете да посетите <$1$2> за да видите Вашето уики.\n\nАко имате въпроси, вижте списъка с често задавани въпроси:\n<https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> или използвайте някой от форумите за поддръжка на тази страница.",
+       "config-install-db-success": "Базата от данни е успешно настроена",
        "config-download-localsettings": "Изтегляне на <code>LocalSettings.php</code>",
        "config-help": "помощ",
        "config-help-tooltip": "щракнете за разгръщане",
index 2a358e7..26b33af 100644 (file)
        "config-welcome": "=== Comprovacions de l'entorn ===\nS'efectuaran comprovacions bàsiques per veure si l'entorn és adequat per a la instal·lació del MediaWiki.\nRecordeu d'incloure aquesta informació si heu de demanar ajuda sobre com completar la instal·lació.",
        "config-welcome-section-copyright": "=== Drets d'autor i condicions ===\n\n$1\n\nAquest programa és de programari lliure; podeu redistribuir-lo i/o modificar-lo sota les condicions de la Llicència Pública General GNU com es publicada per la Free Software Foundation; qualsevol versió 2 de la llicència, o (opcionalment) qualsevol versió posterior.\n\nAquest programa és distribueix amb l'esperança que serà útil, però <strong>sense cap garantia</strong>; sense ni tan sols la garantia implícita de <strong>\ncomerciabilitat</strong> o <strong>idoneïtat per a un propòsit particular</strong>.\nConsulteu la Llicència Pública General GNU, per a més detalls.\n\nHauríeu d'haver rebut [$2 una còpia de la Llicència Pública General GNU] amb aquest programa; si no, escriviu a la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA o [https://www.gnu.org/copyleft/gpl.html per llegir-lo en línia].",
        "config-sidebar": "* [https://www.mediawiki.org la Pàgina d'inici]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guia de l'usuari]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Guia de l'administrador]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ PMF]\n----\n* <doclink href=Readme>Llegeix-me</doclink>\n* <doclink href=ReleaseNotes>Notes de la versió</doclink>\n* <doclink href=Còpia>Còpia</doclink>\n* <doclink href=UpgradeDoc>Actualització</doclink>",
+       "config-sidebar-readme": "Llegeix-me",
+       "config-sidebar-relnotes": "Notes de la versió",
+       "config-sidebar-license": "Còpia",
+       "config-sidebar-upgrade": "Actualització",
        "config-env-good": "S'ha comprovat l'entorn.\nPodeu instal·lar el MediaWiki.",
        "config-env-bad": "S'ha comprovat l'entorn.\nNo podeu instal·lar el MediaWiki.",
        "config-env-php": "El PHP $1 està instal·lat.",
@@ -82,6 +86,7 @@
        "config-using-server": "S'utilitza el nom del servidor «<nowiki>$1</nowiki>».",
        "config-using-uri": "S'utilitza l'URL del servidor «<nowiki>$1$2</nowiki>».",
        "config-uploads-not-safe": "<strong>Avís:</strong> El directori de càrregues per defecte <code>$1</code> és vulnerable a l'execució d'scripts arbitraris.\nEncara que el MediaWiki comprova tots els fitxers que es carreguen davant d'amenaces de seguretat, és molt recomanable [https://www.mediawiki.org/ wiki/Special:MyLanguage/Manual:Security#Upload_security tancar aquesta vulnerabilitat de seguretat] abans d'habilitar les càrregues.",
+       "config-no-cli-uploads-check": "<strong>Avís</strong>: no s'ha comprovat el directori per defecte per a càrregues (<code><span class=\"notranslate\">$1</span></code>$) per vulnerabilitats en l'execució arbitrària durant la instal·lació amb la línia d'ordres.",
        "config-brokenlibxml": "El vostre sistema té una combinació de versions de PHP i libxml2 que són problemàtiques i que poden causar corrupció de dades no aparent a MediaWiki i a altres aplicacions web.\nActualitzeu-vos a libxml2 2.7.3 o superior ([https://bugs.php.net/bug.php?id=45996 informe d'error al projecte PHP]).\nS'ha interromput la instal·lació.",
        "config-db-type": "Tipus de base de dades:",
        "config-db-host": "Servidor de la base de dades:",
        "config-db-schema-help": "Aquest esquema normalment ja serveix.\nNomés canvieu-lo si sabeu què us feu.",
        "config-pg-test-error": "No es pot connectar a la base de dades '''$1''': $2",
        "config-sqlite-dir": "Directori de dades de l'SQLite",
+       "config-sqlite-dir-help": "L'SQLite emmagatzema totes les dades en un únic fitxer.\n\nEl directori que proporcioneu ha de ser escrivible pel servidor durant la instal·lació.\n\n<strong>No</strong> hauria de ser accessible des del web. Aquest és el motiu perquè no el posem on són els fitxers PHP.\n\nL'instal·lador escriurà un fitxer <code>.htaccess</code> al mateix temps, però si això fallés, seria possible que s'accedís a la base de dades crua.\nAixò inclou dades d'usuari crues (adreces electròniques, contrasenyes en resum) així com revisions eliminades i altres dades restringida en el wiki.\n\nConsidereu posar la base de dades en algun altre lloc tot plegat, per exemple a <code>/var/lib/mediawiki/yourwiki</code>.",
        "config-oracle-def-ts": "Espai de taules per defecte:",
        "config-oracle-temp-ts": "Espai de taules temporal:",
        "config-type-mysql": "MariaDB, MySQL o compatible",
        "config-license-gfdl": "GNU Free Documentation License 1.3 o posterior",
        "config-license-pd": "Domini públic",
        "config-license-cc-choose": "Selecció d'una llicència personalitzada de Creative Commons",
+       "config-license-help": "Molts wikis públics posen totes llurs contribucions sota una [https://freedomdefined.org/Definició llicència lliure].\nAixò ajuda a crear un sentit de propietat de comunitat i anima les contribucions de llarg termini.\nNo és generalment necessari per a un wiki privat o corporatiu.\n\nSi voleu ser capaç d'utilitzar text de la Viquipèdia, i voleu que la Viquipèdia pugui acceptar text copiat del vostre wiki, hauríeu de triar <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nLa Viquipèdia abans utilitzava la Llicència de documentació lliure de GNU.\nEl GFDL és una llicència vàlida, però difícil d'entendre.\nÉs també difícil reutilitzar contingut sota la GFDL.",
        "config-email-settings": "Paràmetres del correu electrònic",
        "config-enable-email": "Habilita el correu sortint",
        "config-enable-email-help": "Si voleu que el correu electrònic funcioni, cal configurar [https://www.php.net/manual/en/mail.configuration.php PHP's els paràmetres de correu] correctament.\nSi no voleu cap funcionalitat de correu, podeu inhabilitar-ho.",
index 66266b4..a65dbe2 100644 (file)
        "config-restart": "Tak, zacznij od nowa",
        "config-welcome": "=== Sprawdzenie środowiska instalacji ===\nTeraz zostaną wykonane podstawowe testy sprawdzające czy to środowisko jest odpowiednie dla instalacji MediaWiki.\nJeśli potrzebujesz pomocy podczas instalacji, załącz wyniki tych testów.",
        "config-welcome-section-copyright": "=== Prawa autorskie i warunki użytkowania ===\n\n$1\n\nTo oprogramowanie jest wolne; możesz je rozprowadzać dalej i modyfikować zgodnie z warunkami licencji GNU General Public License opublikowanej przez Free Software Foundation w wersji 2 tej licencji lub (według Twojego wyboru) którejś z późniejszych jej wersji.\n\nNiniejsze oprogramowanie jest rozpowszechniane w nadziei, że będzie użyteczne, ale '''bez żadnej gwarancji'''; nawet bez domniemanej gwarancji '''handlowej''' lub '''przydatności do określonego celu'''.\nZobacz treść licencji GNU General Public License, aby uzyskać więcej szczegółów.\n\nRazem z oprogramowaniem powinieneś otrzymać [$2 kopię licencji GNU General Public License]. Jeśli jej nie otrzymałeś, napisz do Free Software Foundation, Inc, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. lub [https://www.gnu.org/copyleft/gpl.html przeczytaj ją online].",
-       "config-sidebar": "* [https://www.mediawiki.org Strona domowa MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Podręcznik użytkownika]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Podręcznik administratora]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Odpowiedzi na często zadawane pytania]\n----\n* <doclink href=Readme>Przeczytaj to</doclink>\n* <doclink href=ReleaseNotes>Informacje o tej wersji</doclink>\n* <doclink href=Copying>Kopiowanie</doclink>\n* <doclink href=UpgradeDoc>Aktualizacja</doclink>",
+       "config-sidebar": "* [https://www.mediawiki.org Strona domowa MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Podręcznik użytkownika]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Podręcznik administratora]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Odpowiedzi na często zadawane pytania]",
+       "config-sidebar-readme": "Podstawowe informacje",
+       "config-sidebar-relnotes": "Informacje o wersji",
+       "config-sidebar-license": "Kopiowanie",
+       "config-sidebar-upgrade": "Uaktualnienie",
        "config-env-good": "Środowisko oprogramowania zostało sprawdzone.\nMożesz teraz zainstalować MediaWiki.",
        "config-env-bad": "Środowisko oprogramowania zostało sprawdzone.\nNie możesz zainstalować MediaWiki.",
        "config-env-php": "Zainstalowane jest PHP w wersji $1.",
index 5234eba..fcad452 100644 (file)
        "config-restart": "Da, pokreni ponovo",
        "config-welcome": "=== Provjere okoline ===\nSada ćemo obaviti osnovne provjere kako bismo utvrdili je li okruženje prikladno za uspostavu MediaWikija. Ne zaboravite navesti ove informacije ako tražite pomoć s dovršavanjem uspostave.",
        "config-welcome-section-copyright": "=== Autorska prava i uvjeti ===\n\n$1\n\nTo je slobodni softver (free software); možete ga redistribuirati i/ili mijenjati pod uvjetima GNU-ove opće javne licence (GNU General Public License) Zaklade za slobodni softver (Free Software Foundation); verzija 2 ili bilo koja kasnija verzija licence (po vašem izboru).\n\nOvaj se program nudi u nadi da će biti koristan, ali '''bez ikakvog jamstva'''; čak i implicirano jamstvo '''sposobnosti prodaje''' ili '''prikladnosti za određenu svrhu'''.\nViše informacija ćete naći u tekstu GNU-ove opće javne licence.\n\nTrebali ste primiti [$2 primjerak GNU-ove opće javne licence] zajedno s programima; ako ga ne primite, pišite nam na Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ili [https://www.gnu.org/copyleft/gpl.html pročitajte je ovdje].",
-       "config-sidebar": "* [https://www.mediawiki.org Početna strana MediaWikija]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Vodič za korisnike]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Vodič za administratore]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ ČPP]\n----\n* <doclink href=Readme>Pročitaj me</doclink>\n* <doclink href=ReleaseNotes>Bilješke o izdanju</doclink>\n* <doclink href=Copying>Kopiranje</doclink>\n* <doclink href=UpgradeDoc>Nadograđivanje</doclink>",
+       "config-sidebar": "* [https://www.mediawiki.org Početna strana MediaWikija]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Vodič za korisnike]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Vodič za administratore]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ ČPP]",
+       "config-sidebar-readme": "Pročitaj me",
+       "config-sidebar-relnotes": "Bilješke o izdanju",
+       "config-sidebar-license": "Kopiranje",
+       "config-sidebar-upgrade": "Nadogradnja",
        "config-env-good": "Okruženje je provjereno.\nMožete uspostaviti MediaWiki.",
        "config-env-bad": "Okruženje je provjereno.\nNe možete uspostaviti MediaWiki.",
        "config-env-php": "PHP $1 je uspostavljen.",
        "config-mysql-myisam": "MyISAM",
        "config-mysql-myisam-dep": "<strong>Upozorenje:</strong> Odabrali ste MyISAM kao skladišni pogon za MySQL. Ali ne preporučuje se za MediaWiki jer:\n* jedva podržava istovremenost iz zaključavanja tabela\n* vjerojatnije je da će ih druge biljke pokvariti\n* kodna baza MediaWikija ne može uvijek ispravno raditi s MyISAM-om\n\nAko vaša uspostava MySQL-a podržava InnoDB, tada seriozno preporučujemo da je koristite umjesto MyISAM.\nAko vaša uspostava MySQL-a ne podržava InnoDB, vjerojatno je vrijeme za nadogradnju.",
        "config-mysql-only-myisam-dep": "<strong>Upozorenje:</strong> MyISAM je jedini dostupan skladišni pogon za MySQL na ovom stroju, a ovo se ne preporučuje za uporabu s MediaWiki, jer:\n* skoro ne podržava istovremeno izvršavanje zadataka zbog zaključavanja tablica\n* više osjetljiv na kvarenje od drugih pogona \n* kodna baza MediaWIkija ne radi uvijek ispravno s MyISAM-om\nVaša MySQL uspostava ne podržava InnoDB. Možda je vrijeme da ga nadogradimo.",
+       "config-mssql-auth": "Tip potvrde identiteta:",
+       "config-mssql-sqlauth": "Potvrda identiteta za SQL Server",
+       "config-mssql-windowsauth": "Potvrda identiteta za Windows",
+       "config-site-name": "Ime wikija:",
+       "config-site-name-help": "Ovo će se pojaviti u naslovnoj traci pregledača i na raznim drugim mestima.",
        "config-admin-password": "Lozinka:",
        "mainpagetext": "<strong>MediaWiki je uspješno instaliran.</strong>",
        "mainpagedocfooter": "Za informacije o korištenju wiki softvera konzultirajte [https://meta.wikimedia.org/wiki/Help:Contents Vodič za korisnike].\n\n== Uvod u rad ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista konfiguracije postavki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista primatelja izdanja MediaWikija]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Lokalizirajte MediaWiki za svoj jezik]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Saznajte kako se boriti protiv spama na svojem wikiju]"
index 7543691..9277f74 100644 (file)
@@ -45,7 +45,7 @@
        "config-help-restart": "Želite počistiti vse shranjene podatke, ki ste jih vnesti, in ponovno začeti s postopkom namestitve?",
        "config-restart": "Da, ponovno zaženi",
        "config-welcome": "=== Pregledi okolja ===\nIzvedli bomo osnovne preglede, da vidimo, če je okolje primerno za namestitev MediaWiki.\nPosredujte rezultate teh pregledov, če med namestitvijo potrebujete pomoč.",
-       "config-sidebar": "* [https://www.mediawiki.org Domača stran MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Vodnik za uporabnike]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Vodnik za administratorje]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Pogosto zastavljena vprašanja]\n----\n* <doclink href=Readme>Beri me</doclink>\n* <doclink href=ReleaseNotes>Opombe ob izidu</doclink>\n* <doclink href=Copying>Kopiranje</doclink>\n* <doclink href=UpgradeDoc>Nadgrajevanje</doclink>",
+       "config-sidebar": "* [https://www.mediawiki.org Domača stran MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Vodnik za uporabnike]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Vodnik za administratorje]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Pogosto zastavljena vprašanja]",
        "config-env-good": "Okolje je pregledano.\nLahko namestite MediaWiki.",
        "config-env-bad": "Okolje je pregledano.\nNe morete namestiti MediaWiki.",
        "config-env-php": "Nameščen je PHP $1.",
index d9fc8dd..a3e8a29 100644 (file)
        "config-env-bad": "Miljön har kontrollerats.\nDu kan inte installera MediaWiki.",
        "config-env-php": "PHP $1 är installerat.",
        "config-env-hhvm": "HHVM $1 är installerat.",
-       "config-unicode-using-intl": "Använder [https://pecl.php.net/intl intl PECL-tillägget] för Unicode-normalisering.",
-       "config-unicode-pure-php-warning": "'''Varning:''' [https://pecl.php.net/intl intl PECL-tillägget] är inte tillgängligt för att hantera Unicode-normalisering, faller tillbaka till en långsamt implementering i ren PHP.\nOm du driver en högtrafikerad webbplats bör du läsa lite om [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode-normalisering].",
+       "config-unicode-using-intl": "Använder tillägget [https://pecl.php.net/intl PHP intl] för Unicode-normalisering.",
+       "config-unicode-pure-php-warning": "'''Varning:''' Tillägget [https://php.net/manual/en/book.intl.php PHP intl] är inte tillgängligt för att hantera Unicode-normalisering, faller tillbaka till en långsamt implementering i ren PHP.\nOm du driver en högtrafikerad webbplats bör du läsa lite om [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode-normalisering].",
        "config-unicode-update-warning": "<strong>Varning:</strong> Den installerade versionen av Unicode-normaliserings \"wrappern\" använder en äldre version av [http://site.icu-project.org/ ICU projektets] bibliotek.\nDu bör [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations uppgradera] om är intresserad av att använda Unicode.",
        "config-no-db": "Kunde inte hitta en lämplig databasdrivrutin! Du måste installera en databasdrivrutin för PHP.\nFöljande databas{{PLURAL:$2|typ |typer}} stöds: $1.\n\nI du själv kompilerat din PHP, konfigurera den med en databasklient aktiverad genom att t.ex. använda <code>./configure --with-mysqli</code>.\nOm du installerade PHP från ett Debian- eller Ubuntupaket måste du även installera, t.ex. <code>php-mysql</code>-paketet.",
-       "config-outdated-sqlite": "'''Varning:''' du har SQLite $1, vilket är lägre än minimikravet version $2. SQLite kommer inte att vara tillgänglig.",
+       "config-outdated-sqlite": "<strong>Varning:</strong> Du har SQLite $2, vilket är lägre än minimikravet version $1. SQLite kommer inte att vara tillgänglig.",
        "config-no-fts3": "'''Varning:''' SQLite kompileras utan [//sqlite.org/fts3.html FTS3-modulen], sökfunktioner kommer att vara otillgängliga på denna backend.",
        "config-pcre-old": "'''Kritiskt:''' PCRE $1 eller senare krävs.\nDin PHP-binär är länkad till PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Mer information].",
        "config-pcre-no-utf8": "'''Kritiskt:''' PHP:s PCRE-modul verkar vara kompilerat utan PCRE_UTF8-stöd.\nMediaWiki kräver stöd för UTF-8 för att fungera korrekt.",
        "config-license-help": "Många publika wikis släpper alla bidrag under en  [https://freedomdefined.org/Definition fri licens].\nDetta bidrar till en känsla av gemensamt ägandeskap och uppmuntrar till långsiktiga bidrag.\nDet är i allmänhet inte nödvändigt för en privat eller företagswiki.\n\nOm du vill kunna använda text från Wikipedia, och du vill att Wikipedia ska kunna acceptera text kopierad ifrån din wiki bör du välja <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia använde tidigare  GNU Free Documentation License.\nGFDL är en giltig licens, men svår att förstå.\nDet är även svårt att återanvända innehåll som licensierats under GFDL.",
        "config-email-settings": "E-postinställningar",
        "config-enable-email": "Aktivera utgående e-post",
-       "config-enable-email-help": "Om du vill att e-post ska fungera behöver,[Config-dbsupport-oracle/manual/en/mail.configuration.php PHPs e-postinställningar] vara konfigurerad på rätt sätt.\nOm du inte vill ha några e-postfunktioner, kan du inaktivera dem här.",
+       "config-enable-email-help": "Om du vill att e-post ska fungera behöver [https://www.php.net/manual/en/mail.configuration.php PHPs e-postinställningar] vara konfigurerad på rätt sätt.\nOm du inte vill ha några e-postfunktioner kan du inaktivera dem här.",
        "config-email-user": "Aktivera e-post mellan användare",
        "config-email-user-help": "Tillåta alla användare att skicka e-post till varandra om de har aktiverat det i sina inställningar.",
        "config-email-usertalk": "Aktivera meddelanden för användardiskussionssidor",
index bc222a5..60fa81e 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "KhayR",
                        "Seb35",
-                       "Ильнар"
+                       "Ильнар",
+                       "Ерней"
                ]
        },
        "config-desc": "MediaWiki йөкләүче",
        "config-db-host": "Мәгълүмат базасы хосты:",
        "config-db-host-oracle": "TNS мәгълүмат базасы:",
        "config-db-wiki-settings": "Бу вики идентификациясе",
-       "config-db-name": "Мәгълүмат базасы исеме:",
+       "config-db-name": "Мәгълүматлар базасы исеме (сызыкчасыз):",
        "config-db-name-oracle": "Мәгълүмат базасы төзелеше:",
        "config-db-username": "Мәгълүмат базасын кулланучы исеме:",
        "config-db-password": "Мәгълүмат базасының серсүзе:",
        "config-db-port": "Мәгълүмат базасы порты:",
-       "config-db-schema": "MediaWiki өчен төзелеш:",
+       "config-db-schema": "MediaWiki өчен (сызыкчасыз) төзелеш:",
        "config-type-mysql": "MariaDB, MySQL яисә ярашлы",
        "config-type-mssql": "Microsoft SQL Server",
        "config-header-mysql": "MariaDB/MySQL көйләнмәләре",
index 906e955..8c99532 100644 (file)
@@ -440,20 +440,20 @@ abstract class BagOStuff implements IExpiringStore, IStoreKeyEncoder, LoggerAwar
         *
         * @since 1.27
         * @param string $class Key class
-        * @param string|null $component [optional] Key component (starting with a key collection name)
-        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        * @param string ...$components Key components (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components
         */
-       abstract public function makeGlobalKey( $class, $component = null );
+       abstract public function makeGlobalKey( $class, ...$components );
 
        /**
         * Make a cache key, scoped to this instance's keyspace.
         *
         * @since 1.27
         * @param string $class Key class
-        * @param string|null $component [optional] Key component (starting with a key collection name)
-        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        * @param string ...$components Key components (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components
         */
-       abstract public function makeKey( $class, $component = null );
+       abstract public function makeKey( $class, ...$components );
 
        /**
         * @param int $flag ATTR_* class constant
index c97f56e..0ab26c9 100644 (file)
@@ -145,15 +145,15 @@ class CachedBagOStuff extends BagOStuff {
        }
 
        public function makeKeyInternal( $keyspace, $args ) {
-               return $this->backend->makeKeyInternal( ...func_get_args() );
+               return $this->backend->makeKeyInternal( $keyspace, $args );
        }
 
-       public function makeKey( $class, $component = null ) {
-               return $this->backend->makeKey( ...func_get_args() );
+       public function makeKey( $class, ...$components ) {
+               return $this->backend->makeKey( $class, ...$components );
        }
 
-       public function makeGlobalKey( $class, $component = null ) {
-               return $this->backend->makeGlobalKey( ...func_get_args() );
+       public function makeGlobalKey( $class, ...$components ) {
+               return $this->backend->makeGlobalKey( $class, ...$components );
        }
 
        public function getLastError() {
index da0686e..59e1c05 100644 (file)
@@ -11,17 +11,17 @@ interface IStoreKeyEncoder {
         * Make a global cache key.
         *
         * @param string $class Key class
-        * @param string|null $component [optional] Key component (starting with a key collection name)
-        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        * @param string ...$components Key components (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components
         */
-       public function makeGlobalKey( $class, $component = null );
+       public function makeGlobalKey( $class, ...$components );
 
        /**
         * Make a cache key, scoped to this instance's keyspace.
         *
         * @param string $class Key class
-        * @param string|null $component [optional] Key component (starting with a key collection name)
-        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        * @param string ...$components Key components (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components
         */
-       public function makeKey( $class, $component = null );
+       public function makeKey( $class, ...$components );
 }
index fb088c8..e742432 100644 (file)
@@ -858,11 +858,11 @@ abstract class MediumSpecificBagOStuff extends BagOStuff {
         * Make a global cache key.
         *
         * @param string $class Key class
-        * @param string|null $component [optional] Key component (starting with a key collection name)
-        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        * @param string ...$components Key components (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components
         * @since 1.27
         */
-       public function makeGlobalKey( $class, $component = null ) {
+       public function makeGlobalKey( $class, ...$components ) {
                return $this->makeKeyInternal( 'global', func_get_args() );
        }
 
@@ -870,11 +870,11 @@ abstract class MediumSpecificBagOStuff extends BagOStuff {
         * Make a cache key, scoped to this instance's keyspace.
         *
         * @param string $class Key class
-        * @param string|null $component [optional] Key component (starting with a key collection name)
-        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        * @param string ...$components Key components (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components
         * @since 1.27
         */
-       public function makeKey( $class, $component = null ) {
+       public function makeKey( $class, ...$components ) {
                return $this->makeKeyInternal( $this->keyspace, func_get_args() );
        }
 
index 6e9f387..d150880 100644 (file)
@@ -350,14 +350,14 @@ class MultiWriteBagOStuff extends BagOStuff {
        }
 
        public function makeKeyInternal( $keyspace, $args ) {
-               return $this->caches[0]->makeKeyInternal( ...func_get_args() );
+               return $this->caches[0]->makeKeyInternal( $keyspace, $args );
        }
 
-       public function makeKey( $class, $component = null ) {
+       public function makeKey( $class, ...$components ) {
                return $this->caches[0]->makeKey( ...func_get_args() );
        }
 
-       public function makeGlobalKey( $class, $component = null ) {
+       public function makeGlobalKey( $class, ...$components ) {
                return $this->caches[0]->makeGlobalKey( ...func_get_args() );
        }
 
index e49fa10..504d515 100644 (file)
@@ -162,11 +162,11 @@ class ReplicatedBagOStuff extends BagOStuff {
                return $this->writeStore->makeKeyInternal( ...func_get_args() );
        }
 
-       public function makeKey( $class, $component = null ) {
+       public function makeKey( $class, ...$components ) {
                return $this->writeStore->makeKey( ...func_get_args() );
        }
 
-       public function makeGlobalKey( $class, $component = null ) {
+       public function makeGlobalKey( $class, ...$components ) {
                return $this->writeStore->makeGlobalKey( ...func_get_args() );
        }
 
index f416ec5..69edb11 100644 (file)
@@ -118,20 +118,21 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
        protected $cache;
        /** @var MapCacheLRU[] Map of group PHP instance caches */
        protected $processCaches = [];
+       /** @var LoggerInterface */
+       protected $logger;
+       /** @var StatsdDataFactoryInterface */
+       protected $stats;
+       /** @var callable|null Function that takes a WAN cache callback and runs it later */
+       protected $asyncHandler;
+
        /** @bar bool Whether to use mcrouter key prefixing for routing */
        protected $mcrouterAware;
        /** @var string Physical region for mcrouter use */
        protected $region;
        /** @var string Cache cluster name for mcrouter use */
        protected $cluster;
-       /** @var LoggerInterface */
-       protected $logger;
-       /** @var StatsdDataFactoryInterface */
-       protected $stats;
        /** @var bool Whether to use "interim" caching while keys are tombstoned */
        protected $useInterimHoldOffCaching = true;
-       /** @var callable|null Function that takes a WAN cache callback and runs it later */
-       protected $asyncHandler;
        /** @var float Unix timestamp of the oldest possible valid values */
        protected $epoch;
        /** @var string Stable secret used for hasing long strings into key components */
@@ -147,93 +148,104 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
        /** @var float|null */
        private $wallClockOverride;
 
-       /** Max time expected to pass between delete() and DB commit finishing */
+       /** @var int Max expected seconds to pass between delete() and DB commit finishing */
        const MAX_COMMIT_DELAY = 3;
-       /** Max replication+snapshot lag before applying TTL_LAGGED or disallowing set() */
+       /** @var int Max expected seconds of combined lag from replication and view snapshots */
        const MAX_READ_LAG = 7;
-       /** Seconds to tombstone keys on delete() */
-       const HOLDOFF_TTL = 11; // MAX_COMMIT_DELAY + MAX_READ_LAG + 1
-
-       /** Seconds to keep dependency purge keys around */
-       const CHECK_KEY_TTL = self::TTL_YEAR;
-       /** Seconds to keep interim value keys for tombstoned keys around */
-       const INTERIM_KEY_TTL = 1;
-
-       /** Seconds to keep lock keys around */
-       const LOCK_TTL = 10;
-       /** Seconds to no-op key set() calls to avoid large blob I/O stampedes */
-       const COOLOFF_TTL = 1;
-       /** Default remaining TTL at which to consider pre-emptive regeneration */
+       /** @var int Seconds to tombstone keys on delete() and treat as volatile after invalidation */
+       const HOLDOFF_TTL = self::MAX_COMMIT_DELAY + self::MAX_READ_LAG + 1;
+
+       /** @var int Idiom for getWithSetCallback() meaning "do not store the callback result" */
+       const TTL_UNCACHEABLE = -1;
+
+       /** @var int Consider regeneration if the key will expire within this many seconds */
        const LOW_TTL = 30;
-       /** Max TTL to store keys when a data sourced is lagged */
+       /** @var int Max TTL, in seconds, to store keys when a data sourced is lagged */
        const TTL_LAGGED = 30;
 
-       /** Never consider performing "popularity" refreshes until a key reaches this age */
-       const AGE_NEW = 60;
-       /** The time length of the "popularity" refresh window for hot keys */
+       /** @var int Expected time-till-refresh, in seconds, if the key is accessed once per second */
        const HOT_TTR = 900;
-       /** Hits/second for a refresh to be expected within the "popularity" window */
-       const HIT_RATE_HIGH = 1;
-       /** Seconds to ramp up to the "popularity" refresh chance after a key is no longer new */
-       const RAMPUP_TTL = 30;
+       /** @var int Minimum key age, in seconds, for expected time-till-refresh to be considered */
+       const AGE_NEW = 60;
 
-       /** Idiom for getWithSetCallback() meaning "do not store the callback result" */
-       const TTL_UNCACHEABLE = -1;
-       /** Idiom for getWithSetCallback() meaning "no regeneration mutex based on key hotness" */
+       /** @var int Idiom for getWithSetCallback() meaning "no cache stampede mutex required" */
        const TSE_NONE = -1;
-       /** Idiom for set()/getWithSetCallback() meaning "no post-expiration persistence" */
+
+       /** @var int Idiom for set()/getWithSetCallback() meaning "no post-expiration persistence" */
        const STALE_TTL_NONE = 0;
-       /** Idiom for set()/getWithSetCallback() meaning "no post-expiration grace period" */
+       /** @var int Idiom for set()/getWithSetCallback() meaning "no post-expiration grace period" */
        const GRACE_TTL_NONE = 0;
-       /** Idiom for delete()/touchCheckKey() meaning "no hold-off period for cache writes" */
-       const HOLDOFF_NONE = 0;
+       /** @var int Idiom for delete()/touchCheckKey() meaning "no hold-off period" */
+       const HOLDOFF_TTL_NONE = 0;
+       /** @var int Alias for HOLDOFF_TTL_NONE (b/c) (deprecated since 1.34) */
+       const HOLDOFF_NONE = self::HOLDOFF_TTL_NONE;
 
-       /** Idiom for getWithSetCallback() meaning "no minimum required as-of timestamp" */
+       /** @var float Idiom for getWithSetCallback() meaning "no minimum required as-of timestamp" */
        const MIN_TIMESTAMP_NONE = 0.0;
-       /** @var int One second into the UNIX timestamp epoch */
-       const EPOCH_UNIX_ONE_SECOND = 1.0;
-
-       /** Tiny negative float to use when CTL comes up >= 0 due to clock skew */
-       const TINY_NEGATIVE = -0.000001;
-       /** Tiny positive float to use when using "minTime" to assert an inequality */
-       const TINY_POSTIVE = 0.000001;
 
-       /** Milliseconds of delay after get() where set() storms are a consideration with "lockTSE" */
-       const SET_DELAY_HIGH_MS = 50;
-       /** Min millisecond set() backoff for keys in hold-off (far less than INTERIM_KEY_TTL) */
-       const RECENT_SET_LOW_MS = 50;
-       /** Max millisecond set() backoff for keys in hold-off (far less than INTERIM_KEY_TTL) */
-       const RECENT_SET_HIGH_MS = 100;
+       /** @var string Default process cache name and max key count */
+       const PC_PRIMARY = 'primary:1000';
 
-       /** @var int Seconds needed for value generation considered slow */
-       const GENERATION_SLOW_SEC = 3;
-
-       /** Parameter to get()/getMulti() to return extra information by reference */
+       /** @var int Idion for get()/getMulti() to return extra information by reference */
        const PASS_BY_REF = -1;
 
-       /** Cache format version number */
-       const VERSION = 1;
-
-       const FLD_FORMAT_VERSION = 0; // key to WAN cache version number
-       const FLD_VALUE = 1; // key to the cached value
-       const FLD_TTL = 2; // key to the original TTL
-       const FLD_TIME = 3; // key to the cache timestamp
-       const FLD_FLAGS = 4; // key to the flags bitfield (reserved number)
-       const FLD_VALUE_VERSION = 5; // key to collection cache version number
-       const FLD_GENERATION_TIME = 6; // key to how long it took to generate the value
-
-       const PURGE_TIME = 0; // key to the tombstone entry timestamp
-       const PURGE_HOLDOFF = 1; // key to the tombstone entry hold-off TTL
-
-       const VALUE_KEY_PREFIX = 'WANCache:v:';
-       const INTERIM_KEY_PREFIX = 'WANCache:i:';
-       const TIME_KEY_PREFIX = 'WANCache:t:';
-       const MUTEX_KEY_PREFIX = 'WANCache:m:';
-       const COOLOFF_KEY_PREFIX = 'WANCache:c:';
-
-       const PURGE_VAL_PREFIX = 'PURGED:';
-
-       const PC_PRIMARY = 'primary:1000'; // process cache name and max key count
+       /** @var int Seconds to keep dependency purge keys around */
+       private static $CHECK_KEY_TTL = self::TTL_YEAR;
+       /** @var int Seconds to keep interim value keys for tombstoned keys around */
+       private static $INTERIM_KEY_TTL = 1;
+
+       /** @var int Seconds to keep lock keys around */
+       private static $LOCK_TTL = 10;
+       /** @var int Seconds to no-op key set() calls to avoid large blob I/O stampedes */
+       private static $COOLOFF_TTL = 1;
+       /** @var int Seconds to ramp up the chance of regeneration due to expected time-till-refresh */
+       private static $RAMPUP_TTL = 30;
+
+       /** @var float Tiny negative float to use when CTL comes up >= 0 due to clock skew */
+       private static $TINY_NEGATIVE = -0.000001;
+       /** @var float Tiny positive float to use when using "minTime" to assert an inequality */
+       private static $TINY_POSTIVE = 0.000001;
+
+       /** @var int Milliseconds of key fetch/validate/regenerate delay prone to set() stampedes */
+       private static $SET_DELAY_HIGH_MS = 50;
+       /** @var int Min millisecond set() backoff during hold-off (far less than INTERIM_KEY_TTL) */
+       private static $RECENT_SET_LOW_MS = 50;
+       /** @var int Max millisecond set() backoff during hold-off (far less than INTERIM_KEY_TTL) */
+       private static $RECENT_SET_HIGH_MS = 100;
+
+       /** @var int Consider value generation slow if it takes more than this many seconds */
+       private static $GENERATION_SLOW_SEC = 3;
+
+       /** @var int Key to the tombstone entry timestamp */
+       private static $PURGE_TIME = 0;
+       /** @var int Key to the tombstone entry hold-off TTL */
+       private static $PURGE_HOLDOFF = 1;
+
+       /** @var int Cache format version number */
+       private static $VERSION = 1;
+
+       /** @var int Key to WAN cache version number */
+       private static $FLD_FORMAT_VERSION = 0;
+       /** @var int Key to the cached value */
+       private static $FLD_VALUE = 1;
+       /** @var int Key to the original TTL */
+       private static $FLD_TTL = 2;
+       /** @var int Key to the cache timestamp */
+       private static $FLD_TIME = 3;
+       /** @var int Key to the flags bit field (reserved number) */
+       private static /** @noinspection PhpUnusedPrivateFieldInspection */ $FLD_FLAGS = 4;
+       /** @var int Key to collection cache version number */
+       private static $FLD_VALUE_VERSION = 5;
+       /** @var int Key to how long it took to generate the value */
+       private static $FLD_GENERATION_TIME = 6;
+
+       private static $VALUE_KEY_PREFIX = 'WANCache:v:';
+       private static $INTERIM_KEY_PREFIX = 'WANCache:i:';
+       private static $TIME_KEY_PREFIX = 'WANCache:t:';
+       private static $MUTEX_KEY_PREFIX = 'WANCache:m:';
+       private static $COOLOFF_KEY_PREFIX = 'WANCache:c:';
+
+       private static $PURGE_VAL_PREFIX = 'PURGED:';
 
        /**
         * @param array $params
@@ -265,7 +277,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                $this->region = $params['region'] ?? 'main';
                $this->cluster = $params['cluster'] ?? 'wan-main';
                $this->mcrouterAware = !empty( $params['mcrouterAware'] );
-               $this->epoch = $params['epoch'] ?? self::EPOCH_UNIX_ONE_SECOND;
+               $this->epoch = $params['epoch'] ?? 0;
                $this->secret = $params['secret'] ?? (string)$this->epoch;
 
                $this->setLogger( $params['logger'] ?? new NullLogger() );
@@ -392,14 +404,14 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                $curTTLs = [];
                $infoByKey = [];
 
-               $vPrefixLen = strlen( self::VALUE_KEY_PREFIX );
-               $valueKeys = self::prefixCacheKeys( $keys, self::VALUE_KEY_PREFIX );
+               $vPrefixLen = strlen( self::$VALUE_KEY_PREFIX );
+               $valueKeys = self::prefixCacheKeys( $keys, self::$VALUE_KEY_PREFIX );
 
                $checkKeysForAll = [];
                $checkKeysByKey = [];
                $checkKeysFlat = [];
                foreach ( $checkKeys as $i => $checkKeyGroup ) {
-                       $prefixed = self::prefixCacheKeys( (array)$checkKeyGroup, self::TIME_KEY_PREFIX );
+                       $prefixed = self::prefixCacheKeys( (array)$checkKeyGroup, self::$TIME_KEY_PREFIX );
                        $checkKeysFlat = array_merge( $checkKeysFlat, $prefixed );
                        // Are these check keys for a specific cache key, or for all keys being fetched?
                        if ( is_int( $i ) ) {
@@ -445,11 +457,11 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
 
                        $lastCKPurge = null; // timestamp of the highest check key
                        foreach ( $purgeValues as $purge ) {
-                               $lastCKPurge = max( $purge[self::PURGE_TIME], $lastCKPurge );
-                               $safeTimestamp = $purge[self::PURGE_TIME] + $purge[self::PURGE_HOLDOFF];
+                               $lastCKPurge = max( $purge[self::$PURGE_TIME], $lastCKPurge );
+                               $safeTimestamp = $purge[self::$PURGE_TIME] + $purge[self::$PURGE_HOLDOFF];
                                if ( $value !== false && $safeTimestamp >= $keyInfo['asOf'] ) {
                                        // How long ago this value was invalidated by *this* check key
-                                       $ago = min( $purge[self::PURGE_TIME] - $now, self::TINY_NEGATIVE );
+                                       $ago = min( $purge[self::$PURGE_TIME] - $now, self::$TINY_NEGATIVE );
                                        // How long ago this value was invalidated by *any* known check key
                                        $keyInfo['curTTL'] = min( $keyInfo['curTTL'], $ago );
                                }
@@ -489,7 +501,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                        if ( $purge === false ) {
                                // Key is not set or malformed; regenerate
                                $newVal = $this->makePurgeValue( $now, self::HOLDOFF_TTL );
-                               $this->cache->add( $timeKey, $newVal, self::CHECK_KEY_TTL );
+                               $this->cache->add( $timeKey, $newVal, self::$CHECK_KEY_TTL );
                                $purge = $this->parsePurgeValue( $newVal );
                        }
                        $purgeValues[] = $purge;
@@ -649,10 +661,10 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                $storeTTL = $ttl + $staleTTL;
 
                if ( $creating ) {
-                       $ok = $this->cache->add( self::VALUE_KEY_PREFIX . $key, $wrapped, $storeTTL );
+                       $ok = $this->cache->add( self::$VALUE_KEY_PREFIX . $key, $wrapped, $storeTTL );
                } else {
                        $ok = $this->cache->merge(
-                               self::VALUE_KEY_PREFIX . $key,
+                               self::$VALUE_KEY_PREFIX . $key,
                                function ( $cache, $key, $cWrapped ) use ( $wrapped ) {
                                        // A string value means that it is a tombstone; do nothing in that case
                                        return ( is_string( $cWrapped ) ) ? false : $wrapped;
@@ -716,7 +728,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         *
         * The $ttl parameter can be used when purging values that have not actually changed
         * recently. For example, a cleanup script to purge cache entries does not really need
-        * a hold-off period, so it can use HOLDOFF_NONE. Likewise for user-requested purge.
+        * a hold-off period, so it can use HOLDOFF_TTL_NONE. Likewise for user-requested purge.
         * Note that $ttl limits the effective range of 'lockTSE' for getWithSetCallback().
         *
         * If called twice on the same key, then the last hold-off TTL takes precedence. For
@@ -729,10 +741,10 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
        final public function delete( $key, $ttl = self::HOLDOFF_TTL ) {
                if ( $ttl <= 0 ) {
                        // Publish the purge to all datacenters
-                       $ok = $this->relayDelete( self::VALUE_KEY_PREFIX . $key );
+                       $ok = $this->relayDelete( self::$VALUE_KEY_PREFIX . $key );
                } else {
                        // Publish the purge to all datacenters
-                       $ok = $this->relayPurge( self::VALUE_KEY_PREFIX . $key, $ttl, self::HOLDOFF_NONE );
+                       $ok = $this->relayPurge( self::$VALUE_KEY_PREFIX . $key, $ttl, self::HOLDOFF_TTL_NONE );
                }
 
                $kClass = $this->determineKeyClassForStats( $key );
@@ -828,7 +840,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
        final public function getMultiCheckKeyTime( array $keys ) {
                $rawKeys = [];
                foreach ( $keys as $key ) {
-                       $rawKeys[$key] = self::TIME_KEY_PREFIX . $key;
+                       $rawKeys[$key] = self::$TIME_KEY_PREFIX . $key;
                }
 
                $rawValues = $this->cache->getMulti( $rawKeys );
@@ -838,14 +850,14 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                foreach ( $rawKeys as $key => $rawKey ) {
                        $purge = $this->parsePurgeValue( $rawValues[$rawKey] );
                        if ( $purge !== false ) {
-                               $time = $purge[self::PURGE_TIME];
+                               $time = $purge[self::$PURGE_TIME];
                        } else {
                                // Casting assures identical floats for the next getCheckKeyTime() calls
                                $now = (string)$this->getCurrentTime();
                                $this->cache->add(
                                        $rawKey,
                                        $this->makePurgeValue( $now, self::HOLDOFF_TTL ),
-                                       self::CHECK_KEY_TTL
+                                       self::$CHECK_KEY_TTL
                                );
                                $time = (float)$now;
                        }
@@ -887,12 +899,12 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         * @see WANObjectCache::resetCheckKey()
         *
         * @param string $key Cache key
-        * @param int $holdoff HOLDOFF_TTL or HOLDOFF_NONE constant
+        * @param int $holdoff HOLDOFF_TTL or HOLDOFF_TTL_NONE constant
         * @return bool True if the item was purged or not found, false on failure
         */
        final public function touchCheckKey( $key, $holdoff = self::HOLDOFF_TTL ) {
                // Publish the purge to all datacenters
-               $ok = $this->relayPurge( self::TIME_KEY_PREFIX . $key, self::CHECK_KEY_TTL, $holdoff );
+               $ok = $this->relayPurge( self::$TIME_KEY_PREFIX . $key, self::$CHECK_KEY_TTL, $holdoff );
 
                $kClass = $this->determineKeyClassForStats( $key );
                $this->stats->increment( "wanobjectcache.$kClass.ck_touch." . ( $ok ? 'ok' : 'error' ) );
@@ -929,7 +941,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         */
        final public function resetCheckKey( $key ) {
                // Publish the purge to all datacenters
-               $ok = $this->relayDelete( self::TIME_KEY_PREFIX . $key );
+               $ok = $this->relayDelete( self::$TIME_KEY_PREFIX . $key );
 
                $kClass = $this->determineKeyClassForStats( $key );
                $this->stats->increment( "wanobjectcache.$kClass.ck_reset." . ( $ok ? 'ok' : 'error' ) );
@@ -1456,7 +1468,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         */
        private function claimStampedeLock( $key ) {
                // Note that locking is not bypassed due to I/O errors; this avoids stampedes
-               return $this->cache->add( self::MUTEX_KEY_PREFIX . $key, 1, self::LOCK_TTL );
+               return $this->cache->add( self::$MUTEX_KEY_PREFIX . $key, 1, self::$LOCK_TTL );
        }
 
        /**
@@ -1468,7 +1480,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                        // The backend might be a mcrouter proxy set to broadcast DELETE to *all* the local
                        // datacenter cache servers via OperationSelectorRoute (for increased consistency).
                        // Since that would be excessive for these locks, use TOUCH to expire the key.
-                       $this->cache->changeTTL( self::MUTEX_KEY_PREFIX . $key, $this->getCurrentTime() - 60 );
+                       $this->cache->changeTTL( self::$MUTEX_KEY_PREFIX . $key, $this->getCurrentTime() - 60 );
                }
        }
 
@@ -1477,7 +1489,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         * @return bool Whether the age of a volatile value is negligible
         */
        private function isVolatileValueAgeNegligible( $age ) {
-               return ( $age < mt_rand( self::RECENT_SET_LOW_MS, self::RECENT_SET_HIGH_MS ) / 1e3 );
+               return ( $age < mt_rand( self::$RECENT_SET_LOW_MS, self::$RECENT_SET_HIGH_MS ) / 1e3 );
        }
 
        /**
@@ -1499,13 +1511,13 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                // consistent hashing).
                if ( $lockTSE < 0 || $hasLock ) {
                        return true; // either not a priori hot or thread has the lock
-               } elseif ( $elapsed <= self::SET_DELAY_HIGH_MS * 1e3 ) {
+               } elseif ( $elapsed <= self::$SET_DELAY_HIGH_MS * 1e3 ) {
                        return true; // not enough time for threads to pile up
                }
 
                $this->cache->clearLastError();
                if (
-                       !$this->cache->add( self::COOLOFF_KEY_PREFIX . $key, 1, self::COOLOFF_TTL ) &&
+                       !$this->cache->add( self::$COOLOFF_KEY_PREFIX . $key, 1, self::$COOLOFF_TTL ) &&
                        // Don't treat failures due to I/O errors as the key being in cooloff
                        $this->cache->getLastError() === BagOStuff::ERR_NONE
                ) {
@@ -1532,7 +1544,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
 
                $touched = $touchedCallback( $value );
                if ( $touched !== null && $touched >= $curInfo['asOf'] ) {
-                       $curTTL = min( $curTTL, self::TINY_NEGATIVE, $curInfo['asOf'] - $touched );
+                       $curTTL = min( $curTTL, self::$TINY_NEGATIVE, $curInfo['asOf'] - $touched );
                }
 
                return [ $curTTL, max( $curInfo['tombAsOf'], $curInfo['lastCKPurge'], $touched ) ];
@@ -1560,7 +1572,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                $now = $this->getCurrentTime();
 
                if ( $this->useInterimHoldOffCaching ) {
-                       $wrapped = $this->cache->get( self::INTERIM_KEY_PREFIX . $key );
+                       $wrapped = $this->cache->get( self::$INTERIM_KEY_PREFIX . $key );
 
                        list( $value, $keyInfo ) = $this->unwrap( $wrapped, $now );
                        if ( $this->isValid( $value, $keyInfo['asOf'], $minAsOf ) ) {
@@ -1579,11 +1591,11 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         * @param float $walltime How long it took to generate the value in seconds
         */
        private function setInterimValue( $key, $value, $ttl, $version, $walltime ) {
-               $ttl = max( self::INTERIM_KEY_TTL, (int)$ttl );
+               $ttl = max( self::$INTERIM_KEY_TTL, (int)$ttl );
 
                $wrapped = $this->wrap( $value, $ttl, $version, $this->getCurrentTime(), $walltime );
                $this->cache->merge(
-                       self::INTERIM_KEY_PREFIX . $key,
+                       self::$INTERIM_KEY_PREFIX . $key,
                        function () use ( $wrapped ) {
                                return $wrapped;
                        },
@@ -1825,12 +1837,12 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         */
        final public function reap( $key, $purgeTimestamp, &$isStale = false ) {
                $minAsOf = $purgeTimestamp + self::HOLDOFF_TTL;
-               $wrapped = $this->cache->get( self::VALUE_KEY_PREFIX . $key );
-               if ( is_array( $wrapped ) && $wrapped[self::FLD_TIME] < $minAsOf ) {
+               $wrapped = $this->cache->get( self::$VALUE_KEY_PREFIX . $key );
+               if ( is_array( $wrapped ) && $wrapped[self::$FLD_TIME] < $minAsOf ) {
                        $isStale = true;
                        $this->logger->warning( "Reaping stale value key '$key'." );
                        $ttlReap = self::HOLDOFF_TTL; // avoids races with tombstone creation
-                       $ok = $this->cache->changeTTL( self::VALUE_KEY_PREFIX . $key, $ttlReap );
+                       $ok = $this->cache->changeTTL( self::$VALUE_KEY_PREFIX . $key, $ttlReap );
                        if ( !$ok ) {
                                $this->logger->error( "Could not complete reap of key '$key'." );
                        }
@@ -1853,11 +1865,11 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         * @since 1.28
         */
        final public function reapCheckKey( $key, $purgeTimestamp, &$isStale = false ) {
-               $purge = $this->parsePurgeValue( $this->cache->get( self::TIME_KEY_PREFIX . $key ) );
-               if ( $purge && $purge[self::PURGE_TIME] < $purgeTimestamp ) {
+               $purge = $this->parsePurgeValue( $this->cache->get( self::$TIME_KEY_PREFIX . $key ) );
+               if ( $purge && $purge[self::$PURGE_TIME] < $purgeTimestamp ) {
                        $isStale = true;
                        $this->logger->warning( "Reaping stale check key '$key'." );
-                       $ok = $this->cache->changeTTL( self::TIME_KEY_PREFIX . $key, self::TTL_SECOND );
+                       $ok = $this->cache->changeTTL( self::$TIME_KEY_PREFIX . $key, self::TTL_SECOND );
                        if ( !$ok ) {
                                $this->logger->error( "Could not complete reap of check key '$key'." );
                        }
@@ -1873,22 +1885,22 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
        /**
         * @see BagOStuff::makeKey()
         * @param string $class Key class
-        * @param string|null $component [optional] Key component (starting with a key collection name)
-        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        * @param string ...$components Key components (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components
         * @since 1.27
         */
-       public function makeKey( $class, $component = null ) {
+       public function makeKey( $class, ...$components ) {
                return $this->cache->makeKey( ...func_get_args() );
        }
 
        /**
         * @see BagOStuff::makeGlobalKey()
         * @param string $class Key class
-        * @param string|null $component [optional] Key component (starting with a key collection name)
-        * @return string Colon-delimited list of $keyspace followed by escaped components of $args
+        * @param string ...$components Key components (starting with a key collection name)
+        * @return string Colon-delimited list of $keyspace followed by escaped components
         * @since 1.27
         */
-       public function makeGlobalKey( $class, $component = null ) {
+       public function makeGlobalKey( $class, ...$components ) {
                return $this->cache->makeGlobalKey( ...func_get_args() );
        }
 
@@ -2190,14 +2202,14 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                        // Wildcards select all matching routes, e.g. the WAN cluster on all DCs
                        $ok = $this->cache->set(
                                "/*/{$this->cluster}/{$key}",
-                               $this->makePurgeValue( $this->getCurrentTime(), self::HOLDOFF_NONE ),
+                               $this->makePurgeValue( $this->getCurrentTime(), self::HOLDOFF_TTL_NONE ),
                                $ttl
                        );
                } else {
                        // This handles the mcrouter and the single-DC case
                        $ok = $this->cache->set(
                                $key,
-                               $this->makePurgeValue( $this->getCurrentTime(), self::HOLDOFF_NONE ),
+                               $this->makePurgeValue( $this->getCurrentTime(), self::HOLDOFF_TTL_NONE ),
                                $ttl
                        );
                }
@@ -2329,17 +2341,18 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                        return false;
                }
 
+               $popularHitsPerSec = 1;
                // Lifecycle is: new, ramp-up refresh chance, full refresh chance.
-               // Note that the "expected # of refreshes" for the ramp-up time range is half of what it
-               // would be if P(refresh) was at its full value during that time range.
-               $refreshWindowSec = max( $timeTillRefresh - $ageNew - self::RAMPUP_TTL / 2, 1 );
+               // Note that the "expected # of refreshes" for the ramp-up time range is half
+               // of what it would be if P(refresh) was at its full value during that time range.
+               $refreshWindowSec = max( $timeTillRefresh - $ageNew - self::$RAMPUP_TTL / 2, 1 );
                // P(refresh) * (# hits in $refreshWindowSec) = (expected # of refreshes)
-               // P(refresh) * ($refreshWindowSec * $popularHitsPerSec) = 1
+               // P(refresh) * ($refreshWindowSec * $popularHitsPerSec) = 1 (by definition)
                // P(refresh) = 1/($refreshWindowSec * $popularHitsPerSec)
-               $chance = 1 / ( self::HIT_RATE_HIGH * $refreshWindowSec );
+               $chance = 1 / ( $popularHitsPerSec * $refreshWindowSec );
 
                // Ramp up $chance from 0 to its nominal value over RAMPUP_TTL seconds to avoid stampedes
-               $chance *= ( $timeOld <= self::RAMPUP_TTL ) ? $timeOld / self::RAMPUP_TTL : 1;
+               $chance *= ( $timeOld <= self::$RAMPUP_TTL ) ? $timeOld / self::$RAMPUP_TTL : 1;
 
                return mt_rand( 1, 1e9 ) <= 1e9 * $chance;
        }
@@ -2355,7 +2368,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         */
        protected function isValid( $value, $asOf, $minAsOf, $purgeTime = null ) {
                // Avoid reading any key not generated after the latest delete() or touch
-               $safeMinAsOf = max( $minAsOf, $purgeTime + self::TINY_POSTIVE );
+               $safeMinAsOf = max( $minAsOf, $purgeTime + self::$TINY_POSTIVE );
 
                if ( $value === false ) {
                        return false;
@@ -2378,16 +2391,16 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                // Returns keys in ascending integer order for PHP7 array packing:
                // https://nikic.github.io/2014/12/22/PHPs-new-hashtable-implementation.html
                $wrapped = [
-                       self::FLD_FORMAT_VERSION => self::VERSION,
-                       self::FLD_VALUE => $value,
-                       self::FLD_TTL => $ttl,
-                       self::FLD_TIME => $now
+                       self::$FLD_FORMAT_VERSION => self::$VERSION,
+                       self::$FLD_VALUE => $value,
+                       self::$FLD_TTL => $ttl,
+                       self::$FLD_TIME => $now
                ];
                if ( $version !== null ) {
-                       $wrapped[self::FLD_VALUE_VERSION] = $version;
+                       $wrapped[self::$FLD_VALUE_VERSION] = $version;
                }
-               if ( $walltime >= self::GENERATION_SLOW_SEC ) {
-                       $wrapped[self::FLD_GENERATION_TIME] = $walltime;
+               if ( $walltime >= self::$GENERATION_SLOW_SEC ) {
+                       $wrapped[self::$FLD_GENERATION_TIME] = $walltime;
                }
 
                return $wrapped;
@@ -2410,20 +2423,20 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                if ( is_array( $wrapped ) ) {
                        // Entry expected to be a cached value; validate it
                        if (
-                               ( $wrapped[self::FLD_FORMAT_VERSION] ?? null ) === self::VERSION &&
-                               $wrapped[self::FLD_TIME] >= $this->epoch
+                               ( $wrapped[self::$FLD_FORMAT_VERSION] ?? null ) === self::$VERSION &&
+                               $wrapped[self::$FLD_TIME] >= $this->epoch
                        ) {
-                               if ( $wrapped[self::FLD_TTL] > 0 ) {
+                               if ( $wrapped[self::$FLD_TTL] > 0 ) {
                                        // Get the approximate time left on the key
-                                       $age = $now - $wrapped[self::FLD_TIME];
-                                       $curTTL = max( $wrapped[self::FLD_TTL] - $age, 0.0 );
+                                       $age = $now - $wrapped[self::$FLD_TIME];
+                                       $curTTL = max( $wrapped[self::$FLD_TTL] - $age, 0.0 );
                                } else {
                                        // Key had no TTL, so the time left is unbounded
                                        $curTTL = INF;
                                }
-                               $value = $wrapped[self::FLD_VALUE];
-                               $info['version'] = $wrapped[self::FLD_VALUE_VERSION] ?? null;
-                               $info['asOf'] = $wrapped[self::FLD_TIME];
+                               $value = $wrapped[self::$FLD_VALUE];
+                               $info['version'] = $wrapped[self::$FLD_VALUE_VERSION] ?? null;
+                               $info['asOf'] = $wrapped[self::$FLD_TIME];
                                $info['curTTL'] = $curTTL;
                        }
                } else {
@@ -2431,8 +2444,8 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                        $purge = $this->parsePurgeValue( $wrapped );
                        if ( $purge !== false ) {
                                // Tombstoned keys should always have a negative current $ttl
-                               $info['curTTL'] = min( $purge[self::PURGE_TIME] - $now, self::TINY_NEGATIVE );
-                               $info['tombAsOf'] = $purge[self::PURGE_TIME];
+                               $info['curTTL'] = min( $purge[self::$PURGE_TIME] - $now, self::$TINY_NEGATIVE );
+                               $info['tombAsOf'] = $purge[self::$PURGE_TIME];
                        }
                }
 
@@ -2474,8 +2487,10 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                }
 
                $segments = explode( ':', $value, 3 );
-               if ( !isset( $segments[0] ) || !isset( $segments[1] )
-                       || "{$segments[0]}:" !== self::PURGE_VAL_PREFIX
+               if (
+                       !isset( $segments[0] ) ||
+                       !isset( $segments[1] ) ||
+                       "{$segments[0]}:" !== self::$PURGE_VAL_PREFIX
                ) {
                        return false;
                }
@@ -2491,8 +2506,8 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                }
 
                return [
-                       self::PURGE_TIME => (float)$segments[1],
-                       self::PURGE_HOLDOFF => (int)$segments[2],
+                       self::$PURGE_TIME => (float)$segments[1],
+                       self::$PURGE_HOLDOFF => (int)$segments[2],
                ];
        }
 
@@ -2502,7 +2517,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         * @return string Wrapped purge value
         */
        private function makePurgeValue( $timestamp, $holdoff ) {
-               return self::PURGE_VAL_PREFIX . (float)$timestamp . ':' . (int)$holdoff;
+               return self::$PURGE_VAL_PREFIX . (float)$timestamp . ':' . (int)$holdoff;
        }
 
        /**
@@ -2562,18 +2577,18 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                $keysWarmUp = [];
                // Get all the value keys to fetch...
                foreach ( $keys as $key ) {
-                       $keysWarmUp[] = self::VALUE_KEY_PREFIX . $key;
+                       $keysWarmUp[] = self::$VALUE_KEY_PREFIX . $key;
                }
                // Get all the check keys to fetch...
                foreach ( $checkKeys as $i => $checkKeyOrKeys ) {
                        if ( is_int( $i ) ) {
                                // Single check key that applies to all value keys
-                               $keysWarmUp[] = self::TIME_KEY_PREFIX . $checkKeyOrKeys;
+                               $keysWarmUp[] = self::$TIME_KEY_PREFIX . $checkKeyOrKeys;
                        } else {
                                // List of check keys that apply to value key $i
                                $keysWarmUp = array_merge(
                                        $keysWarmUp,
-                                       self::prefixCacheKeys( $checkKeyOrKeys, self::TIME_KEY_PREFIX )
+                                       self::prefixCacheKeys( $checkKeyOrKeys, self::$TIME_KEY_PREFIX )
                                );
                        }
                }
index 048b567..3bc19ff 100644 (file)
@@ -23,6 +23,8 @@
  * @since 1.22
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * This class formats delete log entries.
  *
@@ -280,10 +282,10 @@ class DeleteLogFormatter extends LogFormatter {
                        ];
 
                        static $fields = [
-                               Revision::DELETED_TEXT => 'content',
-                               Revision::DELETED_COMMENT => 'comment',
-                               Revision::DELETED_USER => 'user',
-                               Revision::DELETED_RESTRICTED => 'restricted',
+                               RevisionRecord::DELETED_TEXT => 'content',
+                               RevisionRecord::DELETED_COMMENT => 'comment',
+                               RevisionRecord::DELETED_USER => 'user',
+                               RevisionRecord::DELETED_RESTRICTED => 'restricted',
                        ];
 
                        if ( isset( $rawParams['6::ofield'] ) ) {
index 4e28085..f158e4d 100644 (file)
@@ -454,7 +454,9 @@ class Article implements Page {
                $this->mRevIdFetched = $this->mRevision->getId();
                $this->fetchResult = Status::newGood( $this->mRevision );
 
-               if ( !$this->mRevision->userCan( Revision::DELETED_TEXT, $this->getContext()->getUser() ) ) {
+               if (
+                       !$this->mRevision->userCan( RevisionRecord::DELETED_TEXT, $this->getContext()->getUser() )
+               ) {
                        wfDebug( __METHOD__ . " failed to retrieve content of revision " .
                                $this->mRevision->getId() . "\n" );
 
@@ -466,7 +468,7 @@ class Article implements Page {
 
                if ( Hooks::isRegistered( 'ArticleAfterFetchContentObject' ) ) {
                        $contentObject = $this->mRevision->getContent(
-                               Revision::FOR_THIS_USER,
+                               RevisionRecord::FOR_THIS_USER,
                                $this->getContext()->getUser()
                        );
 
@@ -489,7 +491,7 @@ class Article implements Page {
 
                // For B/C only
                $this->mContentObject = $this->mRevision->getContent(
-                       Revision::FOR_THIS_USER,
+                       RevisionRecord::FOR_THIS_USER,
                        $this->getContext()->getUser()
                );
 
@@ -1481,7 +1483,7 @@ class Article implements Page {
         * @return bool True if the view is allowed, false if not.
         */
        public function showDeletedRevisionHeader() {
-               if ( !$this->mRevision->isDeleted( Revision::DELETED_TEXT ) ) {
+               if ( !$this->mRevision->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                        // Not deleted
                        return true;
                }
@@ -1489,7 +1491,7 @@ class Article implements Page {
                $outputPage = $this->getContext()->getOutput();
                $user = $this->getContext()->getUser();
                // If the user is not allowed to see it...
-               if ( !$this->mRevision->userCan( Revision::DELETED_TEXT, $user ) ) {
+               if ( !$this->mRevision->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                        $outputPage->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                'rev-deleted-text-permission' );
 
@@ -1499,7 +1501,7 @@ class Article implements Page {
                        # Give explanation and add a link to view the revision...
                        $oldid = intval( $this->getOldID() );
                        $link = $this->getTitle()->getFullURL( "oldid={$oldid}&unhide=1" );
-                       $msg = $this->mRevision->isDeleted( Revision::DELETED_RESTRICTED ) ?
+                       $msg = $this->mRevision->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ?
                                'rev-suppressed-text-unhide' : 'rev-deleted-text-unhide';
                        $outputPage->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                [ $msg, $link ] );
@@ -1507,7 +1509,7 @@ class Article implements Page {
                        return false;
                // We are allowed to see...
                } else {
-                       $msg = $this->mRevision->isDeleted( Revision::DELETED_RESTRICTED ) ?
+                       $msg = $this->mRevision->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ?
                                'rev-suppressed-text-view' : 'rev-deleted-text-view';
                        $outputPage->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n", $msg );
 
@@ -2412,7 +2414,7 @@ class Article implements Page {
         * Call to WikiPage function for backwards compatibility.
         * @see WikiPage::getComment
         */
-       public function getComment( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+       public function getComment( $audience = RevisionRecord::FOR_PUBLIC, User $user = null ) {
                return $this->mPage->getComment( $audience, $user );
        }
 
@@ -2444,7 +2446,7 @@ class Article implements Page {
         * Call to WikiPage function for backwards compatibility.
         * @see WikiPage::getCreator
         */
-       public function getCreator( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+       public function getCreator( $audience = RevisionRecord::FOR_PUBLIC, User $user = null ) {
                return $this->mPage->getCreator( $audience, $user );
        }
 
@@ -2556,7 +2558,7 @@ class Article implements Page {
         * Call to WikiPage function for backwards compatibility.
         * @see WikiPage::getUser
         */
-       public function getUser( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+       public function getUser( $audience = RevisionRecord::FOR_PUBLIC, User $user = null ) {
                return $this->mPage->getUser( $audience, $user );
        }
 
@@ -2564,7 +2566,7 @@ class Article implements Page {
         * Call to WikiPage function for backwards compatibility.
         * @see WikiPage::getUserText
         */
-       public function getUserText( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+       public function getUserText( $audience = RevisionRecord::FOR_PUBLIC, User $user = null ) {
                return $this->mPage->getUserText( $audience, $user );
        }
 
index fdba6fb..173fdc6 100644 (file)
@@ -813,7 +813,7 @@ class WikiPage implements Page, IDBAccessObject {
         *
         * @since 1.21
         */
-       public function getContent( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+       public function getContent( $audience = RevisionRecord::FOR_PUBLIC, User $user = null ) {
                $this->loadLastEdit();
                if ( $this->mLastRevision ) {
                        return $this->mLastRevision->getContent( $audience, $user );
@@ -851,7 +851,7 @@ class WikiPage implements Page, IDBAccessObject {
         *   to the $audience parameter
         * @return int User ID for the user that made the last article revision
         */
-       public function getUser( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+       public function getUser( $audience = RevisionRecord::FOR_PUBLIC, User $user = null ) {
                $this->loadLastEdit();
                if ( $this->mLastRevision ) {
                        return $this->mLastRevision->getUser( $audience, $user );
@@ -870,7 +870,7 @@ class WikiPage implements Page, IDBAccessObject {
         *   to the $audience parameter
         * @return User|null
         */
-       public function getCreator( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+       public function getCreator( $audience = RevisionRecord::FOR_PUBLIC, User $user = null ) {
                $revision = $this->getOldestRevision();
                if ( $revision ) {
                        $userName = $revision->getUserText( $audience, $user );
@@ -889,7 +889,7 @@ class WikiPage implements Page, IDBAccessObject {
         *   to the $audience parameter
         * @return string Username of the user that made the last article revision
         */
-       public function getUserText( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+       public function getUserText( $audience = RevisionRecord::FOR_PUBLIC, User $user = null ) {
                $this->loadLastEdit();
                if ( $this->mLastRevision ) {
                        return $this->mLastRevision->getUserText( $audience, $user );
@@ -908,7 +908,7 @@ class WikiPage implements Page, IDBAccessObject {
         * @return string|null Comment stored for the last article revision, or null if the specified
         *  audience does not have access to the comment.
         */
-       public function getComment( $audience = Revision::FOR_PUBLIC, User $user = null ) {
+       public function getComment( $audience = RevisionRecord::FOR_PUBLIC, User $user = null ) {
                $this->loadLastEdit();
                if ( $this->mLastRevision ) {
                        return $this->mLastRevision->getComment( $audience, $user );
@@ -1176,7 +1176,7 @@ class WikiPage implements Page, IDBAccessObject {
                $conds[] = 'NOT(' . $actorMigration->getWhere( $dbr, 'rev_user', $user )['conds'] . ')';
 
                // Username hidden?
-               $conds[] = "{$dbr->bitAnd( 'rev_deleted', Revision::DELETED_USER )} = 0";
+               $conds[] = "{$dbr->bitAnd( 'rev_deleted', RevisionRecord::DELETED_USER )} = 0";
 
                $jconds = [
                        'user' => [ 'LEFT JOIN', $actorQuery['fields']['rev_user'] . ' = user_id' ],
@@ -2695,7 +2695,7 @@ class WikiPage implements Page, IDBAccessObject {
                // we need to remember the old content so we can use it to generate all deletion updates.
                $revision = $this->getRevision();
                try {
-                       $content = $this->getContent( Revision::RAW );
+                       $content = $this->getContent( RevisionRecord::RAW );
                } catch ( Exception $ex ) {
                        wfLogWarning( __METHOD__ . ': failed to load content during deletion! '
                                . $ex->getMessage() );
@@ -2844,7 +2844,7 @@ class WikiPage implements Page, IDBAccessObject {
 
                // Bitfields to further suppress the content
                if ( $suppress ) {
-                       $bitfield = Revision::SUPPRESSED_ALL;
+                       $bitfield = RevisionRecord::SUPPRESSED_ALL;
                        $revQuery['fields'] = array_diff( $revQuery['fields'], [ 'rev_deleted' ] );
                }
 
@@ -3768,7 +3768,7 @@ class WikiPage implements Page, IDBAccessObject {
                        $slotContent = [ SlotRecord::MAIN => $rev ];
                } else {
                        $slotContent = array_map( function ( SlotRecord $slot ) {
-                               return $slot->getContent( Revision::RAW );
+                               return $slot->getContent( RevisionRecord::RAW );
                        }, $rev->getSlots()->getSlots() );
                }
 
index 457648a..fca06c9 100644 (file)
@@ -177,7 +177,7 @@ class MessageBlobStore implements LoggerAwareInterface {
                // - This global check key invalidates message blobs for all modules for all wikis
                //   in cache contexts (e.g. languages, skins). Setting a hold-off on this key could
                //   cause a cache stampede since no values would be stored for several seconds.
-               $cache->touchCheckKey( $cache->makeGlobalKey( __CLASS__ ), $cache::HOLDOFF_NONE );
+               $cache->touchCheckKey( $cache->makeGlobalKey( __CLASS__ ), $cache::HOLDOFF_TTL_NONE );
        }
 
        /**
index d37c31b..b104073 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use MediaWiki\Linker\LinkTarget;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Assert\Assert;
 use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
@@ -220,7 +221,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                        if ( !$revision ) {
                                return null;
                        }
-                       $content = $revision->getContent( Revision::RAW );
+                       $content = $revision->getContent( RevisionRecord::RAW );
 
                        if ( !$content ) {
                                $this->getLogger()->error(
index 00e40a0..ab9830f 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Item class for a filearchive table row
  */
@@ -109,8 +111,8 @@ class RevDelArchivedFileItem extends RevDelFileItem {
                        'width' => $file->getWidth(),
                        'height' => $file->getHeight(),
                        'size' => $file->getSize(),
-                       'userhidden' => (bool)$file->isDeleted( Revision::DELETED_USER ),
-                       'commenthidden' => (bool)$file->isDeleted( Revision::DELETED_COMMENT ),
+                       'userhidden' => (bool)$file->isDeleted( RevisionRecord::DELETED_USER ),
+                       'commenthidden' => (bool)$file->isDeleted( RevisionRecord::DELETED_COMMENT ),
                        'contenthidden' => (bool)$this->isDeleted(),
                ];
                if ( $this->canViewContent() ) {
@@ -124,13 +126,13 @@ class RevDelArchivedFileItem extends RevDelFileItem {
                                ),
                        ];
                }
-               if ( $file->userCan( Revision::DELETED_USER, $user ) ) {
+               if ( $file->userCan( RevisionRecord::DELETED_USER, $user ) ) {
                        $ret += [
                                'userid' => $file->getUser( 'id' ),
                                'user' => $file->getUser( 'text' ),
                        ];
                }
-               if ( $file->userCan( Revision::DELETED_COMMENT, $user ) ) {
+               if ( $file->userCan( RevisionRecord::DELETED_COMMENT, $user ) ) {
                        $ret += [
                                'comment' => $file->getRawDescription(),
                        ];
index c7941b7..8c080ba 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Item class for an oldimage table row
  */
@@ -164,14 +166,14 @@ class RevDelFileItem extends RevDelItem {
         * @return string HTML
         */
        protected function getUserTools() {
-               if ( $this->file->userCan( Revision::DELETED_USER, $this->list->getUser() ) ) {
+               if ( $this->file->userCan( RevisionRecord::DELETED_USER, $this->list->getUser() ) ) {
                        $uid = $this->file->getUser( 'id' );
                        $name = $this->file->getUser( 'text' );
                        $link = Linker::userLink( $uid, $name ) . Linker::userToolLinks( $uid, $name );
                } else {
                        $link = $this->list->msg( 'rev-deleted-user' )->escaped();
                }
-               if ( $this->file->isDeleted( Revision::DELETED_USER ) ) {
+               if ( $this->file->isDeleted( RevisionRecord::DELETED_USER ) ) {
                        return '<span class="history-deleted">' . $link . '</span>';
                }
 
@@ -217,8 +219,8 @@ class RevDelFileItem extends RevDelItem {
                        'width' => $file->getWidth(),
                        'height' => $file->getHeight(),
                        'size' => $file->getSize(),
-                       'userhidden' => (bool)$file->isDeleted( Revision::DELETED_USER ),
-                       'commenthidden' => (bool)$file->isDeleted( Revision::DELETED_COMMENT ),
+                       'userhidden' => (bool)$file->isDeleted( RevisionRecord::DELETED_USER ),
+                       'commenthidden' => (bool)$file->isDeleted( RevisionRecord::DELETED_COMMENT ),
                        'contenthidden' => (bool)$this->isDeleted(),
                ];
                if ( !$this->isDeleted() ) {
@@ -236,13 +238,13 @@ class RevDelFileItem extends RevDelItem {
                                ),
                        ];
                }
-               if ( $file->userCan( Revision::DELETED_USER, $user ) ) {
+               if ( $file->userCan( RevisionRecord::DELETED_USER, $user ) ) {
                        $ret += [
                                'userid' => $file->user,
                                'user' => $file->user_text,
                        ];
                }
-               if ( $file->userCan( Revision::DELETED_COMMENT, $user ) ) {
+               if ( $file->userCan( RevisionRecord::DELETED_COMMENT, $user ) ) {
                        $ret += [
                                'comment' => $file->description,
                        ];
index 221359d..680ae8e 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 
 /**
  * Abstract base class for a list of deletable items. The list class
@@ -195,7 +196,7 @@ abstract class RevDelList extends RevisionListBase {
                                $status->failCount++;
                                continue;
                        // Cannot just "hide from Sysops" without hiding any fields
-                       } elseif ( $newBits == Revision::DELETED_RESTRICTED ) {
+                       } elseif ( $newBits == RevisionRecord::DELETED_RESTRICTED ) {
                                $itemStatus->warning(
                                        'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
                                $status->failCount++;
index 54a715d..edb86da 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Item class for a logging table row
  */
@@ -44,7 +46,9 @@ class RevDelLogItem extends RevDelItem {
        }
 
        public function canView() {
-               return LogEventsList::userCan( $this->row, Revision::DELETED_RESTRICTED, $this->list->getUser() );
+               return LogEventsList::userCan(
+                       $this->row, RevisionRecord::DELETED_RESTRICTED, $this->list->getUser()
+               );
        }
 
        public function canViewContent() {
index b26fffd..fcdcb9a 100644 (file)
@@ -19,6 +19,7 @@
  * @ingroup RevisionDelete
  */
 
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
@@ -91,7 +92,7 @@ class RevDelLogList extends RevDelList {
        }
 
        public function getSuppressBit() {
-               return Revision::DELETED_RESTRICTED;
+               return RevisionRecord::DELETED_RESTRICTED;
        }
 
        public function getLogAction() {
index 6eb0b37..a5859e5 100644 (file)
@@ -19,6 +19,8 @@
  * @ingroup RevisionDelete
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Item class for a live revision table row
  */
@@ -63,11 +65,15 @@ class RevDelRevisionItem extends RevDelItem {
        }
 
        public function canView() {
-               return $this->revision->userCan( Revision::DELETED_RESTRICTED, $this->list->getUser() );
+               return $this->revision->userCan(
+                       RevisionRecord::DELETED_RESTRICTED, $this->list->getUser()
+               );
        }
 
        public function canViewContent() {
-               return $this->revision->userCan( Revision::DELETED_TEXT, $this->list->getUser() );
+               return $this->revision->userCan(
+                       RevisionRecord::DELETED_TEXT, $this->list->getUser()
+               );
        }
 
        public function getBits() {
@@ -108,11 +114,11 @@ class RevDelRevisionItem extends RevDelItem {
        }
 
        public function isDeleted() {
-               return $this->revision->isDeleted( Revision::DELETED_TEXT );
+               return $this->revision->isDeleted( RevisionRecord::DELETED_TEXT );
        }
 
        public function isHideCurrentOp( $newBits ) {
-               return ( $newBits & Revision::DELETED_TEXT )
+               return ( $newBits & RevisionRecord::DELETED_TEXT )
                        && $this->list->getCurrent() == $this->getId();
        }
 
@@ -203,19 +209,19 @@ class RevDelRevisionItem extends RevDelItem {
                $ret = [
                        'id' => $rev->getId(),
                        'timestamp' => wfTimestamp( TS_ISO_8601, $rev->getTimestamp() ),
-                       'userhidden' => (bool)$rev->isDeleted( Revision::DELETED_USER ),
-                       'commenthidden' => (bool)$rev->isDeleted( Revision::DELETED_COMMENT ),
-                       'texthidden' => (bool)$rev->isDeleted( Revision::DELETED_TEXT ),
+                       'userhidden' => (bool)$rev->isDeleted( RevisionRecord::DELETED_USER ),
+                       'commenthidden' => (bool)$rev->isDeleted( RevisionRecord::DELETED_COMMENT ),
+                       'texthidden' => (bool)$rev->isDeleted( RevisionRecord::DELETED_TEXT ),
                ];
-               if ( $rev->userCan( Revision::DELETED_USER, $user ) ) {
+               if ( $rev->userCan( RevisionRecord::DELETED_USER, $user ) ) {
                        $ret += [
-                               'userid' => $rev->getUser( Revision::FOR_THIS_USER ),
-                               'user' => $rev->getUserText( Revision::FOR_THIS_USER ),
+                               'userid' => $rev->getUser( RevisionRecord::FOR_THIS_USER ),
+                               'user' => $rev->getUserText( RevisionRecord::FOR_THIS_USER ),
                        ];
                }
-               if ( $rev->userCan( Revision::DELETED_COMMENT, $user ) ) {
+               if ( $rev->userCan( RevisionRecord::DELETED_COMMENT, $user ) ) {
                        $ret += [
-                               'comment' => $rev->getComment( Revision::FOR_THIS_USER ),
+                               'comment' => $rev->getComment( RevisionRecord::FOR_THIS_USER ),
                        ];
                }
 
index 07362c4..0705503 100644 (file)
@@ -19,6 +19,7 @@
  * @ingroup RevisionDelete
  */
 
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\FakeResultWrapper;
 use Wikimedia\Rdbms\IDatabase;
 
@@ -48,7 +49,7 @@ class RevDelRevisionList extends RevDelList {
        }
 
        public static function getRevdelConstant() {
-               return Revision::DELETED_TEXT;
+               return RevisionRecord::DELETED_TEXT;
        }
 
        public static function suggestTarget( $target, array $ids ) {
@@ -167,7 +168,7 @@ class RevDelRevisionList extends RevDelList {
        }
 
        public function getSuppressBit() {
-               return Revision::DELETED_RESTRICTED;
+               return RevisionRecord::DELETED_RESTRICTED;
        }
 
        public function doPreCommitUpdates() {
index f7f7e89..5644b95 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup RevisionDelete
  */
 
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
@@ -52,13 +53,13 @@ class RevisionDeleteUser {
                        $dbw = wfGetDB( DB_MASTER );
                }
 
-               # To suppress, we OR the current bitfields with Revision::DELETED_USER
+               # To suppress, we OR the current bitfields with RevisionRecord::DELETED_USER
                # to put a 1 in the username *_deleted bit. To unsuppress we AND the
-               # current bitfields with the inverse of Revision::DELETED_USER. The
+               # current bitfields with the inverse of RevisionRecord::DELETED_USER. The
                # username bit is made to 0 (x & 0 = 0), while others are unchanged (x & 1 = x).
                # The same goes for the sysop-restricted *_deleted bit.
-               $delUser = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
-               $delAction = LogPage::DELETED_ACTION | Revision::DELETED_RESTRICTED;
+               $delUser = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
+               $delAction = LogPage::DELETED_ACTION | RevisionRecord::DELETED_RESTRICTED;
                if ( $op === '&' ) {
                        $delUser = $dbw->bitNot( $delUser );
                        $delAction = $dbw->bitNot( $delAction );
index 7b2147a..3ab96cb 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup RevisionDelete
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * General controller for RevDel, used by both SpecialRevisiondelete and
  * ApiRevisionDelete.
@@ -129,14 +131,14 @@ class RevisionDeleter {
                $ret = [ 0 => [], 1 => [], 2 => [] ];
                // Build bitfield changes in language
                self::checkItem( 'revdelete-content',
-                       Revision::DELETED_TEXT, $diff, $n, $ret );
+                       RevisionRecord::DELETED_TEXT, $diff, $n, $ret );
                self::checkItem( 'revdelete-summary',
-                       Revision::DELETED_COMMENT, $diff, $n, $ret );
+                       RevisionRecord::DELETED_COMMENT, $diff, $n, $ret );
                self::checkItem( 'revdelete-uname',
-                       Revision::DELETED_USER, $diff, $n, $ret );
+                       RevisionRecord::DELETED_USER, $diff, $n, $ret );
                // Restriction application to sysops
-               if ( $diff & Revision::DELETED_RESTRICTED ) {
-                       if ( $n & Revision::DELETED_RESTRICTED ) {
+               if ( $diff & RevisionRecord::DELETED_RESTRICTED ) {
+                       if ( $n & RevisionRecord::DELETED_RESTRICTED ) {
                                $ret[2][] = 'revdelete-restricted';
                        } else {
                                $ret[2][] = 'revdelete-unrestricted';
index faf8d82..bf90c06 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Item class for a live revision table row
  */
@@ -53,15 +55,19 @@ class RevisionItem extends RevisionItemBase {
        }
 
        public function canView() {
-               return $this->revision->userCan( Revision::DELETED_RESTRICTED, $this->context->getUser() );
+               return $this->revision->userCan(
+                       RevisionRecord::DELETED_RESTRICTED, $this->context->getUser()
+               );
        }
 
        public function canViewContent() {
-               return $this->revision->userCan( Revision::DELETED_TEXT, $this->context->getUser() );
+               return $this->revision->userCan(
+                       RevisionRecord::DELETED_TEXT, $this->context->getUser()
+               );
        }
 
        public function isDeleted() {
-               return $this->revision->isDeleted( Revision::DELETED_TEXT );
+               return $this->revision->isDeleted( RevisionRecord::DELETED_TEXT );
        }
 
        /**
index 29bd463..ce3fc26 100644 (file)
@@ -13,7 +13,7 @@ class AugmentPageProps implements ResultSetAugmentor {
                $this->propnames = $propnames;
        }
 
-       public function augmentAll( SearchResultSet $resultSet ) {
+       public function augmentAll( ISearchResultSet $resultSet ) {
                $titles = $resultSet->extractTitles();
                return PageProps::getInstance()->getProperties( $titles, $this->propnames );
        }
diff --git a/includes/search/ISearchResultSet.php b/includes/search/ISearchResultSet.php
new file mode 100644 (file)
index 0000000..1b30f5a
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+
+/**
+ * @ingroup Search
+ */
+interface ISearchResultSet extends \Countable, \IteratorAggregate {
+       /**
+        * Identifier for interwiki results that are displayed only together with existing main wiki
+        * results.
+        */
+       const SECONDARY_RESULTS = 0;
+
+       /**
+        * Identifier for interwiki results that can be displayed even if no existing main wiki results
+        * exist.
+        */
+       const INLINE_RESULTS = 1;
+
+       /**
+        * @return int
+        */
+       function numRows();
+
+       /**
+        * Some search modes return a total hit count for the query
+        * in the entire article database. This may include pages
+        * in namespaces that would not be matched on the given
+        * settings.
+        *
+        * Return null if no total hits number is supported.
+        *
+        * @return int|null
+        */
+       function getTotalHits();
+
+       /**
+        * Some search modes will run an alternative query that it thinks gives
+        * a better result than the provided search. Returns true if this has
+        * occurred.
+        *
+        * @return bool
+        */
+       function hasRewrittenQuery();
+
+       /**
+        * @return string|null The search the query was internally rewritten to,
+        *  or null when the result of the original query was returned.
+        */
+       function getQueryAfterRewrite();
+
+       /**
+        * @return string|null Same as self::getQueryAfterRewrite(), but in HTML
+        *  and with changes highlighted. Null when the query was not rewritten.
+        */
+       function getQueryAfterRewriteSnippet();
+
+       /**
+        * Some search modes return a suggested alternate term if there are
+        * no exact hits. Returns true if there is one on this set.
+        *
+        * @return bool
+        */
+       function hasSuggestion();
+
+       /**
+        * @return string|null Suggested query, null if none
+        */
+       function getSuggestionQuery();
+
+       /**
+        * @return string HTML highlighted suggested query, '' if none
+        */
+       function getSuggestionSnippet();
+
+       /**
+        * Return a result set of hits on other (multiple) wikis associated with this one
+        *
+        * @param int $type
+        * @return ISearchResultSet[]
+        */
+       function getInterwikiResults( $type = self::SECONDARY_RESULTS );
+
+       /**
+        * Check if there are results on other wikis
+        *
+        * @param int $type
+        * @return bool
+        */
+       function hasInterwikiResults( $type = self::SECONDARY_RESULTS );
+
+       /**
+        * Did the search contain search syntax?  If so, Special:Search won't offer
+        * the user a link to a create a page named by the search string because the
+        * name would contain the search syntax.
+        * @return bool
+        */
+       public function searchContainedSyntax();
+
+       /**
+        * @return bool True when there are more pages of search results available.
+        */
+       public function hasMoreResults();
+
+       /**
+        * @param int $limit Shrink result set to $limit and flag
+        *  if more results are available.
+        */
+       public function shrink( $limit );
+
+       /**
+        * Extract all the results in the result set as array.
+        * @return SearchResult[]
+        */
+       public function extractResults();
+
+       /**
+        * Extract all the titles in the result set.
+        * @return Title[]
+        */
+       public function extractTitles();
+
+       /**
+        * Sets augmented data for result set.
+        * @param string $name Extra data item name
+        * @param array[] $data Extra data as PAGEID => data
+        */
+       public function setAugmentedData( $name, $data );
+
+       /**
+        * Returns extra data for specific result and store it in SearchResult object.
+        * @param SearchResult $result
+        */
+       public function augmentResult( SearchResult $result );
+
+       /**
+        * @return int|null The offset the current page starts at. Typically
+        *  this should be null to allow the UI to decide on its own, but in
+        *  special cases like interleaved AB tests specifying explicitly is
+        *  necessary.
+        */
+       public function getOffset();
+}
index 97ef2d5..f132e13 100644 (file)
@@ -2,7 +2,7 @@
 
 /**
  * Marker class for search engines that can handle their own pagination, by
- * reporting in their SearchResultSet when a next page is available. This
+ * reporting in their ISearchResultSet when a next page is available. This
  * only applies to search{Title,Text} and not to completion search.
  *
  * SearchEngine implementations not implementing this interface will have
index a3979f7..6430a8a 100644 (file)
@@ -20,10 +20,10 @@ class PerRowAugmentor implements ResultSetAugmentor {
 
        /**
         * Produce data to augment search result set.
-        * @param SearchResultSet $resultSet
+        * @param ISearchResultSet $resultSet
         * @return array Data for all results
         */
-       public function augmentAll( SearchResultSet $resultSet ) {
+       public function augmentAll( ISearchResultSet $resultSet ) {
                $data = [];
                foreach ( $resultSet->extractResults() as $result ) {
                        $id = $result->getTitle()->getArticleID();
index e2d79a9..aabdde6 100644 (file)
@@ -6,8 +6,8 @@
 interface ResultSetAugmentor {
        /**
         * Produce data to augment search result set.
-        * @param SearchResultSet $resultSet
+        * @param ISearchResultSet $resultSet
         * @return array Data for all results
         */
-       public function augmentAll( SearchResultSet $resultSet );
+       public function augmentAll( ISearchResultSet $resultSet );
 }
index 8ea356f..0c5d4da 100644 (file)
@@ -51,7 +51,7 @@ abstract class SearchDatabase extends SearchEngine {
 
        /**
         * @param string $term
-        * @return SearchResultSet|Status|null
+        * @return ISearchResultSet|Status|null
         */
        final public function doSearchText( $term ) {
                return $this->doSearchTextInDB( $this->extractNamespacePrefix( $term ) );
@@ -67,7 +67,7 @@ abstract class SearchDatabase extends SearchEngine {
 
        /**
         * @param string $term
-        * @return SearchResultSet|null
+        * @return ISearchResultSet|null
         */
        final public function doSearchTitle( $term ) {
                return $this->doSearchTitleInDB( $this->extractNamespacePrefix( $term ) );
index 2fb4585..32b0f06 100644 (file)
@@ -79,7 +79,7 @@ abstract class SearchEngine {
         * be converted to final in 1.34. Override self::doSearchText().
         *
         * @param string $term Raw search term
-        * @return SearchResultSet|Status|null
+        * @return ISearchResultSet|Status|null
         */
        public function searchText( $term ) {
                return $this->maybePaginate( function () use ( $term ) {
@@ -91,7 +91,7 @@ abstract class SearchEngine {
         * Perform a full text search query and return a result set.
         *
         * @param string $term Raw search term
-        * @return SearchResultSet|Status|null
+        * @return ISearchResultSet|Status|null
         * @since 1.32
         */
        protected function doSearchText( $term ) {
@@ -136,7 +136,7 @@ abstract class SearchEngine {
         * be converted to final in 1.34. Override self::doSearchTitle().
         *
         * @param string $term Raw search term
-        * @return SearchResultSet|null
+        * @return ISearchResultSet|null
         */
        public function searchTitle( $term ) {
                return $this->maybePaginate( function () use ( $term ) {
@@ -148,7 +148,7 @@ abstract class SearchEngine {
         * Perform a title-only search query and return a result set.
         *
         * @param string $term Raw search term
-        * @return SearchResultSet|null
+        * @return ISearchResultSet|null
         * @since 1.32
         */
        protected function doSearchTitle( $term ) {
@@ -161,7 +161,7 @@ abstract class SearchEngine {
         * explicitly implement their own pagination.
         *
         * @param Closure $fn Takes no arguments
-        * @return SearchResultSet|Status<SearchResultSet>|null Result of calling $fn
+        * @return ISearchResultSet|Status<ISearchResultSet>|null Result of calling $fn
         */
        private function maybePaginate( Closure $fn ) {
                if ( $this instanceof PaginatingSearchEngine ) {
@@ -175,10 +175,10 @@ abstract class SearchEngine {
                }
 
                $resultSet = null;
-               if ( $resultSetOrStatus instanceof SearchResultSet ) {
+               if ( $resultSetOrStatus instanceof ISearchResultSet ) {
                        $resultSet = $resultSetOrStatus;
                } elseif ( $resultSetOrStatus instanceof Status &&
-                       $resultSetOrStatus->getValue() instanceof SearchResultSet
+                       $resultSetOrStatus->getValue() instanceof ISearchResultSet
                ) {
                        $resultSet = $resultSetOrStatus->getValue();
                }
@@ -784,9 +784,9 @@ abstract class SearchEngine {
        /**
         * Augment search results with extra data.
         *
-        * @param SearchResultSet $resultSet
+        * @param ISearchResultSet $resultSet
         */
-       public function augmentSearchResults( SearchResultSet $resultSet ) {
+       public function augmentSearchResults( ISearchResultSet $resultSet ) {
                $setAugmentors = [];
                $rowAugmentors = [];
                Hooks::run( "SearchResultsAugment", [ &$setAugmentors, &$rowAugmentors ] );
index 42bc62d..6d25aa4 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * A SearchResultSet wrapper for SearchNearMatcher
+ * A ISearchResultSet wrapper for SearchNearMatcher
  */
 class SearchNearMatchResultSet extends SearchResultSet {
        /**
index d400267..4715c75 100644 (file)
@@ -39,10 +39,10 @@ class SearchNearMatcher {
 
        /**
         * Do a near match (see SearchEngine::getNearMatch) and wrap it into a
-        * SearchResultSet.
+        * ISearchResultSet.
         *
         * @param string $searchterm
-        * @return SearchResultSet
+        * @return ISearchResultSet
         */
        public function getNearMatchResultSet( $searchterm ) {
                return new SearchNearMatchResultSet( $this->getNearMatch( $searchterm ) );
index 7703e38..a862e17 100644 (file)
@@ -66,10 +66,10 @@ class SearchResult {
         * Return a new SearchResult and initializes it with a title.
         *
         * @param Title $title
-        * @param SearchResultSet|null $parentSet
+        * @param ISearchResultSet|null $parentSet
         * @return SearchResult
         */
-       public static function newFromTitle( $title, SearchResultSet $parentSet = null ) {
+       public static function newFromTitle( $title, ISearchResultSet $parentSet = null ) {
                $result = new static();
                $result->initFromTitle( $title );
                if ( $parentSet ) {
index 5ee96cb..84f8bcf 100644 (file)
 /**
  * @ingroup Search
  */
-class SearchResultSet implements Countable, IteratorAggregate {
-
-       /**
-        * Identifier for interwiki results that are displayed only together with existing main wiki
-        * results.
-        */
-       const SECONDARY_RESULTS = 0;
-
-       /**
-        * Identifier for interwiki results that can be displayed even if no existing main wiki results
-        * exist.
-        */
-       const INLINE_RESULTS = 1;
+class SearchResultSet implements ISearchResultSet {
 
        protected $containedSyntax = false;
 
@@ -179,7 +167,7 @@ class SearchResultSet implements Countable, IteratorAggregate {
         * Return a result set of hits on other (multiple) wikis associated with this one
         *
         * @param int $type
-        * @return SearchResultSet[]
+        * @return ISearchResultSet[]
         */
        function getInterwikiResults( $type = self::SECONDARY_RESULTS ) {
                return null;
@@ -234,9 +222,9 @@ class SearchResultSet implements Countable, IteratorAggregate {
 
        /**
         * Frees the result set, if applicable.
+        * @deprecated noop since 1.34
         */
        function free() {
-               // ...
        }
 
        /**
index 87068ca..f5d795f 100644 (file)
@@ -66,14 +66,6 @@ class SqlSearchResultSet extends SearchResultSet {
                return $this->results;
        }
 
-       function free() {
-               if ( $this->resultSet === false ) {
-                       return;
-               }
-
-               $this->resultSet->free();
-       }
-
        function getTotalHits() {
                if ( !is_null( $this->totalHits ) ) {
                        return $this->totalHits;
index 7742075..4ba7868 100644 (file)
@@ -446,8 +446,9 @@ class Command {
                        // stream_select parameter names are from the POV of us being able to do the operation;
                        // proc_open desriptor types are from the POV of the process doing it.
                        // So $writePipes is passed as the $read parameter and $readPipes as $write.
-                       // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
-                       $numReadyPipes = @stream_select( $writePipes, $readPipes, $emptyArray, $timeout );
+                       AtEase::suppressWarnings();
+                       $numReadyPipes = stream_select( $writePipes, $readPipes, $emptyArray, $timeout );
+                       AtEase::restoreWarnings();
                        if ( $numReadyPipes === false ) {
                                $error = error_get_last();
                                if ( strncmp( $error['message'], $eintrMessage, strlen( $eintrMessage ) ) == 0 ) {
index c47d87b..cf9da49 100644 (file)
@@ -49,14 +49,15 @@ class FewestrevisionsPage extends QueryPage {
                                'namespace' => 'page_namespace',
                                'title' => 'page_title',
                                'value' => 'COUNT(*)',
-                               'redirect' => 'page_is_redirect'
                        ],
                        'conds' => [
                                'page_namespace' => MediaWikiServices::getInstance()->getNamespaceInfo()->
                                        getContentNamespaces(),
-                               'page_id = rev_page' ],
+                               'page_id = rev_page',
+                               'page_is_redirect = 0',
+                       ],
                        'options' => [
-                               'GROUP BY' => [ 'page_namespace', 'page_title', 'page_is_redirect' ]
+                               'GROUP BY' => [ 'page_namespace', 'page_title' ]
                        ]
                ];
        }
index 89eb410..5b77d5a 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Special page allowing users with the appropriate permissions to
  * merge article histories, with some restrictions
@@ -293,12 +295,12 @@ class SpecialMergeHistory extends SpecialPage {
                        [],
                        [ 'oldid' => $rev->getId() ]
                );
-               if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                        $pageLink = '<span class="history-deleted">' . $pageLink . '</span>';
                }
 
                # Last link
-               if ( !$rev->userCan( Revision::DELETED_TEXT, $user ) ) {
+               if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                        $last = $this->msg( 'last' )->escaped();
                } elseif ( isset( $this->prevId[$row->rev_id] ) ) {
                        $last = $linkRenderer->makeKnownLink(
index 682bceb..7444225 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup SpecialPage
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 /**
  * Special page allowing users with the appropriate permissions to view
  * and hide revisions. Log items can also be hidden.
@@ -197,12 +199,12 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        [ $this->typeLabels['check-label'], 'wpHidePrimary',
                                RevisionDeleter::getRevdelConstant( $this->typeName )
                        ],
-                       [ 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ],
-                       [ 'revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER ]
+                       [ 'revdelete-hide-comment', 'wpHideComment', RevisionRecord::DELETED_COMMENT ],
+                       [ 'revdelete-hide-user', 'wpHideUser', RevisionRecord::DELETED_USER ]
                ];
                if ( $user->isAllowed( 'suppressrevision' ) ) {
                        $this->checks[] = [ 'revdelete-hide-restricted',
-                               'wpHideRestricted', Revision::DELETED_RESTRICTED ];
+                               'wpHideRestricted', RevisionRecord::DELETED_RESTRICTED ];
                }
 
                # Either submit or create our form
@@ -530,7 +532,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                                        $bitfield & $field
                                );
 
-                               if ( $field == Revision::DELETED_RESTRICTED ) {
+                               if ( $field == RevisionRecord::DELETED_RESTRICTED ) {
                                        $innerHTML = "<b>$innerHTML</b>";
                                }
 
@@ -561,7 +563,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                                $line .= '<td class="mw-revdel-checkbox">' . Xml::radio( $name, 0, $selected == 0 ) . '</td>';
                                $line .= '<td class="mw-revdel-checkbox">' . Xml::radio( $name, 1, $selected == 1 ) . '</td>';
                                $label = $this->msg( $message )->escaped();
-                               if ( $field == Revision::DELETED_RESTRICTED ) {
+                               if ( $field == RevisionRecord::DELETED_RESTRICTED ) {
                                        $label = "<b>$label</b>";
                                }
                                $line .= "<td>$label</td>";
@@ -599,7 +601,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                                . $this->otherReason;
                }
                # Can the user set this field?
-               if ( $bitParams[Revision::DELETED_RESTRICTED] == 1
+               if ( $bitParams[RevisionRecord::DELETED_RESTRICTED] == 1
                        && !$this->getUser()->isAllowed( 'suppressrevision' )
                ) {
                        throw new PermissionsError( 'suppressrevision' );
@@ -662,8 +664,8 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        }
                        $bitfield[$field] = $val;
                }
-               if ( !isset( $bitfield[Revision::DELETED_RESTRICTED] ) ) {
-                       $bitfield[Revision::DELETED_RESTRICTED] = 0;
+               if ( !isset( $bitfield[RevisionRecord::DELETED_RESTRICTED] ) ) {
+                       $bitfield[RevisionRecord::DELETED_RESTRICTED] = 0;
                }
 
                return $bitfield;
index e1fbe6a..eacc7a0 100644 (file)
@@ -377,9 +377,9 @@ class SpecialSearch extends SpecialPage {
 
                $hasErrors = $textStatus && $textStatus->getErrors() !== [];
                $hasOtherResults = $textMatches &&
-                       $textMatches->hasInterwikiResults( SearchResultSet::INLINE_RESULTS );
+                       $textMatches->hasInterwikiResults( ISearchResultSet::INLINE_RESULTS );
 
-               if ( $textMatches && $textMatches->hasInterwikiResults( SearchResultSet::SECONDARY_RESULTS ) ) {
+               if ( $textMatches && $textMatches->hasInterwikiResults( ISearchResultSet::SECONDARY_RESULTS ) ) {
                        $out->addHTML( '<div class="searchresults mw-searchresults-has-iw">' );
                } else {
                        $out->addHTML( '<div class="searchresults">' );
@@ -443,14 +443,6 @@ class SpecialSearch extends SpecialPage {
                        $term, $this->offset, $titleMatches, $textMatches
                ) );
 
-               if ( $titleMatches ) {
-                       $titleMatches->free();
-               }
-
-               if ( $textMatches ) {
-                       $textMatches->free();
-               }
-
                $out->addHTML( '<div class="mw-search-visualclear"></div>' );
 
                // prev/next links
@@ -481,8 +473,8 @@ class SpecialSearch extends SpecialPage {
        /**
         * @param Title $title
         * @param int $num The number of search results found
-        * @param null|SearchResultSet $titleMatches Results from title search
-        * @param null|SearchResultSet $textMatches Results from text search
+        * @param null|ISearchResultSet $titleMatches Results from title search
+        * @param null|ISearchResultSet $textMatches Results from text search
         */
        protected function showCreateLink( $title, $num, $titleMatches, $textMatches ) {
                // show direct page/create link if applicable
index 31e4836..9a16a72 100644 (file)
@@ -387,11 +387,11 @@ class SpecialUndelete extends SpecialPage {
                        return;
                }
 
-               if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
-                       if ( !$rev->userCan( Revision::DELETED_TEXT, $user ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
+                       if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                                $out->wrapWikiMsg(
                                        "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
-                               $rev->isDeleted( Revision::DELETED_RESTRICTED ) ?
+                               $rev->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ?
                                        'rev-suppressed-text-permission' : 'rev-deleted-text-permission'
                                );
 
@@ -400,7 +400,7 @@ class SpecialUndelete extends SpecialPage {
 
                        $out->wrapWikiMsg(
                                "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
-                               $rev->isDeleted( Revision::DELETED_RESTRICTED ) ?
+                               $rev->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ?
                                        'rev-suppressed-text-view' : 'rev-deleted-text-view'
                        );
                        $out->addHTML( '<br />' );
@@ -932,7 +932,7 @@ class SpecialUndelete extends SpecialPage {
                if ( $this->mCanView ) {
                        $titleObj = $this->getPageTitle();
                        # Last link
-                       if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
+                       if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() ) ) {
                                $pageLink = htmlspecialchars( $this->getLanguage()->userTimeAndDate( $ts, $user ) );
                                $last = $this->msg( 'diff' )->escaped();
                        } elseif ( $remaining > 0 || ( $earliestLiveTime && $ts > $earliestLiveTime ) ) {
@@ -1055,7 +1055,7 @@ class SpecialUndelete extends SpecialPage {
                $user = $this->getUser();
                $time = $this->getLanguage()->userTimeAndDate( $ts, $user );
 
-               if ( !$rev->userCan( Revision::DELETED_TEXT, $user ) ) {
+               if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                        return '<span class="history-deleted">' . $time . '</span>';
                }
 
@@ -1069,7 +1069,7 @@ class SpecialUndelete extends SpecialPage {
                        ]
                );
 
-               if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                        $link = '<span class="history-deleted">' . $link . '</span>';
                }
 
index d82ba53..1cb78b8 100644 (file)
@@ -24,6 +24,7 @@
  * @ingroup Pager
  */
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\FakeResultWrapper;
 use Wikimedia\Rdbms\IDatabase;
@@ -347,10 +348,13 @@ class ContribsPager extends RangeChronologicalPager {
 
                // Paranoia: avoid brute force searches (T19342)
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $queryInfo['conds'][] = $this->mDb->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0';
+                       $queryInfo['conds'][] = $this->mDb->bitAnd(
+                               'rev_deleted', RevisionRecord::DELETED_USER
+                               ) . ' = 0';
                } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                       $queryInfo['conds'][] = $this->mDb->bitAnd( 'rev_deleted', Revision::SUPPRESSED_USER ) .
-                               ' != ' . Revision::SUPPRESSED_USER;
+                       $queryInfo['conds'][] = $this->mDb->bitAnd(
+                               'rev_deleted', RevisionRecord::SUPPRESSED_USER
+                               ) . ' != ' . RevisionRecord::SUPPRESSED_USER;
                }
 
                // $this->getIndexField() must be in the result rows, as reallyDoQuery() tries to access it.
@@ -642,11 +646,12 @@ class ContribsPager extends RangeChronologicalPager {
                                        && $page->quickUserCan( 'edit', $user )
                                ) {
                                        $this->preventClickjacking();
-                                       $topmarktext .= ' ' . Linker::generateRollback( $rev, $this->getContext() );
+                                       $topmarktext .= ' ' . Linker::generateRollback( $rev, $this->getContext(),
+                                               [ 'noBrackets' ] );
                                }
                        }
                        # Is there a visible previous revision?
-                       if ( $rev->userCan( Revision::DELETED_TEXT, $user ) && $rev->getParentId() !== 0 ) {
+                       if ( $rev->userCan( RevisionRecord::DELETED_TEXT, $user ) && $rev->getParentId() !== 0 ) {
                                $difftext = $linkRenderer->makeKnownLink(
                                        $page,
                                        new HtmlArmor( $this->messages['diff'] ),
@@ -696,7 +701,7 @@ class ContribsPager extends RangeChronologicalPager {
                        # Note that only unprivileged users have rows with hidden user names excluded.
                        # When querying for an IP range, we want to always show user and user talk links.
                        $userlink = '';
-                       if ( ( $this->contribs == 'newbie' && !$rev->isDeleted( Revision::DELETED_USER ) )
+                       if ( ( $this->contribs == 'newbie' && !$rev->isDeleted( RevisionRecord::DELETED_USER ) )
                                || $this->isQueryableRange( $this->target ) ) {
                                $userlink = ' <span class="mw-changeslist-separator"></span> '
                                        . $lang->getDirMark()
@@ -756,7 +761,7 @@ class ContribsPager extends RangeChronologicalPager {
                        ];
 
                        # Denote if username is redacted for this edit
-                       if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
+                       if ( $rev->isDeleted( RevisionRecord::DELETED_USER ) ) {
                                $templateParams['rev-deleted-user-contribs'] =
                                        $this->msg( 'rev-deleted-user-contribs' )->escaped();
                        }
index 11a8532..88e1ea8 100644 (file)
@@ -23,6 +23,7 @@
  * @ingroup Pager
  */
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\FakeResultWrapper;
@@ -88,10 +89,10 @@ class DeletedContribsPager extends IndexPager {
                $user = $this->getUser();
                // Paranoia: avoid brute force searches (T19792)
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $conds[] = $this->mDb->bitAnd( 'ar_deleted', Revision::DELETED_USER ) . ' = 0';
+                       $conds[] = $this->mDb->bitAnd( 'ar_deleted', RevisionRecord::DELETED_USER ) . ' = 0';
                } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                       $conds[] = $this->mDb->bitAnd( 'ar_deleted', Revision::SUPPRESSED_USER ) .
-                               ' != ' . Revision::SUPPRESSED_USER;
+                       $conds[] = $this->mDb->bitAnd( 'ar_deleted', RevisionRecord::SUPPRESSED_USER ) .
+                               ' != ' . RevisionRecord::SUPPRESSED_USER;
                }
 
                $commentQuery = CommentStore::getStore()->getJoin( 'ar_comment' );
@@ -337,7 +338,7 @@ class DeletedContribsPager extends IndexPager {
                $comment = Linker::revComment( $rev );
                $date = $this->getLanguage()->userTimeAndDate( $rev->getTimestamp(), $user );
 
-               if ( !$user->isAllowed( 'undelete' ) || !$rev->userCan( Revision::DELETED_TEXT, $user ) ) {
+               if ( !$user->isAllowed( 'undelete' ) || !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
                        $link = htmlspecialchars( $date ); // unusable link
                } else {
                        $link = $linkRenderer->makeKnownLink(
@@ -351,7 +352,7 @@ class DeletedContribsPager extends IndexPager {
                        );
                }
                // Style deleted items
-               if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
                        $link = '<span class="history-deleted">' . $link . '</span>';
                }
 
@@ -384,7 +385,7 @@ class DeletedContribsPager extends IndexPager {
                $ret = "{$del}{$link} {$tools} {$separator} {$mflag} {$pagelink} {$comment}";
 
                # Denote if username is redacted for this edit
-               if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
+               if ( $rev->isDeleted( RevisionRecord::DELETED_USER ) ) {
                        $ret .= " <strong>" . $this->msg( 'rev-deleted-user-contribs' )->escaped() . "</strong>";
                }
 
index f6ad623..df5ea70 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use MediaWiki\Linker\LinkTarget;
+use MediaWiki\Storage\RevisionRecord;
 use MediaWiki\User\UserIdentity;
 use Wikimedia\Assert\Assert;
 use Wikimedia\Rdbms\IDatabase;
@@ -566,9 +567,9 @@ class WatchedItemQueryService {
                // Avoid brute force searches (T19342)
                $bitmask = 0;
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $bitmask = Revision::DELETED_USER;
+                       $bitmask = RevisionRecord::DELETED_USER;
                } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                       $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+                       $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
                }
                if ( $bitmask ) {
                        $conds[] = $db->bitAnd( 'rc_deleted', $bitmask ) . " != $bitmask";
index 0e10287..698d223 100644 (file)
@@ -2,9 +2,9 @@
 
 namespace MediaWiki\Widget\Search;
 
+use ISearchResultSet;
 use MediaWiki\MediaWikiServices;
 use Message;
-use SearchResultSet;
 use SpecialSearch;
 use Status;
 
@@ -33,23 +33,23 @@ class BasicSearchResultSetWidget {
        /**
         * @param string $term The search term to highlight
         * @param int $offset The offset of the first result in the result set
-        * @param SearchResultSet|null $titleResultSet Results of searching only page titles
-        * @param SearchResultSet|null $textResultSet Results of general full text search.
+        * @param ISearchResultSet|null $titleResultSet Results of searching only page titles
+        * @param ISearchResultSet|null $textResultSet Results of general full text search.
         * @return string HTML
         */
        public function render(
                $term,
                $offset,
-               SearchResultSet $titleResultSet = null,
-               SearchResultSet $textResultSet = null
+               ISearchResultSet $titleResultSet = null,
+               ISearchResultSet $textResultSet = null
        ) {
                $hasTitle = $titleResultSet ? $titleResultSet->numRows() > 0 : false;
                $hasText = $textResultSet ? $textResultSet->numRows() > 0 : false;
                $hasSecondary = $textResultSet
-                       ? $textResultSet->hasInterwikiResults( SearchResultSet::SECONDARY_RESULTS )
+                       ? $textResultSet->hasInterwikiResults( ISearchResultSet::SECONDARY_RESULTS )
                        : false;
                $hasSecondaryInline = $textResultSet
-                       ? $textResultSet->hasInterwikiResults( SearchResultSet::INLINE_RESULTS )
+                       ? $textResultSet->hasInterwikiResults( ISearchResultSet::INLINE_RESULTS )
                        : false;
 
                if ( !$hasTitle && !$hasText && !$hasSecondary && !$hasSecondaryInline ) {
@@ -71,7 +71,7 @@ class BasicSearchResultSetWidget {
                }
 
                if ( $hasSecondaryInline ) {
-                       $iwResults = $textResultSet->getInterwikiResults( SearchResultSet::INLINE_RESULTS );
+                       $iwResults = $textResultSet->getInterwikiResults( ISearchResultSet::INLINE_RESULTS );
                        foreach ( $iwResults as $interwiki => $results ) {
                                if ( $results instanceof Status || $results->numRows() === 0 ) {
                                        // ignore bad interwikis for now
@@ -88,7 +88,7 @@ class BasicSearchResultSetWidget {
                if ( $hasSecondary ) {
                        $out .= $this->sidebarWidget->render(
                                $term,
-                               $textResultSet->getInterwikiResults( SearchResultSet::SECONDARY_RESULTS )
+                               $textResultSet->getInterwikiResults( ISearchResultSet::SECONDARY_RESULTS )
                        );
                }
 
@@ -112,11 +112,11 @@ class BasicSearchResultSetWidget {
        }
 
        /**
-        * @param SearchResultSet $resultSet The search results to render
+        * @param ISearchResultSet $resultSet The search results to render
         * @param int $offset Offset of the first result in $resultSet
         * @return string HTML
         */
-       protected function renderResultSet( SearchResultSet $resultSet, $offset ) {
+       protected function renderResultSet( ISearchResultSet $resultSet, $offset ) {
                $hits = [];
                foreach ( $resultSet as $result ) {
                        $hits[] = $this->resultWidget->render( $result, $offset++ );
index 135b01d..a8f57e2 100644 (file)
@@ -3,7 +3,7 @@
 namespace MediaWiki\Widget\Search;
 
 use HtmlArmor;
-use SearchResultSet;
+use ISearchResultSet;
 use SpecialSearch;
 
 /**
@@ -20,10 +20,10 @@ class DidYouMeanWidget {
 
        /**
         * @param string $term The user provided search term
-        * @param SearchResultSet $resultSet
+        * @param ISearchResultSet $resultSet
         * @return string HTML
         */
-       public function render( $term, SearchResultSet $resultSet ) {
+       public function render( $term, ISearchResultSet $resultSet ) {
                if ( $resultSet->hasRewrittenQuery() ) {
                        $html = $this->rewrittenHtml( $term, $resultSet );
                } elseif ( $resultSet->hasSuggestion() ) {
@@ -40,11 +40,11 @@ class DidYouMeanWidget {
         * rewritten, and the results of the rewritten query are being returned.
         *
         * @param string $term The users search input
-        * @param SearchResultSet $resultSet The response to the search request
+        * @param ISearchResultSet $resultSet The response to the search request
         * @return string HTML Links the user to their original $term query, and the
         *  one suggested by $resultSet
         */
-       protected function rewrittenHtml( $term, SearchResultSet $resultSet ) {
+       protected function rewrittenHtml( $term, ISearchResultSet $resultSet ) {
                $params = [
                        'search' => $resultSet->getQueryAfterRewrite(),
                        // Don't magic this link into a 'go' link, it should always
@@ -81,10 +81,10 @@ class DidYouMeanWidget {
         * a query that might give more/better results than their current
         * query.
         *
-        * @param SearchResultSet $resultSet
+        * @param ISearchResultSet $resultSet
         * @return string HTML
         */
-       protected function suggestionHtml( SearchResultSet $resultSet ) {
+       protected function suggestionHtml( ISearchResultSet $resultSet ) {
                $params = [
                        'search' => $resultSet->getSuggestionQuery(),
                        'fulltext' => 1,
index 48c624c..c495aa5 100644 (file)
@@ -4,14 +4,14 @@ namespace MediaWiki\Widget\Search;
 
 use MediaWiki\Interwiki\InterwikiLookup;
 use MediaWiki\Linker\LinkRenderer;
-use SearchResultSet;
+use ISearchResultSet;
 use SpecialSearch;
 use Title;
 use Html;
 use OOUI;
 
 /**
- * Renders one or more SearchResultSets into a sidebar grouped by
+ * Renders one or more ISearchResultSets into a sidebar grouped by
  * interwiki prefix. Includes a per-wiki header indicating where
  * the results are from.
  */
@@ -48,7 +48,7 @@ class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
 
        /**
         * @param string $term User provided search term
-        * @param SearchResultSet|SearchResultSet[] $resultSets List of interwiki
+        * @param ISearchResultSet|ISearchResultSet[] $resultSets List of interwiki
         *  results to render.
         * @return string HTML
         */
@@ -82,7 +82,7 @@ class InterwikiSearchResultSetWidget implements SearchResultSetWidget {
                        $iwResultItemOutput = '';
 
                        foreach ( $results as $result ) {
-                               $iwResultItemOutput .= $this->resultWidget->render( $result, $term, $position++ );
+                               $iwResultItemOutput .= $this->resultWidget->render( $result, $position++ );
                        }
 
                        $footerHtml = $this->footerHtml( $term, $iwPrefix );
index 6df6e65..ee9142e 100644 (file)
@@ -2,7 +2,7 @@
 
 namespace MediaWiki\Widget\Search;
 
-use SearchResultSet;
+use ISearchResultSet;
 
 /**
  * Renders a set of search results to HTML
@@ -10,7 +10,7 @@ use SearchResultSet;
 interface SearchResultSetWidget {
        /**
         * @param string $term User provided search term
-        * @param SearchResultSet|SearchResultSet[] $resultSets List of interwiki
+        * @param ISearchResultSet|ISearchResultSet[] $resultSets List of interwiki
         *  results to render.
         * @return string HTML
         */
index 248099a..12bc4b2 100644 (file)
@@ -4,13 +4,13 @@ namespace MediaWiki\Widget\Search;
 
 use MediaWiki\Interwiki\InterwikiLookup;
 use MediaWiki\Linker\LinkRenderer;
-use SearchResultSet;
+use ISearchResultSet;
 use SpecialSearch;
 use Title;
 use Html;
 
 /**
- * Renders one or more SearchResultSets into a sidebar grouped by
+ * Renders one or more ISearchResultSets into a sidebar grouped by
  * interwiki prefix. Includes a per-wiki header indicating where
  * the results are from.
  *
@@ -43,7 +43,7 @@ class SimpleSearchResultSetWidget implements SearchResultSetWidget {
 
        /**
         * @param string $term User provided search term
-        * @param SearchResultSet|SearchResultSet[] $resultSets List of interwiki
+        * @param ISearchResultSet|ISearchResultSet[] $resultSets List of interwiki
         *  results to render.
         * @return string HTML
         */
index 9fc7d73..61a967d 100644 (file)
@@ -21,6 +21,7 @@
 use MediaWiki\MediaWikiServices;
 
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\Storage\RevisionRecord;
 
 /**
  * Base class for language conversion.
@@ -1043,7 +1044,7 @@ class LanguageConverter {
                                $revision = Revision::newFromTitle( $title );
                                if ( $revision ) {
                                        if ( $revision->getContentModel() == CONTENT_MODEL_WIKITEXT ) {
-                                               $txt = $revision->getContent( Revision::RAW )->getText();
+                                               $txt = $revision->getContent( RevisionRecord::RAW )->getText();
                                        }
 
                                        // @todo in the future, use a specialized content model, perhaps based on json!
index 49ee88a..03790fa 100644 (file)
 /**
  * Turkish (Türkçe)
  *
- * Turkish has two different i, one with a dot and another without a dot. They
- * are totally different letters in this language, so we have to override the
+ * The Turkish language, like other Turkic languages, distinguishes
+ * a dotted letter 'i' from a dotless letter 'ı' (U+0131 LATIN SMALL LETTER DOTLESS I).
+ * In these languages, each has an equivalent uppercase mapping:
+ * ı (U+0131 LATIN SMALL LETTER DOTLESS I) -> I (U+0049 LATIN CAPITAL LETTER I),
+ * i (U+0069 LATIN SMALL LETTER I) -> İ (U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE).
+ *
+ * Unicode CaseFolding.txt defines this case as type 'T', a special case for Turkic languages:
+ * tr and az. PHP 7.3 parser ignores this special cases. so we have to override the
  * ucfirst and lcfirst methods.
+ *
  * See https://en.wikipedia.org/wiki/Dotted_and_dotless_I and T30040
  * @ingroup Language
  */
 class LanguageTr extends Language {
 
+       private $uc = [ 'I', 'İ' ];
+       private $lc = [ 'ı', 'i' ];
+
        /**
         * @param string $string
         * @return string
         */
        public function ucfirst( $string ) {
-               if ( strlen( $string ) && $string[0] == 'i' ) {
-                       return 'İ' . substr( $string, 1 );
+               $first = mb_substr( $string, 0, 1 );
+               if ( in_array( $first, $this->lc ) ) {
+                       $first = str_replace( $this->lc, $this->uc, $first );
+                       return $first . mb_substr( $string, 1 );
                }
                return parent::ucfirst( $string );
        }
@@ -48,8 +60,10 @@ class LanguageTr extends Language {
         * @return mixed|string
         */
        function lcfirst( $string ) {
-               if ( strlen( $string ) && $string[0] == 'I' ) {
-                       return 'ı' . substr( $string, 1 );
+               $first = mb_substr( $string, 0, 1 );
+               if ( in_array( $first, $this->uc ) ) {
+                       $first = str_replace( $this->uc, $this->lc, $first );
+                       return $first . mb_substr( $string, 1 );
                }
                return parent::lcfirst( $string );
        }
index 99dbc27..1b5aa79 100644 (file)
        "right-editmyusercss": "تعديل ملفات CSS للمستخدم نفسه",
        "right-editmyuserjson": "تعديل ملفات جسون للمستخدم نفسه",
        "right-editmyuserjs": "تعديل ملفات جافاسكربت للمستخدم نفسه",
+       "right-editmyuserjsredirect": "تحرير ملفات جافا سكريبت المحولة الخاصة بالمستخدم",
        "right-viewmywatchlist": "عرض قائمة مراقبتك",
        "right-editmywatchlist": "حرر قائمة مراقبتك. لاحظ أن بعض الإجراءات لا تزال تضيف الصفحات حتى بدون هذا الحق.",
        "right-viewmyprivateinfo": "استعراض بياناتك الشخصية (مثل البريد الإلكتروني والاسم الحقيقي)",
        "action-editmyusercss": "تحرير ملفات CSS المستخدم الخاصة بك",
        "action-editmyuserjson": "تحرير ملفات جسون المستخدم الخاصة بك",
        "action-editmyuserjs": "تحرير ملفات جافا سكريبت المستخدم الخاصة بك",
+       "action-editmyuserjsredirect": "تحرير ملفات جافا سكريبت المحولة الخاصة بالمستخدم",
        "action-viewsuppressed": "عرض المراجعات المخفية بواسطة أي مستخدم",
        "action-hideuser": "منع اسم مستخدم، مخفيا إياه عن العامة",
        "action-ipblock-exempt": "تفادي عمليات منع الأيبي والمنع التلقائي ومنع النطاق",
        "specialmute-success": "تم تحديث تفضيلات كتم الصوت بنجاح، شاهد كل المستخدمين الصامتين في [[Special:Preferences|تفضيلاتك]].",
        "specialmute-submit": "تأكيد",
        "specialmute-label-mute-email": "كتم رسائل البريد الإلكتروني من هذا المستخدم",
-       "specialmute-header": "Ù\8aÙ\8fرجÙ\8eÙ\89 ØªØ­Ø¯Ù\8aد ØªÙ\81ضÙ\8aÙ\84ات Ù\83تÙ\85 Ø§Ù\84صÙ\88ت Ù\84Ù\80{{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Ù\8aÙ\8fرجÙ\8eÙ\89 ØªØ­Ø¯Ù\8aد ØªÙ\81ضÙ\8aÙ\84ات Ù\83تÙ\85 Ø§Ù\84صÙ\88ت Ù\84Ù\84Ù\85ستخدÙ\85 <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "لا يمكن العثور على اسم المستخدم المطلوب.",
-       "specialmute-error-email-blacklist-disabled": "لم يتم تمكين كتم المستخدمين من إرسال رسائل البريد الإلكتروني إليك.",
-       "specialmute-error-email-preferences": "يجب تأكيد عنوان بريدك الإلكتروني قبل أن تتمكن من كتم صوت المستخدم، يمكنك القيام بذلك من [[Special:Preferences]].",
-       "specialmute-email-footer": "لإدارة تفضيلات البريد الإلكتروني لـ{{BIDI:$2}}؛ تُرجَى زيارة <$1>",
+       "specialmute-error-no-options": "ميزات كتم الصوت غير متوفرة، قد يكون هذا بسبب: أنك لم تؤكد عنوان بريدك الإلكتروني أو قام إداري الويكي بتعطيل ميزات البريد الإلكتروني و/أو قائمة البريد الإلكتروني السوداء لهذه الويكي.",
+       "specialmute-email-footer": "لإدارة تفضيلات البريد الإلكتروني للمستخدم {{BIDI:$2}}؛ تُرجَى زيارة <$1>",
        "specialmute-login-required": "يُرجَى تسجيل الدخول لتغيير تفضيلات الصمت الخاصة بك.",
        "mute-preferences": "كتم صوت التفضيلات",
        "revid": "المراجعة $1",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "لا يمكن أن تكون كلمة المرور في قائمة كلمات المرور الـ100.000 الأكثر استخداما.",
        "passwordpolicies-policyflag-forcechange": "يجب أن تتغير عند تسجيل الدخول",
        "passwordpolicies-policyflag-suggestchangeonlogin": "اقتراح التغيير عند تسجيل الدخول",
+       "mycustomjsredirectprotected": "ليست لديك صلاحية لتعديل صفحة جافا سكريبت هذه لأنها تحويلة ولا تشير إلى نطاق المستخدمي الخاص بك.",
        "easydeflate-invaliddeflate": "المحتوى المقدم لا يتم تفريغه بشكل صحيح",
        "unprotected-js": "لأسباب تتعلق بالأمان; لا يمكن تحميل جافا سكريبت من الصفحات غير المحمية; الرجاء إنشاء جافا سكريبت فقط في نطاق ميدياويكي: أو كصفحة فرعية للمستخدم",
        "userlogout-continue": "هل تريد تسجيل الخروج؟"
index 21151e5..f8bbef5 100644 (file)
@@ -34,7 +34,8 @@
                        "Fitoschido",
                        "Toghrul Rahimli",
                        "Vlad5250",
-                       "Hüseynzadə"
+                       "Hüseynzadə",
+                       "Patriot Kur"
                ]
        },
        "tog-underline": "Keçidlərin altını xətlə:",
        "histfirst": "Ən əvvəlki",
        "histlast": "Ən sonuncu",
        "historysize": "({{PLURAL:$1|1 bayt|$1 bayt}})",
-       "historyempty": "(boş)",
+       "historyempty": "boş",
        "history-feed-title": "Redaktə tarixçəsi",
        "history-feed-description": "Vikidə bu səhifənin dəyişikliklər tarixçəsi",
        "history-feed-item-nocomment": "$1 $2-də",
        "recentchangesdays": "Son dəyişiklərdə göstərilən günlərin miqdarı:",
        "recentchangesdays-max": "Maksimum $1 {{PLURAL:$1|gün|gün}}",
        "recentchangescount": "Son dəyişikliklərdə başlıq sayı:",
-       "prefs-help-recentchangescount": "Buraya yeni dəyişikliklər, səhifələrin və jurnalların tarixçəsi daxildir.",
+       "prefs-help-recentchangescount": "Maksimum say: 1000",
        "savedprefs": "Seçiminiz qəbul edildi.",
        "timezonelegend": "Vaxt zonası:",
        "localtime": "Yerli vaxt:",
        "right-sendemail": "Digər istifadəçilərə elektron poçt göndər",
        "grant-group-email": "E-məktub göndər",
        "grant-editmywatchlist": "İzləmə siyahınızda redaktə",
+       "grant-basic": "Əsas hüquqlar",
+       "grant-viewdeleted": "Silinən fayllara və səhifələrə bax",
+       "grant-viewmywatchlist": "İzləmə siyahınıza baxın",
        "newuserlogpage": "Yeni istifadəçilərin qeydiyyatı",
        "newuserlogpagetext": "Yeni qeydiyyatdan keçmiş istifadəçilərin siyahısı.",
        "rightslog": "İstifadəçi hüquqları qeydləri",
        "action-userrights-interwiki": "Digər vikilərdəki istifadəçilərin istifadəçi hüquqlarını dəyişdir",
        "action-siteadmin": "Məlumatlar bazasının bloklanması və blokun götürülməsi",
        "action-sendemail": "e-məktub göndər",
+       "action-editmywatchlist": "İzləmə siyahınızda redaktə",
+       "action-viewmywatchlist": "İzləmə siyahınıza baxın",
+       "action-viewmyprivateinfo": "Şəxsi məlumatlarınıza baxın",
+       "action-editmyprivateinfo": "Şəxsi məlumatlarınızı redaktə edin",
        "action-purge": "bu səhifənin yaddaşını təmizlə",
        "nchanges": "$1 {{PLURAL:$1|dəyişiklik|dəyişiklik}}",
        "enhancedrc-history": "tarixçə",
        "rcfilters-savedqueries-add-new-title": "Hazırkı filtr nizamlamalarını yaddaşa ver",
        "rcfilters-restore-default-filters": "Standart filtrləri bərpa et",
        "rcfilters-clear-all-filters": "Bütün filtrləri sil",
-       "rcfilters-show-new-changes": "Ən son dəyişiklikləri göstər",
+       "rcfilters-show-new-changes": "Ən son dəyişiklikləri göstər: $1",
        "rcfilters-search-placeholder": "Son dəyişiklikləri filtrlə (siyahıdan seçin və ya daxil edin)",
        "rcfilters-empty-filter": "Aktiv filtr yoxdur. Bütün redaktələr göstərilir.",
        "rcfilters-filterlist-title": "Filtrlər",
index c54899f..a000ad4 100644 (file)
@@ -21,8 +21,8 @@
        },
        "tog-underline": ":لینکاں کِشک کن",
        "tog-hideminor": "ھوردݔں ٹگلاں پناہ کن",
-       "tog-hidepatrolled": "ته نوکین تغییرات اصلاحاتی که گردگ بیتگن پناه کن",
-       "tog-newpageshidepatrolled": "تاکاتے کہ گندگ بیتگ اَنت پناہ کن",
+       "tog-hidepatrolled": "نۏکݔں ٹگلاں مہ مہ گُڈی نۏکݔں ٹگلاں پݔش مہ دار",
+       "tog-newpageshidepatrolled": "تاکانے کہ گندگ بیتگ اَنت پناہ کن",
        "tog-hidecategorization": "تاکانء تراشوانء پناہ کنگ",
        "tog-extendwatchlist": "چارگ لیستءَ مزن کن کہ دراھیگݔں گندگ بہ بَنت",
        "tog-usenewrc": "گروپء تاک ءُ چارگ لیستء ٹگلاں",
@@ -43,7 +43,7 @@
        "tog-enotifminoredits": "هنچوش پر هوردین ٹگل مان پیج و فایلان پر منء ایمیل دیم بدئ",
        "tog-enotifrevealaddr": "منی ایمیل پیش دار ته ایمیل أن هوژاری",
        "tog-shownumberswatching": "پیش دار تعداد کاربرانی که چارگتن",
-       "tog-oldsig": "انیگین ایمزا کنوک",
+       "tog-oldsig": "ھنیگݔں نامپَد کنۏک",
        "tog-fancysig": "امضاءَ په داب ویکی متنی بزان(بی اتوماتیکی لینک)",
        "tog-uselivepreview": "پیش‌نمایش بدون نیاز به بروزرسانی صفحه",
        "tog-forceeditsummary": "من آ هال دی وهدی وارد کتن یک هالیکین خلاصه ی اصلاح",
        "mostcategories": "صفحات گون گیشترین دسته جات",
        "mostimages": "فایلان گیشنر لینک بوتیگن",
        "mostrevisions": "صفحاتی گون گیشترین بازبینی",
-       "prefixindex": "کل صفحات گون پیش وند",
+       "prefixindex": "پھکݔں تاکاں گۏں پݔشبند",
        "shortpages": "هوردین صفحه",
        "longpages": "صفحات مزنین",
        "deadendpages": "مرتگین صفحات",
        "alllogstext": "هور کت پیش دارگ کل موجودین آمار {{SITENAME}}.\nشما تونیت گون انتخاب یک نوع آمار،نام کاربر (حساس په هورد-مزنی)، یا متاثرین صفحه (هنچوش حساس په هورد-مزنی) کمتری کنیت.",
        "logempty": "هچ آیتم هم دپ ته آمار",
        "log-title-wildcard": "بگرد عناوین که گون ای متن شروع بنت",
-       "allpages": "کل صفحات",
+       "allpages": "پھکݔں تاکاں",
        "nextpage": "($1)ء اݔدگہ تاک",
        "prevpage": " ($1)پیشگین صفحه",
        "allpagesfrom": "پیش در صفحات شروع بنت ته:",
        "undelete-error-long": "حطایانی پیش آت وهدی که فایل حذف ترینگ بوت:\n\n$1",
        "undelete-show-file-confirm": "آیا مطمئن ایت که حذف بوتگین بازبینی فایل \"<nowiki>$1</nowiki>\" از $2 ته $3 را بچاریت؟",
        "undelete-show-file-submit": "بله",
-       "namespace": "Ù\81اصÙ\84Ù\87 Ù\86اÙ\85",
+       "namespace": "Ù\86اÙ\85Ø¡ Ø¬Ø¯Ø§Û\8cÛ\8c",
        "invert": "برگردینگ انتخاب",
        "blanknamespace": "(بُنیادی)",
        "contributions": "مشارکتان کاربر",
index 08ac863..03c57b5 100644 (file)
        "systemblockedtext": "Вашае імя ўдзельніка ці IP-адрас былі аўтаматычна заблякаваныя MediaWiki.\nЗ наступнай прычыны:\n\n:<em>$2</em>\n\n* Пачатак блякаваньня: $8\n* Сканчэньне блякаваньня: $6\n* Мэта блякаваньня: $7\n\nВаш цяперашні IP-адрас — $3.\nКалі ласка, уключайце ўсе пададзеныя вышэй дэталі ва ўсе запыты, што вы робіце.",
        "blockednoreason": "прычына не пазначана",
        "blockedtext-composite": "<strong>Вашае імя ўдзельніка ці IP-адрас былі заблякаваныя.</strong>\n\nПададзеная прычына:\n\n:<em>$2</em>.\n\n* Пачатак блякаваньня: $8\n* Сканчэньне найдаўжэйшага з блякаваньняў: $6\n\n* $5\n\nВаш цяперашні IP-адрас — $3.\nКалі ласка, дадайце ўсе падрабязнасьці, прыведзеныя вышэй, у запыты, што вы будзеце рабіць.",
+       "blockedtext-composite-ids": "Адпаведныя ідэнтыфікатары блякаваньня: $1 (ваш IP-адрас таксама можа знаходзіцца ў чорным сьпісе)",
        "blockedtext-composite-reason": "Маецца некалькі блякаваньняў вашага рахунку і/ці IP-адрасу",
        "whitelistedittext": "Вам трэба $1, каб рэдагаваць старонкі.",
        "confirmedittext": "Вы мусіце пацьвердзіць Ваш адрас электроннай пошты перад рэдагаваньнем старонак. Калі ласка, пазначце і пацьвердзіце адрас электроннай пошты праз Вашы [[Special:Preferences|налады]].",
        "specialmute-success": "Вашыя налады заглушэньня былі абноўленыя. Глядзіце ўсіх заглушаных удзельнікаў на старонцы [[Special:Preferences|вашых наладаў]].",
        "specialmute-submit": "Пацьвердзіць",
        "specialmute-label-mute-email": "Заглушыць лісты электроннай пошты ад гэтага ўдзельніка",
-       "specialmute-header": "Калі ласка, абярыце вашыя налады заглушэньня для {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Калі ласка, абярыце вашыя налады заглушэньня для <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "Запытанае імя ўдзельніка ня можа быць знойдзенае.",
-       "specialmute-error-email-blacklist-disabled": "Заглушэньне ўдзельнікам магчымасьці дасылаць вам лісты электроннай поштай ня ўключанае.",
-       "specialmute-error-email-preferences": "Вы мусіце пацьвердзіць ваш адрас электроннай пошты перад тым, як зможаце заглушыць удзельніка. Вы можаце зрабіць гэта ў [[Special:Preferences|наладах]].",
        "specialmute-email-footer": "Для кіраваньня наладамі электроннай пошты для {{BIDI:$2}}, калі ласка, наведайце <$1>.",
        "specialmute-login-required": "Калі ласка, увайдзіце, каб зьмяніць вашыя налады заглушэньня.",
        "mute-preferences": "Налады заглушэньня",
index 832c1ca..4a525c7 100644 (file)
        "backend-fail-maxsize": "Файлът „$1“ не може да бъде съхранен, тъй като размерът му надвишава {{PLURAL:$2|един байт|$2 байт}}.",
        "backend-fail-connect": "Не е възможно свързването към бекенда за съхранение „$1“.",
        "backend-fail-internal": "Възникна неизвестна грешка в бекенда за съхранение „$1“.",
+       "backend-fail-contenttype": "Не може да бъде определен типът на съдържанието на този файл, за да бъде съхранен в „$1“.",
        "zip-file-open-error": "Възникна грешка при отваряне на файла за проверка на ZIP.",
        "zip-wrong-format": "Указаният файл не е ZIP файл.",
        "zip-bad": "Файлът е повреден или е нечетим ZIP файл.\nСигурността му не може да бъде проверена.",
        "uploadstash-errclear": "Изчистването на файловете беше неуспешно.",
        "uploadstash-refresh": "Обновяване на списъка с файлове",
        "uploadstash-thumbnail": "преглед на миниатюра",
+       "uploadstash-bad-path": "Пътят не съществува.",
+       "uploadstash-bad-path-invalid": "Пътят не е валиден.",
        "uploadstash-bad-path-unknown-type": "Неизвестен тип „$1“.",
+       "uploadstash-bad-path-unrecognized-thumb-name": "Неразпознато име на миниатюрата.",
+       "uploadstash-bad-path-bad-format": "Ключът „$1“ не е в подходящ формат.",
+       "uploadstash-file-not-found-missing-content-type": "Липсващо заглавие за типа на съдържание.",
+       "uploadstash-file-not-found-not-exists": "Не може да бъде намерен пътят или файлът не е обикновен.",
        "uploadstash-wrong-owner": "Файлът ($1) не принадлежи на текущия потребител.",
        "uploadstash-no-such-key": "Няма такъв ключ ($1), не може да бъде премахнат.",
        "uploadstash-no-extension": "Разширението е нулево.",
        "blocklist-userblocks": "Скриване блокирането на потребителски сметки",
        "blocklist-tempblocks": "Скриване на временни блокирания",
        "blocklist-addressblocks": "Скриване на отделни блокирания на IP адреси",
+       "blocklist-type-opt-all": "Всички",
        "blocklist-type-opt-sitewide": "За всички уикита",
        "blocklist-type-opt-partial": "Частично",
        "blocklist-rangeblocks": "Скриване на блокиранията по IP диапазон",
        "blocklink": "блокиране",
        "unblocklink": "отблокиране",
        "change-blocklink": "промяна на параметрите на блокирането",
+       "empty-username": "(недостъпно потребителско име)",
        "contribslink": "приноси",
        "emaillink": "изпращане на е-писмо",
        "autoblocker": "Бяхте блокиран автоматично, тъй като неотдавна IP-адресът Ви е бил ползван от блокирания в момента потребител „[[User:$1|$1]]“.\nПричината за блокирането на „$1“ е: „$2“.",
        "limitreport-ppgeneratednodes-value": "$1/$2",
        "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|байт|байта}}",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|байт|байта}}",
+       "limitreport-expansiondepth": "Най-голяма дълбочина на разгръщане",
        "limitreport-expansiondepth-value": "$1/$2",
        "limitreport-expensivefunctioncount-value": "$1/$2",
        "expandtemplates": "Разгръщане на шаблони",
        "mediastatistics-header-video": "Видео",
        "mediastatistics-header-multimedia": "Мултимедия",
        "mediastatistics-header-office": "Офис",
+       "mediastatistics-header-text": "Текстови",
+       "mediastatistics-header-executable": "Изпълними",
+       "mediastatistics-header-archive": "Компресирани формати",
        "mediastatistics-header-total": "Всички файлове",
        "json-error-state-mismatch": "Невалиден или грешно структуриран JSON",
        "json-error-ctrl-char": "Грешка в контролния знак. Вероятно е неправилно кодиран",
        "mw-widgets-abandonedit-discard": "Отказване на редакциите",
        "mw-widgets-abandonedit-keep": "Продължаване на редактирането",
        "mw-widgets-abandonedit-title": "Сигурни ли сте?",
+       "mw-widgets-copytextlayout-copy": "Копиране",
+       "mw-widgets-copytextlayout-copy-fail": "Неуспех при копиране в системния буфер.",
+       "mw-widgets-copytextlayout-copy-success": "Копирано в системния буфер.",
        "mw-widgets-dateinput-no-date": "Не е избрана дата",
        "mw-widgets-dateinput-placeholder-day": "ГГГГ-ММ-ДД",
        "mw-widgets-dateinput-placeholder-month": "ГГГГ-ММ",
        "authmanager-provider-password": "Удостоверяване с парола",
        "authmanager-provider-temporarypassword": "Временна парола",
        "authprovider-confirmlink-option": "$1 ($2)",
+       "authprovider-confirmlink-success-line": "$1: Успешно свързано.",
        "authprovider-confirmlink-failed-line": "$1: $2",
+       "authprovider-confirmlink-failed": "Свързването на сметката не е напълно успешно: $1",
+       "authprovider-confirmlink-ok-help": "Продължаване след показване на съобщения за неуспешно свързване.",
        "authprovider-resetpass-skip-label": "Пропускане",
        "authform-newtoken": "Липсва маркер. $1",
        "authform-notoken": "Липсва маркер",
        "restrictionsfield-label": "Позволени IP-диапазони:",
        "edit-error-short": "Грешка: $1",
        "edit-error-long": "Грешки:\n\n$1",
+       "specialmute-submit": "Потвърждаване",
        "revid": "версия $1",
        "pageid": "ID на страницата $1",
        "interfaceadmin-info": "$1\n\nПравата за редактиране на CSS/JS/JSON в целия сайт наскоро бяха отделени от правата <code>editinterface</code>. Ако не разбирате защо получавате тази грешка, погледнете [[mw:MediaWiki_1.32/interface-admin]].",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Паролата не може да съвпада с пароли от черния списък",
        "passwordpolicies-policy-maximalpasswordlength": "Паролата трябва да бъде по-малко от $1 {{PLURAL:$1|знак|знака}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Паролата не може да бъде {{PLURAL:$1|най-популярната такава|от списъка на най-популярните $1 пароли}}",
-       "passwordpolicies-policyflag-forcechange": "трябва да бъде променена при влизане"
+       "passwordpolicies-policyflag-forcechange": "трябва да бъде променена при влизане",
+       "passwordpolicies-policyflag-suggestchangeonlogin": "предложи промяна при вход",
+       "userlogout-continue": "Искате да излезете?"
 }
index 461ad0a..c17299f 100644 (file)
        "edit-gone-missing": "No s'ha pogut actualitzar la pàgina.\nSembla haver estat esborrada.",
        "edit-conflict": "Conflicte d'edició.",
        "edit-no-change": "S'ha ignorat la vostra modificació perquè no feia cap canvi al text.",
+       "edit-slots-cannot-add": "{{PLURAL:$1|L'espai no està|Els espais no estan}} implementats aquí: $2.",
+       "edit-slots-cannot-remove": "{{PLURAL:$1|L'espai següent és necessari i no es pot suprimir|Els espais següents són necessaris i no es poden suprimir}}: $2.",
        "postedit-confirmation-created": "S'ha creat la pàgina.",
        "postedit-confirmation-restored": "S'ha restaurat la pàgina.",
        "postedit-confirmation-saved": "S'ha desat la modificació.",
        "defaultmessagetext": "Missatge per defecte",
        "content-failed-to-parse": "Ha fallat l'anàlisi del contingut de $2 per al model $1: $3",
        "invalid-content-data": "Dades de contingut no vàlides",
-       "content-not-allowed-here": "No és permès el contingut «$1» a la pàgina [[:$2]]",
+       "content-not-allowed-here": "No és permès el contingut «$1» a la pàgina [[:$2]] a l'espai «$3»",
        "editwarning-warning": "Si sortiu d'aquesta pàgina, perdreu tots els canvis que hàgiu fet.\nSi teniu un compte d'usuari, podeu eliminar aquest avís en la secció «{{int:prefs-editing}}» de les vostres preferències.",
        "editpage-invalidcontentmodel-title": "Model de contingut no permès",
        "editpage-invalidcontentmodel-text": "El model de contingut «$1» no és permès.",
        "converter-manual-rule-error": "Error detectat a la norma de conversió de llengua manual",
        "undo-success": "Pot desfer-se la modificació. Si us plau, reviseu la comparació de sota per a assegurar-vos que és el que voleu fer; llavors deseu els canvis per a finalitzar la desfeta de l'edició.",
        "undo-failure": "No pot desfer-se la modificació perquè hi ha edicions intermèdies en conflicte.",
+       "undo-main-slot-only": "No s'ha pogut desfer la modificació perquè implicava contingut de fora de l'espai principal.",
        "undo-norev": "No s'ha pogut desfer l'edició perquè no existeix o s'ha suprimit.",
        "undo-nochange": "Sembla que ja s'ha desfet la modificació.",
        "undo-summary": "Es desfà la revisió $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussió]])",
        "grant-delete": "Suprimeix pàgines, revisions i entrades de registre",
        "grant-editinterface": "Modifica l'espai de noms MediaWiki i el JSON global del lloc o de l'usuari",
        "grant-editmycssjs": "Modifiqueu el vostre CSS/JSON/JavaScript d'usuari",
-       "grant-editmyoptions": "Editeu les vostres preferències d'usuari",
+       "grant-editmyoptions": "Editeu les vostres preferències d'usuari i la configuració JSON",
        "grant-editmywatchlist": "Modifica la llista de seguiment",
        "grant-editpage": "Modifica les pàgines existents",
        "grant-editprotected": "Modifica pàgines protegides",
        "lockmanager-fail-closelock": "No s'ha pogut blocar el fitxer per «$1».",
        "lockmanager-fail-deletelock": "No s'ha pogut suprimir el fitxer de blocatge per «$1».",
        "lockmanager-fail-acquirelock": "No s'ha pogut adquirir el blocatge de «$1».",
-       "lockmanager-fail-openlock": "No s'ha pogut obrir el fitxer de blocatge de «$1».",
+       "lockmanager-fail-openlock": "No s'ha pogut obrir el fitxer de blocatge de «$1». Assegureu-vos que el directori de càrrega està configurat correctament i que el servidor web té permisos per escriure-hi. Vegeu https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory per a més informació.",
        "lockmanager-fail-releaselock": "No s'ha pogut alliberar el blocatge de «$1».",
        "lockmanager-fail-db-bucket": "No s'han pogut contactar un nombre suficient de bases de blocatge en el cubell $1.",
        "lockmanager-fail-db-release": "No s'han pogut alliberar els blocatges a la base de dades $1.",
        "cachedspecial-refresh-now": "Mostra la darrera.",
        "categories": "Categories",
        "categories-submit": "Mostra",
-       "categoriespagetext": "{{PLURAL:$1|La següent categoria conté|Les següents categories contenen}} pàgines, o fitxers multimèdia.\n[[Special:UnusedCategories|Les categories no usades]] no s'hi mostren.\nVegeu també [[Special:WantedCategories|les categories sol·licitades]].",
+       "categoriespagetext": "{{PLURAL:$1|La següent categoria existeix|Les següents categories existeixen}} en aquest wiki, tant en ús com no.\nVegeu també [[Special:WantedCategories|les categories sol·licitades]].",
        "categoriesfrom": "Mostra les categories que comencen a:",
        "deletedcontributions": "Contribucions suprimides",
        "deletedcontributions-title": "Contribucions suprimides",
        "revertpage-nouser": "Edicions revertides per un usuari ocult a l'última revisió de {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Revertides les edicions de {{GENDER:$3|$1}}; recuperant la darrera versió de {{GENDER:$4|$2}}.",
        "sessionfailure-title": "Error de sessió",
-       "sessionfailure": "S'ha produït un error amb la vostra sessió. S'ha anul·lat aquesta acció en prevenció de pirateig de sessió. Premeu «Torna», recarregueu la pàgina des d'on veniu i torneu-ho a intentar.",
+       "sessionfailure": "S'ha produït un problema amb la vostra sessió d'inici. S'ha cancel·lat aquesta acció en prevenció de pirateig de sessió. Torneu a trametre el formulari.",
        "changecontentmodel": "Canvia el model de contingut d'una pàgina",
        "changecontentmodel-legend": "Canvia el model de contingut",
        "changecontentmodel-title-label": "Títol de la pàgina",
        "blocklist-editing-page": "pàgines",
        "blocklist-editing-ns": "espais de noms",
        "ipblocklist-empty": "La llista de blocatges està buida.",
-       "ipblocklist-no-results": "L'adreça IP o nom d'usuari sol·licitat no està blocat.",
+       "ipblocklist-no-results": "No s'han trobat blocs que coincideixin amb l'adreça o nom d'usuari sol·licitat.",
        "blocklink": "bloca",
        "unblocklink": "desbloca",
        "change-blocklink": "canvia el blocatge",
        "logentry-rights-autopromote": "$1 ha estat {{GENDER:$2|promogut}} automàticament de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|ha carregat}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|ha carregat}} una nova versió de $3",
-       "logentry-upload-revert": "$1 {{GENDER:$2|ha carregat}} $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|ha revertit}} $3 a una versió antiga",
        "log-name-managetags": "Registre de gestió d'etiquetes",
        "log-description-managetags": "Aquesta pàgina té llistades les tasques de gestió referents a les [[Special:Tags|etiquetes]]. El registre conté només les accions dutes a terme manualment per un administrador; algunes etiquetes poden ser creades o eliminades pel programari wiki sense deixar inventariada una entrada en aquest registre.",
        "logentry-managetags-create": "$1 {{GENDER:$2|va crear}} l'etiqueta «$4»",
        "limitreport-expensivefunctioncount": "Nombre de funcions d'anàlisi dispendioses",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Expansió de plantilles",
-       "expand_templates_intro": "Aquesta pàgina especial expandeix de forma recursiva totes les plantilles d'un text donat.\nTambé expandeix les funcions sintàctiques, com ara <code><nowiki>{{</nowiki>#language:…}}</code>, i les variables predefinides, com <code><nowiki>{{</nowiki>CURRENTDAY}}</code> &mdash;de fet, gairebé tot que estigui entre claus dobles.",
+       "expand_templates_intro": "Aquesta pàgina especial expandeix de forma recursiva totes les plantilles d'un wikitext donat.\nTambé expandeix les funcions sintàctiques, com ara <code><nowiki>{{</nowiki>#language:…}}</code>, i les variables predefinides, com <code><nowiki>{{</nowiki>CURRENTDAY}}</code> &mdash;de fet, gairebé tot que estigui entre claus dobles.",
        "expand_templates_title": "Títol per contextualitzar ({{FULLPAGENAME}}, etc):",
        "expand_templates_input": "Wikitext d'entrada:",
        "expand_templates_output": "Resultat:",
        "specialmute-submit": "Confirma",
        "specialmute-label-mute-email": "Silencia el correu electrònic d'aquest usuari",
        "specialmute-error-invalid-user": "No s’ha trobat el nom d’usuari que heu indicat.",
-       "specialmute-error-email-preferences": "Heu de confirmar l'adreça electrònica abans de poder silenciar un usuari. Podeu fer-ho des de [[Special:Preferences]].",
        "specialmute-login-required": "Inicieu una sessió per canviar les preferències de silenciament.",
        "revid": "revisió $1",
        "pageid": "ID de pàgina $1",
index a6a5b20..3bb077b 100644 (file)
        "right-editmyusercss": "Editace vlastních uživatelských CSS souborů",
        "right-editmyuserjson": "Editace vlastních uživatelských souborů s JSONem",
        "right-editmyuserjs": "Editace vlastních uživatelských JavaScriptových souborů",
+       "right-editmyuserjsredirect": "Editace vlastních uživatelských JavaScriptových souborů, které nejsou přesměrování",
        "right-viewmywatchlist": "Prohlížení vlastního seznamu sledovaných stránek",
        "right-editmywatchlist": "Editace vlastního seznamu sledovaných stránek. Uvědomte si, že některé akce do něj mohou přidat stránky i bez tohoto oprávnění.",
        "right-viewmyprivateinfo": "Prohlížení vlastních soukromých údajů (např. e-mailová adresa, skutečné jméno)",
        "action-editmyusercss": "upravovat vlastní uživatelské CSS soubory",
        "action-editmyuserjson": "upravovat vlastní uživatelské JSON soubory",
        "action-editmyuserjs": "upravovat vlastní uživatelský JavaScript",
+       "action-editmyuserjsredirect": "editovat vlastní uživatelské JavaScriptové soubory, které nejsou přesměrování",
        "action-viewsuppressed": "prohlížet revize skryté všem uživatelům",
        "action-hideuser": "zablokovat uživatelské jméno a skrýt jej",
        "action-ipblock-exempt": "obcházet blokování IP adres, jejich rozsahů a autobloků",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Heslo nesmí být v seznamu 100 000 nejčastěji používaných hesel.",
        "passwordpolicies-policyflag-forcechange": "nutné změnit při přihlášení",
        "passwordpolicies-policyflag-suggestchangeonlogin": "navrhnout změnu při přihlášení",
+       "mycustomjsredirectprotected": "Nemáte oprávnění editovat tuto stránku s JavaScriptem, protože je to přesměrování mimo váš uživatelský prostor.",
        "easydeflate-invaliddeflate": "Poskytnutý obsah nebyl správně zkomprimován",
        "unprotected-js": "Z bezpečnostních důvodů nelze načítat JavaScript z nechráněných stran. Vyrábějte prosím JavaScriptové skripty jen ve jmenném prostoru MediaWiki: nebo jako uživatelskou podstránku",
        "userlogout-continue": "Chcete se odhlásit?"
index 495cdd6..fb0fc71 100644 (file)
        "specialmute-success": "Deine Stummschaltungseinstellungen wurden aktualisiert. Schau dir alle stummgeschalteten Benutzer in [[Special:Preferences|deinen Einstellungen]] an.",
        "specialmute-submit": "Bestätigen",
        "specialmute-label-mute-email": "E-Mails von diesem Benutzer stummschalten",
-       "specialmute-header": "Bitte wähle deine Stummschaltungseinstellungen für {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Bitte wähle deine Stummschaltungseinstellungen für <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "Der gesuchte Benutzername konnte nicht gefunden werden.",
-       "specialmute-error-email-blacklist-disabled": "Das Stummschalten von E-Mails von Benutzern ist nicht aktiviert.",
-       "specialmute-error-email-preferences": "Du musst deine E-Mail Adresse bestätigen bevor du einen Benutzer bestätigen kannst. Du kannst dies [[Special:Preferences|in deinen Einstellungen]] tun.",
        "specialmute-email-footer": "Um deine E-Mail Einstellungen für {{BIDI:$2}} zu verwalten besuche bitte $1.",
        "specialmute-login-required": "Bitte melde dich an um deine Stummschaltungseinstellungen zu ändern.",
        "revid": "Version $1",
index c6d0e90..d654a52 100644 (file)
        "parentheses-start": "(",
        "parentheses-end": ")",
        "brackets": "[$1]",
+       "brackets-start": "[",
+       "brackets-end": "]",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← previous page",
        "imgmultipagenext": "next page →",
index 378ab0f..ee1d97a 100644 (file)
        "systemblockedtext": "Via salutnomo aŭ IPa adreso estis aŭtomate forbarita de MediaWiki.\nLa kialo donita estas:\n\n:<em>$2</em>\n\n* Komenco de forbaro: $8\n* Eksvalidiĝo de forbaro: $6\n* Intenca forbarulo: $7\n\nVia nuna IP-adreso estas $3.\nBonvolu inkluzivi ĉiujn suprajn detalojn en ajnaj demandoj kiujn vi faras.",
        "blockednoreason": "neniu kialo estis donita",
        "blockedtext-composite": "<strong>Oni forbaris vian salutnomon aŭ IP-adreson.</strong>\n\nLa donita kialo estas:\n\n:<em>$2</em>.\n\n* Komenco de forbaro: $8\n* Fino de plej longa forbaro: $6\n\n* $5\n\nVia aktuala IP-adreso estas $3.\nPlease include all above details in any queries you make.",
+       "blockedtext-composite-ids": "Rilataj identigiloj de forbaro: $1 (via IP-adreso estas eble ankaŭ forbarata)",
+       "blockedtext-composite-no-ids": "Via IP-adreso estas inkluzivita en pluraj forbarlistoj",
        "blockedtext-composite-reason": "Estas pluraj forbaroj kontraŭ via konto kaj/aŭ IP-adreso",
        "whitelistedittext": "Vi devas $1 por redakti paĝojn.",
        "confirmedittext": "Vi devas konfirmi vian retpoŝtan adreson antaŭ ol redakti paĝojn. Bonvolu agordi kaj validigi vian retadreson per viaj [[Special:Preferences|preferoj]].",
        "edit-error-short": "Eraro: $1",
        "edit-error-long": "Eraroj:\n\n$1",
        "specialmute": "Silentigi",
-       "specialmute-success": "Sukcese ĝisdatiĝis viaj preferoj pri kaŝado de mesaĝoj. Vi povas vidi ĉiujn silentigitajn uzantojn ĉe [[Special:Preferences]].",
+       "specialmute-success": "Sukcese ĝisdatiĝis viaj preferoj pri kaŝado de mesaĝoj. Vi povas vidi ĉiujn silentigitajn uzantojn ĉe [[Special:Preferences|viaj preferoj]].",
        "specialmute-submit": "Konfirmi",
        "specialmute-label-mute-email": "Kaŝi retmesaĝojn el ĉi tiu uzanto",
-       "specialmute-header": "Bonvolu elekti viajn preferojn pri kaŝado de mesaĝoj el {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Bonvolu elekti viajn preferojn pri kaŝado de mesaĝoj el uzanto <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "La petita uzantnomo ne troviĝis.",
-       "specialmute-error-email-blacklist-disabled": "Malŝaltiĝis kaŝado de retmesaĝoj el specifaj uzantoj.",
-       "specialmute-error-email-preferences": "Vi povas konfirmi vian retpoŝtan adreson, antaŭ vi povas kaŝi mesaĝojn. Vi povas tion fari ĉe [[Special:Preferences]].",
        "specialmute-email-footer": "[$1 Administri preferojn pri retpoŝto por {{BIDI:$2}}.]",
        "specialmute-login-required": "Bonvolu ensaluti por konservi vian preferon pri kaŝado de mesaĝoj.",
+       "mute-preferences": "Agordoj pri silentigo",
        "revid": "revizio $1",
        "pageid": "Identigilo de paĝo $1",
        "interfaceadmin-info": "$1\n\nPermesoj pri redaktado de tut-retejaj CSS/JavaScript/JSON-dosieroj estis lastatempe disigitaj for de la rajto <code>editinterface</code>. Se vi ne komprenas kial vi ricevis ĉi tiun eraron, vidu la paĝon [[mw:MediaWiki_1.32/interface-admin]].",
index 5f6c846..70add63 100644 (file)
                        "Ryo567",
                        "Agusbou2015",
                        "Waldyrious",
-                       "Johny Weissmuller Jr"
+                       "Johny Weissmuller Jr",
+                       "Dark Dragoon"
                ]
        },
        "tog-underline": "Subrayar enlaces:",
        "edit-error-short": "Error: $1",
        "edit-error-long": "Errores:\n\n$1",
        "specialmute": "Silenciar",
-       "specialmute-success": "\nTus preferencias de silencio han sido actualizadas. Mira todos los usuarios silenciados en [[Especial: Preferencias|tus preferencias]].",
+       "specialmute-success": "Tus preferencias de silencio han sido actualizadas. Mira todos los usuarios silenciados en [[Especial:Preferencias|tus preferencias]].",
        "specialmute-submit": "Confirmar",
        "specialmute-label-mute-email": "Silenciar los correos electrónicos de este usuario",
        "specialmute-error-invalid-user": "No se encontró el nombre de usuario solicitado.",
-       "specialmute-error-email-preferences": "Debes confirmar tu dirección de correo electrónico antes de que puedas silenciar a un usuario. Puedes hacerlo desde [[Special:Preferences|tus preferencias]].",
        "revid": "revisión $1",
        "pageid": "ID de página $1",
        "interfaceadmin-info": "$1\n\nLos permisos para editar los archivos con formato CSS, JS y JSON en todo el sitio han sido recientemente separados del permiso <code>editinterface</code>. Si no comprendes por qué recibes este error, por favor lee [[mw:MediaWiki_1.32/interface-admin]].",
index 7b12798..0e4eb28 100644 (file)
        "exif-source": "Източник",
        "exif-editstatus": "Редакционен статус на изображението",
        "exif-urgency": "Спешност",
+       "exif-fixtureidentifier": "Наименование на рубриката",
        "exif-locationdest": "Показано място",
        "exif-locationdestcode": "Код на показаното място",
        "exif-objectcycle": "Време от деня за което е предназначена снимката",
        "exif-giffilecomment": "Коментар на GIF файл",
        "exif-intellectualgenre": "Тип на обекта",
        "exif-subjectnewscode": "Код на темата",
+       "exif-scenecode": "IPTC-код на кадъра",
        "exif-event": "Изобразено събитие",
        "exif-organisationinimage": "Изобразена организация",
        "exif-personinimage": "Изобразена личност",
        "exif-originalimageheight": "Височина на изображението преди изрязването",
        "exif-originalimagewidth": "Ширина на изображението преди изрязването",
        "exif-compression-1": "Декомпресиран",
+       "exif-compression-2": "CCITT Group 3, 1-мерно модифицирано кодиране на дължината на продължителността по Хъфман",
+       "exif-compression-3": "CCITT Group 3, факсово кодиране",
+       "exif-compression-4": "CCITT Group 4, факсово кодиране",
        "exif-compression-5": "LZW",
        "exif-compression-6": "JPEG (стар)",
        "exif-compression-7": "JPEG",
        "exif-gpsdirection-m": "Магнитна",
        "exif-ycbcrpositioning-1": "Центрирани",
        "exif-dc-contributor": "Сътрудници",
+       "exif-dc-coverage": "Пространствен или времеви обхват на медийния файл",
        "exif-dc-date": "Дата(и)",
        "exif-dc-publisher": "Издател",
        "exif-dc-relation": "Свързани медии",
index d555538..887accd 100644 (file)
@@ -16,6 +16,7 @@
        "exif-yresolution": "Difinizioni verthicari",
        "exif-datetime": "Data e ora di lu ciambamentu di lu file",
        "exif-imagedescription": "Deschrizioni di l'immàgina",
+       "exif-make": "Pruduttori di la telecàmmara",
        "exif-model": "Mudellu",
        "exif-software": "Software usaddu",
        "exif-artist": "Autori",
index 1943da5..aa5e61f 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Conquistador",
                        "Kolega2357",
-                       "OC Ripper"
+                       "OC Ripper",
+                       "Vlad5250"
                ]
        },
        "exif-imagewidth": "Širina",
        "exif-compression-3": "CCITT Group 3 faks kodiranje",
        "exif-compression-4": "CCITT Group 4 faks kodiranje",
        "exif-copyrighted-true": "Pod autorskim pravima",
-       "exif-copyrighted-false": "Javno vlasništvo",
+       "exif-copyrighted-false": "Autorskopravni status nije postavljen",
+       "exif-photometricinterpretation-0": "Crno-bijelo (bijela je 0)",
+       "exif-photometricinterpretation-1": "Crno-bijelo (crna je 0)",
+       "exif-photometricinterpretation-3": "Paleta",
+       "exif-photometricinterpretation-4": "Maska prozirnosti",
+       "exif-photometricinterpretation-5": "Odvojeno (vjerojatno CMYK)",
+       "exif-photometricinterpretation-8": "CIE L*a*b*",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (ICC kodiranje)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (ITU kodiranje)",
        "exif-unknowndate": "Nepoznat datum",
        "exif-orientation-1": "Normalna",
        "exif-orientation-2": "Horizontalno preokrenuto",
index e278a54..8d4fd7d 100644 (file)
        "revdelete-unsuppress": "حذف محدودیت‌ها در بازبینی‌های ترمیم‌شده",
        "revdelete-log": "دلیل:",
        "revdelete-submit": "اعمال بر {{PLURAL:$1|نسخهٔ|نسخه‌های}} انتخاب شده",
-       "revdelete-success": "پیدایی نسخه، روزآمد شد.",
+       "revdelete-success": "پیدایی نسخه روزآمد شد.",
        "revdelete-failure": "'''پیدایی نسخه‌ها قابل به روز کردن نیست:'''\n$1",
        "logdelete-success": "تغییر پیدایی مورد انجام شد.",
        "logdelete-failure": "'''پیدایی سیاهه‌ها قابل تنظیم نیست:'''\n$1",
        "specialmute-success": "تنظیمات بی‌صدا به روز شد. دیدن فهرست همهٔ کاربرانی که در [[Special:Preferences|ترجیحاتتان]] به عنوان بی‌صدا انتخاب کردید.",
        "specialmute-submit": "تأیید",
        "specialmute-label-mute-email": "بی‌صدا کردن ایمیل از این کاربر",
-       "specialmute-header": "لطفاً ترجیحات بی‌صدا برای {{BIDI:[[User:$1]]}} را انتخاب کنید.",
+       "specialmute-header": "لطفاً ترجیحات بی‌صدا برای <b>{{BIDI:[[User:$1]]}}</b> را انتخاب کنید.",
        "specialmute-error-invalid-user": "نام کاربری درخواست شده یافت نشد.",
-       "specialmute-error-email-blacklist-disabled": "بی‌صدا کردن کاربران برای ارسال ایمیل فعال نشده‌است.",
-       "specialmute-error-email-preferences": "پیش از بی‌صدا کردن دیگر کاربران باید آدرس ایمیلیتان را تائید کنید. که از [[Special:Preferences|ترجیحاتتان]] مقدور است.",
        "specialmute-email-footer": "[$1 مدیریت ترجیحات ایمیل برای {{BIDI:$2}}.]",
        "specialmute-login-required": "لطفاً برای تغییر ترجیحات بی‌صدا به سامانه وارد شوید.",
        "revid": "نسخهٔ $1",
index 867e9dc..755b38f 100644 (file)
        "blocklist-nousertalk": "oman keskustelusivun muokkaaminen estetty",
        "blocklist-editing": "muokkaaminen",
        "blocklist-editing-sitewide": "muokkaaminen (sivuston laajuisesti)",
-       "blocklist-editing-page": "sivut",
-       "blocklist-editing-ns": "nimiavaruudet",
+       "blocklist-editing-page": "sivuja",
+       "blocklist-editing-ns": "nimiavaruuksia",
        "ipblocklist-empty": "Estolista on tyhjä.",
        "ipblocklist-no-results": "Pyydetylle IP-osoitteelle tai käyttäjätunnukselle ei löytynyt vastaavia estoja.",
        "blocklink": "estä",
        "ipb_expiry_old": "Vanhentumisaika on menneisyyttä.",
        "ipb_expiry_temp": "Piilotettujen käyttäjätunnusten estojen tulee olla pysyviä.",
        "ipb_hide_invalid": "Tämän tunnuksen piilottaminen ei onnistu; sillä on enemmän kuin {{PLURAL:$1|yksi muokkaus|$1 muokkausta}}.",
-       "ipb_hide_partial": "Hidden username blocks must be sitewide blocks.",
+       "ipb_hide_partial": "Jos käyttäjän tunnus piilotetaan kun tunnus estetään, muokkauseston pitää olla sivuston laajuinen.",
        "ipb_already_blocked": "”$1” on jo estetty.",
        "ipb-needreblock": "$1 on jo estetty. Haluatko muuttaa eston asetuksia?",
        "ipb-otherblocks-header": "{{PLURAL:$1|Muu esto|Muut estot}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|muutti}} eston asetuksia kohteessa {{GENDER:$4|$3}}. Eston kesto on $5 $6",
        "logentry-partialblock-block-page": "{{PLURAL:$1|sivua|sivuja}} $2",
        "logentry-partialblock-block-ns": "{{PLURAL:$1|nimiavaruutta|nimiavaruuksia}} $2",
-       "logentry-partialblock-block": "$1 {{GENDER:$2|esti}} käyttäjää {{GENDER:$4|$3}} muokkaamasta $7. Eston kesto $5 $6",
+       "logentry-partialblock-block": "$1 {{GENDER:$2|esti}} käyttäjää {{GENDER:$4|$3}} muokkaamasta $7. Eston kesto on $5 $6",
        "logentry-partialblock-reblock": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$4|$3}} muokkauseston asetuksia estäen muokkausten tekemisen $7. Eston kesto on $5 $6",
        "logentry-non-editing-block-block": "$1 {{GENDER:$2|esti}} käyttäjää {{GENDER:$4|$3}} suorittamasta määrättyjä toimenpiteitä (lukuun ottamatta muokkaamista). Eston kesto on $5 $6",
        "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|muutti}} käyttäjän {{GENDER:$4|$3}} toimintaeston asetuksia, jotka koskevat määrättyjä toimenpiteitä. Eston kesto on $5 $6",
        "specialmute-success": "Vaimennusasetuksesi on päivitetty. Näet kaikki vaimennetut käyttäjät [[Special:Preferences|asetuksistasi]].",
        "specialmute-submit": "Vahvista",
        "specialmute-label-mute-email": "Vaimenna sähköpostit tältä käyttäjältä",
-       "specialmute-header": "Valitse vaimennusasetuksesi käyttäjälle {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Valitse vaimennusasetuksesi käyttäjälle <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "Pyydettyä käyttäjänimeä ei löydy.",
-       "specialmute-error-email-blacklist-disabled": "Sähköpostin lähettämistä käyttäjiltä ei ole vaimennettu.",
-       "specialmute-error-email-preferences": "Sinun täytyy vahvistaa sähköpostiosoitteesi ennen kuin voit vaimentaa käyttäjän. Voit tehdä sen sivulta [[Special:Preferences]].",
        "specialmute-email-footer": "Hallitaksesi sähköpostiasetuksia käyttäjälle {{BIDI:$2}}, käy sivulla <$1>.",
        "specialmute-login-required": "Kirjaudu sisään muuttaaksesi vaimentamisasetuksiasi.",
        "revid": "versio $1",
index d57678c..9e0d89c 100644 (file)
        "right-editmyusercss": "Modifier vos propres fichiers CSS utilisateur",
        "right-editmyuserjson": "Modifier vos propres fichiers utilisateur JSON",
        "right-editmyuserjs": "Modifier vos propres fichiers JavaScript utilisateur",
+       "right-editmyuserjsredirect": "Modifier vos propres fichiers JavaScript utilisateur qui sont des redirections",
        "right-viewmywatchlist": "Afficher votre propre liste de suivi",
        "right-editmywatchlist": "Modifier votre propre liste de suivi. Remarquez que certaines actions ajouteront encore des pages sans ce droit.",
        "right-viewmyprivateinfo": "Voir vos données personnelles (par exemple votre adresse, votre vrai nom)",
        "action-editmyusercss": "modifier vos propres fichiers CSS utilisateur",
        "action-editmyuserjson": "modifier vos propres fichiers JSON utilisateur",
        "action-editmyuserjs": "modifier vos propres fichiers JavaScript utilisateur",
+       "action-editmyuserjsredirect": "modifier vos propres fichiers JavaScript utilisateur qui sont des redirections",
        "action-viewsuppressed": "afficher les révisions masquées pour n’importe quel utilisateur",
        "action-hideuser": "bloquer un nom d’utilisateur, en le masquant au public",
        "action-ipblock-exempt": "contourner les blocages d’IP, blocages automatiques et blocages de plages d’IP",
        "specialmute-success": "Vos préférences de mise en sourdine on été mises à jour. Voyez tous les utilisateurs impliqués dans [[Special:Preferences|vos préférences]].",
        "specialmute-submit": "Confirmer",
        "specialmute-label-mute-email": "Mettre en sourdine les courriels de cet utilisateur",
-       "specialmute-header": "Veuillez sélectionner vos préférences de mise en sourdine pour {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Veuillez sélectionner vos préférences de mise en sourdine pour l’utilisateur <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "Le nom d’utilisateur demandé n’a pu être trouvé.",
-       "specialmute-error-email-blacklist-disabled": "La mise en sourdine des utilisateurs pour vous envoyer des courriels n’est pas activée.",
-       "specialmute-error-email-preferences": "Vous devez confirmer votre adresse courriel avant de pouvoir mettre en sourdine un utilisateur. Vous pouvez le faire depuis [[Special:Preferences]].",
-       "specialmute-email-footer": "Veuillez voir <$1> pour gérer les préférences courriel pour {{BIDI:$2}}.",
+       "specialmute-error-no-options": "Les fonctionnalités de misse en silence ne sont pas disponibles. Cela peut être dû à ce que vous n’avez pas confirmé votre adresse de messagerie, ou que l’administrateur du wiki a désactivé les fonctionnalités de courriel, ou que votre adresse est en liste noire pour ce wiki.",
+       "specialmute-email-footer": "Veuillez voir <$1> pour gérer les préférences courriel pour l’utilisateur {{BIDI:$2}}.",
        "specialmute-login-required": "Veuillez vous connecter pour mettre-à-jour vos préférences de mise en sourdine d’utilisateurs.",
        "mute-preferences": "Préférences de misse en silence",
        "revid": "version $1",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Le mot de passe ne peut pas faire partie de la liste des 100 000 mots de passe les plus communément utilisés.",
        "passwordpolicies-policyflag-forcechange": "doit changer à la reconnexion",
        "passwordpolicies-policyflag-suggestchangeonlogin": "suggérer une modification à la connexion",
+       "mycustomjsredirectprotected": "Vous n’avez pas le droit de modifier cette page JavaScript parce qu’elle est une redirection et qu’elle ne pointe pas dans votre espace utilisateur.",
        "easydeflate-invaliddeflate": "Le contenu fourni n'est pas correctement développé",
        "unprotected-js": "Pour des raisons de sécurité, JavaScript ne peut pas être chargé depuis des pages non protégées. Veuillez ne créer du javascript que dans l’espace de noms MediaWiki: ou comme sous-page utilisateur",
        "userlogout-continue": "Voulez-vous vous déconnecter ?"
index 8852724..a6eca3d 100644 (file)
        "specialmute-success": "As súas preferencias de silenciamento foron actualizadas. Ver todos os usuarios silenciados en [[Special:Preferences]].",
        "specialmute-submit": "Confirmar",
        "specialmute-label-mute-email": "Silenciar os correos electrónicos deste usuario",
-       "specialmute-header": "Por favor, seleccione as súas preferencias de silenciamento para {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Por favor, seleccione as súas preferencias de silenciamento para <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "Non se atopou o nome de usuario indicado.",
-       "specialmute-error-email-blacklist-disabled": "O silenciamento de usuario para impedir que lle envíen correos electrónicos non está activado.",
-       "specialmute-error-email-preferences": "Debe confirmar o seu enderezo de correo electrónico antes de poder silenciar a un usuario. Pode facelo en [[Special:Preferences]].",
        "specialmute-email-footer": "Para xestionar as preferencias de correo electrónico de {{BIDI:$2}}, por favor,  visite <$1>.",
        "specialmute-login-required": "Por favor, inicie sesión para alterar as súas preferencias de silenciamento.",
        "revid": "revisión $1",
index c388f62..79f0e30 100644 (file)
        "systemblockedtext": "שם המשתמש או כתובת ה־IP שלך נחסמו באופן אוטומטי על־ידי תוכנת מדיה־ויקי.\nהסיבה שניתנה לחסימה היא:\n\n:<em>$2</em>\n\n* תחילת החסימה: $8\n* פקיעת החסימה: $6\n* החסימה שבוצעה: $7\n\nכתובת ה־IP הנוכחית שלך היא $3.\nיש לציין את כל הפרטים הללו בכל פנייה לבירור החסימה.",
        "blockednoreason": "לא ניתנה סיבה",
        "blockedtext-composite": "<strong>שם המשתמש או כתובת ה־IP שלך נחסמו.</strong>\n\nהסיבה שניתנה לכך היא:\n\n:<em>$2</em>.\n\n* תחילת החסימה: $8\n* פקיעת החסימה הארוכה ביותר: $6\n\n* $5\n\nכתובת ה־IP הנוכחית שלך היא $3.\nיש לציין את כל הפרטים הללו בכל פנייה לבירור החסימה.",
+       "blockedtext-composite-ids": "מזהי החסימות הרלוונטיים: $1 (גם כתובת ה־IP שלך יכולה להיות ברשימה השחורה)",
+       "blockedtext-composite-no-ids": "כתובת ה־IP שלך מופיעה במספר רשימות שחורות",
        "blockedtext-composite-reason": "הופעלו מספר חסימות על חשבון המשתמש שלך או על כתובת ה־IP שלך (או על שניהם)",
        "whitelistedittext": "נדרשת $1 כדי לערוך דפים.",
        "confirmedittext": "יש לאמת את כתובת הדוא\"ל לפני עריכת דפים.\nנא להגדיר ולאמת את כתובת הדוא\"ל שלך באמצעות [[Special:Preferences|העדפות המשתמש]] שלך.",
        "right-editmyusercss": "עריכת קובצי CSS של המשתמש עצמו",
        "right-editmyuserjson": "עריכת קובצי JSON של המשתמש עצמו",
        "right-editmyuserjs": "עריכת קובצי JavaScript של המשתמש עצמו",
+       "right-editmyuserjsredirect": "עריכת דפי JavaScript שלך שהם הפניות",
        "right-viewmywatchlist": "צפייה ברשימת המעקב של המשתמש עצמו",
        "right-editmywatchlist": "עריכת רשימת המעקב של המשתמש עצמו. מספר פעולות יוסיפו דפים גם ללא הרשאה זו.",
        "right-viewmyprivateinfo": "צפייה במידע הפרטי של המשתמש עצמו (כגון: כתובת דוא\"ל, שם אמיתי)",
        "action-editmyusercss": "לערוך קובצי CSS של עצמך",
        "action-editmyuserjson": "לערוך קובצי JSON של עצמך",
        "action-editmyuserjs": "לערוך קובצי JavaScript של עצמך",
+       "action-editmyuserjsredirect": "לערוך את דפי ה־JavaScript שלך שהם הפניות",
        "action-viewsuppressed": "לצפות בגרסאות שהוסתרו מכל המשתמשים",
        "action-hideuser": "לחסום שם משתמש תוך הסתרתו מהציבור",
        "action-ipblock-exempt": "לעקוף חסימות של כתובות IP, חסימות אוטומטיות וחסימות טווחים",
        "specialmute-success": "העדפות ההשתקה שלך עודכנו. רשימת כל המשתמשים המושתקים זמינה ב[[Special:Preferences|העדפות שלך]].",
        "specialmute-submit": "אישור",
        "specialmute-label-mute-email": "השתקת הודעות דואר אלקטרוני מהמשתמש הזה",
-       "specialmute-header": "×\91×\97×\99ר×\95ת ×\94×¢×\93פ×\95ת ×\94×\94שתק×\94 ×©×\9c×\9a ×¢×\91×\95ר {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "× ×\90 ×\9c×\91×\97×\95ר ×\90ת ×\94×¢×\93פ×\95ת ×\94×\94שתק×\94 ×©×\9c×\9a ×¢×\91×\95ר ×\94×\9eשת×\9eש <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "שם המשתמש המבוקש לא נמצא.",
-       "specialmute-error-email-blacklist-disabled": "האפשרות להשתקת משתמשים משליחת דואר אלקטרוני אליך אינה מופעלת.",
-       "specialmute-error-email-preferences": "יש לאמת את כתובת הדואר האלקטרוני שלך לפני שתהיה לך אפשרות להשתיק משתמש. אפשר לעשות זאת מהדף [[Special:Preferences]].",
-       "specialmute-email-footer": "כדי לנהל את העדפות קבלת הדואר האלקטרוני שנשלח על־ידי {{BIDI:$2}}, באפשרותך לבקר בדף <$1>.",
+       "specialmute-error-no-options": "אפשרויות ההשתקה אינן זמינות. ייתכן שזה קורה כי: לא עשית אימות כתובת דואר אלקטרוני או שמנהל הוויקי כיבה את אפשרויות הדואר האלקטרוני או את הרשימה השחורה של הדואר האלקטרוני עבור הוויקי הזה.",
+       "specialmute-email-footer": "כדי לנהל את העדפות קבלת הדואר האלקטרוני שנשלח על־ידי המשתמש {{BIDI:$2}}, באפשרותך לבקר בדף <$1>.",
        "specialmute-login-required": "נדרשת כניסה לחשבון כדי לשנות את העדפות ההשתקה שלך.",
        "mute-preferences": "העדפות השתקה",
        "revid": "גרסה $1",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "הסיסמה לא יכולה להיות ברשימת 100,000 הסיסמאות הנפוצות ביותר.",
        "passwordpolicies-policyflag-forcechange": "לדרוש שינוי בעת כניסה לחשבון",
        "passwordpolicies-policyflag-suggestchangeonlogin": "להציע שינוי בעת כניסה לחשבון",
+       "mycustomjsredirectprotected": "אין לך הרשאה לערוך את דף ה־JavaScript הזה כי זאת הפניה ואינה מצביעה לדף בתוך מרחב המשתמש שלך.",
        "easydeflate-invaliddeflate": "התוכן שהועבר אינו דחוס כנדרש",
        "unprotected-js": "מסיבות אבטחה, לא ניתן לטעון JavaScript מדפים שאינם מוגנים. ניתן ליצור סקריפטי JavaScript רק במרחב השם \"מדיה ויקי:\" או בדפי משנה של דף המשתמש.",
        "userlogout-continue": "האם ברצונך לצאת מהחשבון?"
index 1bffe93..3c2da97 100644 (file)
        "specialmute-success": "Vaše postavke utišavanja su uspješno ažurirane. Vidite sve utišane korisnike ovdje: [[Special:Preferences]].",
        "specialmute-submit": "Potvrdi",
        "specialmute-error-invalid-user": "Korisničko ime koje ste tražili nije moguće pronaći.",
-       "specialmute-error-email-preferences": "Morate potvrditi svoju adresu e-pošte prije nego što možete utišati ovoga korisnika. To možete učiniti putem [[Special:Preferences]].",
        "specialmute-login-required": "Molimo Vas, prijavite se da biste promijenili postavke.",
        "gotointerwiki": "Napuštate projekt {{SITENAME}}",
        "gotointerwiki-invalid": "Navedeni naslov nije valjan.",
index 83d01d1..eaf2f0c 100644 (file)
        "specialmute-submit": "Megerősítés",
        "specialmute-label-mute-email": "E-mailek némítása ettől a felhasználótól",
        "specialmute-error-invalid-user": "A kért felhasználónév nem található.",
-       "specialmute-error-email-blacklist-disabled": "Felhasználók e-mailküldési lehetőségének némítása nincs bekapcsolva.",
-       "specialmute-error-email-preferences": "Először meg kell erősítened az e-mail-címedet, mielőtt lenémíthatnál egy felhasználót. Ezt a [[Special:Preferences]] oldalon tudod megtenni.",
        "specialmute-email-footer": "[$1 {{BIDI:$2}} e-mail beállításainak kezelése.]",
        "specialmute-login-required": "Kérjük, jelentkezz be a némítási beállításaid módosításához.",
        "revid": "$1 változat",
index e5d0156..031237a 100644 (file)
        "changeemail-none": "(ոչ մէկ)",
        "changeemail-password": "Ձեր {{SITENAME}} անցաբառը՝",
        "changeemail-submit": "Փոխել ելեկտրոնային հասցէն",
-       "bold_sample": "Շեշտուած տառերով գրութիւն",
-       "bold_tip": "Շեշտուած տառերով գրութիւն",
+       "bold_sample": "Թաւատառ գրութիւն",
+       "bold_tip": "Թաւատառ գրութիւն",
        "italic_sample": "Շեղատառ գրութիւն",
        "italic_tip": "Շեղատառ գրութիւն",
        "link_sample": "Յղման վերնագիր",
        "minoredit": "Ասիկա մանր խմբագրում է",
        "watchthis": "Հսկել այս էջը",
        "savearticle": "Էջը պահել",
-       "savechanges": "Õ\8aÕ¡Õ°ÕºÕ¡Õ¶Õ¥Õ¬ Ö\83Õ¸Ö\83Õ¸Õ­Õ¸Ö\82Õ©Õ«Ö\82Õ¶Õ¶Õ¥Ö\80Õ¨",
+       "savechanges": "Պահել փոփոխութիւնները",
        "publishpage": "Ստեղծել էջը",
        "publishchanges": "Հրապարակել փոփոխութիւնները",
        "savearticle-start": "Էջը պահել...",
-       "savechanges-start": "Õ\8aÕ¡Õ°ÕºÕ¡Õ¶Õ¥Õ¬ Ö\83Õ¸Ö\83Õ¸Õ­Õ¸Ö\82Õ©Õ«Ö\82Õ¶Õ¶Õ¥Ö\80Õ¨...",
+       "savechanges-start": "Պահել փոփոխութիւնները...",
        "publishpage-start": "Ստեղծել էջը...",
        "preview": "Կանխաստուգել",
        "showpreview": "Կանխաստուգել",
        "tooltip-ca-addsection": "Ստեղծել նոր բաժին",
        "tooltip-ca-viewsource": "Այս էջը պահպանուած է։ \nԿրնաք տեսնել անոր աղբիւրը",
        "tooltip-ca-history": "Այս էջի նախորդ խմբագրումները",
-       "tooltip-ca-protect": "Õ\8aÕ¡Õ°ÕºÕ¡Õ¶Õ¥Õ¬ Õ¡ÕµÕ½ Õ§Õ»Õ¨",
+       "tooltip-ca-protect": "Պահել այս էջը",
        "tooltip-ca-delete": "Ջնջել այս էջը",
        "tooltip-ca-move": "Տեղափոխել այս էջը",
        "tooltip-ca-watch": "Այս էջը աւելցնել հսկողութեան ցանկիդ վրան",
        "pagelang-name": "Էջ",
        "pagelang-language": "Լեզու",
        "special-characters-group-latin": "Լատիներէն",
+       "special-characters-group-latinextended": "Ընդլայնուած լատիներէն",
+       "special-characters-group-ipa": "Միջ․ Հնչիւնային Այբուբեն (IPA)",
+       "special-characters-group-symbols": "Նշաններ",
+       "special-characters-group-greek": "Յունարէն",
+       "special-characters-group-greekextended": "Ընդլայնուած յունարէն",
+       "special-characters-group-cyrillic": "Կիւրեղագիր",
        "special-characters-group-arabic": "Արաբերէն",
+       "special-characters-group-arabicextended": "Ընդլայնուած արաբերէն",
+       "special-characters-group-persian": "Պարսկերէն",
+       "special-characters-group-hebrew": "Եբրայերէն",
+       "special-characters-group-bangla": "Պենկալերէն",
+       "special-characters-group-tamil": "Թամիլերէն",
+       "special-characters-group-telugu": "Թելուկերէն",
+       "special-characters-group-sinhala": "Սինհալերէն",
+       "special-characters-group-gujarati": "Կուճարաթի",
+       "special-characters-group-devanagari": "Տեւանակարի",
+       "special-characters-group-thai": "Թայերէն",
+       "special-characters-group-lao": "Լաուերէն",
+       "special-characters-group-canadianaboriginal": "Քանատական վանկագիր",
        "randomrootpage": "Պատահական արմատ էջ"
 }
index 90c1a22..8e7f829 100644 (file)
        "specialmute-success": "Tu preferentias de silentio ha essite actualisate. Vide tote le usatores silentiate in [[Special:Preferences]].",
        "specialmute-submit": "Confirmar",
        "specialmute-label-mute-email": "Silentiar e-mail de iste usator",
-       "specialmute-header": "Selige tu preferentias de silentio pro {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Selige tu preferentias de silentio pro <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "Le nomine de usator que tu requestava non pote esser trovate.",
-       "specialmute-error-email-blacklist-disabled": "Le silentiamento de usatores pro inviar te e-mail non ha essite activate.",
-       "specialmute-error-email-preferences": "Tu debe confirmar tu adresse de e-mail ante de poter silentiar un usator. Face isto in [[Special:Preferences]].",
        "specialmute-email-footer": "Pro gerer le preferentias de e-mail pro {{BIDI:$2}}, visita <$1>.",
        "specialmute-login-required": "Es necessari aperir session pro cambiar le preferentias de silentio.",
        "revid": "version $1",
index 3c91602..2cc9f55 100644 (file)
                        "Albe Albe 460",
                        "Senpremì",
                        "Ignazio Cannata",
-                       "Frubino"
+                       "Frubino",
+                       "TheRukk"
                ]
        },
        "tog-underline": "Sottolinea i collegamenti:",
        "virus-scanfailed": "scansione fallita (codice $1)",
        "virus-unknownscanner": "antivirus sconosciuto:",
        "logouttext": "'''Logout effettuato.'''\n\nNota che alcune pagine potrebbero continuare ad apparire come se il logout non fosse avvenuto finché non viene pulita la cache del proprio browser.",
-       "logging-out-notify": "La tua sessione si sta chiudendo, attendere prego.",
+       "logging-out-notify": "La tua sessione sta terminando, attendi.",
        "logout-failed": "Impossibile uscire ora: $1",
        "cannotlogoutnow-title": "Impossibile uscire ora",
        "cannotlogoutnow-text": "La disconnessione non è possibile quando si sta usando $1.",
        "previewerrortext": "Si è verificato un errore durante il tentativo di mostrare l'anteprima delle tue modifiche.",
        "blockedtitle": "Utente bloccato.",
        "blocked-email-user": "<strong>Alla tua utenza è stato vietato l'invio di email. Puoi ancora modificare altre pagine di questa wiki.</strong> Puoi vedere tutti i dettagli del blocco su [[Special:MyContributions|contributi dell'utenza]].\n\nIl blocco è stato effettuato da $1.\n\nLa ragione data è <em>$2</em>.\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Destinatario del blocco: $7\n* ID Blocco #$5",
-       "blockedtext-partial": "<strong>Alla tua utenza o indirizzo IP address è stato vietato di apportare modifiche a questa pagina. Puoi comunque modificare altre pagine di questa wiki.</strong> Puoi vedere tutti i dettagli del blocco su [[Special:MyContributions|contributi dell'utenza]].\n\nIl blocco è stato effettuato da $1.\n\nLa ragione data è <em>$2</em>.\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Destinatario del blocco: $7\n* ID Blocco #$5",
+       "blockedtext-partial": "<strong>Alla tua utenza o indirizzo IP è stato vietato di apportare modifiche a questa pagina. Puoi ancora modificare altre pagine di questa wiki.</strong> Puoi vedere tutti i dettagli del blocco su [[Special:MyContributions|contributi dell'utenza]].\n\nIl blocco è stato effettuato da $1.\n\nLa ragione data è <em>$2</em>.\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Destinatario del blocco: $7\n* ID Blocco #$5",
        "blockedtext": "<strong>Il tuo nome utente o indirizzo IP è stato bloccato.</strong>\n\nIl blocco è stato imposto da $1. La motivazione del blocco è la seguente: <em>$2</em>.\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Intervallo di blocco: $7\n\nSe lo si desidera, è possibile contattare $1 o un altro [[{{MediaWiki:Grouppage-sysop}}|amministratore]] per discutere del blocco.\n\nSi noti che la funzione \"{{int:emailuser}}\" non è attiva se non è stato registrato un indirizzo email valido nelle proprie [[Special:Preferences|preferenze]] o se l'utilizzo di tale funzione è stato bloccato.\n\nL'indirizzo IP attuale è $3, il numero ID del blocco è #$5.\nSi prega di specificare tutti i dettagli precedenti in qualsiasi richiesta di chiarimenti.",
        "autoblockedtext": "Questo indirizzo IP è stato bloccato automaticamente perché condiviso con un altro utente, a sua volta bloccato da $1.\nLa motivazione del blocco è la seguente:\n\n:<em>$2</em>\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Intervallo di blocco: $7\n\nÈ possibile contattare $1 o un altro [[{{MediaWiki:Grouppage-sysop}}|amministratore]] per richiedere eventuali chiarimenti circa il blocco.\n\nSi noti che la funzione \"{{int:emailuser}}\" non è attiva se non è stato registrato un indirizzo e-mail valido nelle proprie [[Special:Preferences|preferenze]] e, comunque, se nell'applicare il blocco, tale funzione è stata disabilitata (per la durata del blocco).\n\nL'indirizzo IP attuale è $3, il numero ID del blocco è #$5\nSi prega di specificare tutti i dettagli qui inclusi nel compilare qualsiasi richiesta di chiarimenti.",
        "systemblockedtext": "Il tuo nome utente o l'indirizzo IP è stato bloccato automaticamente da MediaWiki.\nLa motivazione del blocco è la seguente:\n\n:''$2''\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Intervallo di blocco: $7\n\nL'indirizzo IP attuale è $3.\nSi prega di specificare tutti i dettagli qui inclusi nel compilare qualsiasi richiesta di chiarimenti.",
        "blockednoreason": "nessuna motivazione indicata",
-       "blockedtext-composite": "<strong>La tua utenza o indirizzo IP sono stati bloccati.</strong>\n\nLa ragione data è:\n\n:<em>$2</em>.\n\n* Inizio del blocco: $8\n* Scadenza del blocco più lungo: $6\n\n* $5\n\nIl tuo indirizzo IP attuale è $3.\nPer facore includi tutti i dettagli sopra riportati nelle richieste che farai.",
+       "blockedtext-composite": "<strong>Il tuo nome utente o indirizzo IP sono stati bloccati.</strong>\n\nLa motivazione del blocco è la seguente:\n\n:<em>$2</em>.\n\n* Inizio del blocco: $8\n* Scadenza del blocco più lungo: $6\n\n* $5\n\nL'indirizzo IP attuale è $3.\nSi prega di specificare tutti i dettagli qui inclusi nel compilare qualsiasi richiesta di chiarimenti.",
+       "blockedtext-composite-ids": "ID del blocco rilevante: $1 (il tuo indirizzo IP potrebbe essere anche nella lista nera)",
+       "blockedtext-composite-no-ids": "Il tuo indirizzo IP figura in varie liste nere.",
+       "blockedtext-composite-reason": "Ci sono molteplici blocchi contro il tuo account e/o indirizzo IP.",
        "whitelistedittext": "Per modificare le pagine è necessario $1.",
        "confirmedittext": "Per essere abilitati alla modifica delle pagine è necessario confermare il proprio indirizzo e-mail. Per impostare e confermare l'indirizzo servirsi delle [[Special:Preferences|preferenze]].",
        "nosuchsectiontitle": "Impossibile trovare la sezione",
        "edit-gone-missing": "Impossibile aggiornare la pagina.\nSembra che sia stata cancellata.",
        "edit-conflict": "Conflitto di edizione.",
        "edit-no-change": "La modifica è stata ignorata poiché non sono stati apportati cambiamenti al testo.",
+       "edit-slots-cannot-add": "{{PLURAL:$1|Il seguente slot non è|I seguenti slot non sono}} supportati qui: $2",
        "postedit-confirmation-created": "La pagina è stata creata.",
        "postedit-confirmation-restored": "La pagina è stata ripristinata.",
        "postedit-confirmation-saved": "La modifica è stata salvata.",
        "expansion-depth-exceeded-warning": "Questa pagina ha superato la profondità di espansione",
        "parser-unstrip-loop-warning": "Rilevato ciclo di Unstrip",
        "unstrip-depth-warning": "Superati i limiti di ricorsione di Unstrip ($1)",
+       "unstrip-size-warning": "Superati i limiti di grandezza di unstrip ($1)",
+       "unstrip-size-category": "Pagine nelle quali il limite di unstrip non viene rispettato",
        "converter-manual-rule-error": "Rilevato errore nella regola manuale di conversione della lingua",
        "undo-success": "Questa modifica può essere annullata.\nControlla le differenze mostrate sotto fra le due versioni per essere certo che il contenuto corrisponda a quanto desiderato, e quindi salvare le modifiche per completare la procedura di annullamento.",
        "undo-failure": "Impossibile annullare la modifica a causa di un conflitto con modifiche intermedie.",
        "action-changetags": "aggiungere o rimuovere specifiche etichette su singole versioni o voci di registro",
        "action-deletechangetags": "cancellare le etichette dal database",
        "action-purge": "aggiornare questa pagina",
+       "action-editinterface": "modifica l'interfaccia utente",
+       "action-editusercss": "modifica i file CSS di altri utenti",
+       "action-edituserjson": "modifica i file JSON di altri utenti",
+       "action-edituserjs": "modifica i file JavaScript di altri utenti",
+       "action-editsitecss": "modifica il CSS globale del sito",
+       "action-editsitejson": "modifica il JSON globale del sito",
+       "action-editsitejs": "modifica il Javascript globale del sito",
+       "action-editmyusercss": "modifica i propri file CSS",
+       "action-editmyuserjson": "modifica i propri file JSON",
+       "action-editmyuserjs": "modifica i propri file JavaScript",
        "nchanges": "$1 {{PLURAL:$1|modifica|modifiche}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|dall'ultima visita}}",
        "enhancedrc-history": "cronologia",
index ee0e787..58383e9 100644 (file)
        "specialmute-success": "ミュートの個人設定が更新されました。[[Special:Preferences|ご自分の個人設定ページ]]でミューとした利用者の一覧を確認できます。",
        "specialmute-submit": "確定",
        "specialmute-label-mute-email": "この利用者からのウィキメールをミュートする",
-       "specialmute-header": "{{BIDI:[[User:$1]]}}さんに対するミュートを個人設定で選択してください。",
+       "specialmute-header": "<b>{{BIDI:[[User:$1|$1]]}}</b>さんに対するミュートを個人設定で選択してください。",
        "specialmute-error-invalid-user": "あなたが要求した利用者名は見つかりませんでした。",
-       "specialmute-error-email-blacklist-disabled": "利用者からメールを受け取らないようにするミュートは設定されていません。",
-       "specialmute-error-email-preferences": "発信者をミューとする準備として、ご自分のeメールアドレスの認証が必要です。手続きは[[Special:Preferences|個人設定]]のページで行います。",
-       "specialmute-email-footer": "{{BIDI:$2}}のeメール発信者の個人設定を変更するには<$1>を開いてください。",
+       "specialmute-email-footer": "{{BIDI:$2}}のメール発信者の個人設定を変更するには<$1>を開いてください。",
        "specialmute-login-required": "ミュートの個人設定を変更するにはログインしてください。",
        "revid": "版 $1",
        "pageid": "ページID $1",
index 551e5be..5d7d405 100644 (file)
        "specialmute-success": "알림 미표시 환경 설정이 업데이트되었습니다. [[Special:Preferences|환경 설정]]에서 알림이 표시되지 않는 모든 사용자를 확인하십시오.",
        "specialmute-submit": "확인",
        "specialmute-label-mute-email": "이 사용자의 이메일 알림을 표시하지 않습니다",
-       "specialmute-header": "{{BIDI:[[User:$1]]}}의 알림 미표시 환경 설정을 선택해 주십시오.",
+       "specialmute-header": "<b>{{BIDI:[[User:$1]]}}</b>의 알림 미표시 환경 설정을 선택해 주십시오.",
        "specialmute-error-invalid-user": "요청한 사용자 이름을 찾을 수 없습니다.",
-       "specialmute-error-email-blacklist-disabled": "이메일 보내기로부터 사용자 알림 미표시가 활성화되어 있지 않습니다.",
-       "specialmute-error-email-preferences": "사용자의 알림을 미표시 처리하기 전에 이메일 주소를 확인해야 합니다. [[Special:Preferences]]에서 이 작업을 할 수 있습니다.",
        "specialmute-email-footer": "{{BIDI:$2}}의 이메일 환경 설정을 관리하려면 <$1>을(를) 방문해 주십시오.",
        "specialmute-login-required": "알림 미표시 환경 설정을 변경하려면 로그인해 주십시오.",
        "revid": "$1 판",
index c8c8e15..a1a00f1 100644 (file)
        "logdelete-text": "ڤانریا پاکسا بیٱ هنی د بٱلگٱ ڤیرگار دؽاری مؽکٱن، ڤلی کوتؽا مینونٱیاشو د مؽن خٱلک دؽار نؽسن.",
        "revdelete-text-others": "دیڤوندارؽا هنی مؽ تونٱن ڤ مینونٱیا قام بیٱ دٱسرسی داشتۊئٱن ۉ ڤٱناْ د نۊ زنٱ بٱکٱن، مگٱر مٱئدۊدؽیٱتؽا اْزافی میزوکاری بان.",
        "revdelete-confirm": "لوتف بٱکؽت پشت راسی بٱکؽت کاْ مؽهایت اؽ کار ناْ ٱنجوم باٛیؽت، ۉ یاٛ دل بۊیؽت کاْ شما نٱتیجٱیا اؽ کار ناْ فٱمسؽتٱ ۉ اؽ کار ناْ موتابق ڤا  [[{{MediaWiki:Policy-url}}|the policy]].ٱنجوم ماٛیؽت.",
-       "revdelete-suppress-text": "پاکساگری فقط با <strong>تئنا</strong> سی جایایی که هان د هار وه کار گرته بوئه:\n*دونسمنیایی که فره تنادارن\n*دونسمنیا نامناسو شخصی\n*: <em>تیرنشون حونه، شماره تیلیفون،رازینه زایاره ای و چیا تر</em>",
-       "revdelete-legend": "میزونکاری محدودیتیا دیار بیین.",
-       "revdelete-hide-text": "متن دوواره دیئن",
-       "revdelete-hide-image": "چی یا مین جانیا نه قام کو",
-       "revdelete-hide-name": "آرمون و انجوم گر نه قام بکید",
-       "revdelete-hide-comment": "Ú\86کسÙ\87 Ù\86Ù\87 Ù\88Û\8cراÛ\8cشت Ø¨Ú©Û\8cد",
-       "revdelete-hide-user": "نوم کاریاری ویرایشتگر/تیرنشون آی پی",
-       "revdelete-hide-restricted": "پاکساگری کردن رسینه یا سی دیوونداریا و کسونا تر",
-       "revdelete-radio-same": "آلشت نکید",
-       "revdelete-radio-set": "قام بیه",
-       "revdelete-radio-unset": "دیینی",
+       "revdelete-suppress-text": "پاکساگری فقٱت با <strong>تٱنڳؽا</strong> سی جایایؽ کاْ هان د هار ڤ کار گرتٱ مۊئٱ:\n*دونسمٱنیایؽ کاْ فرٱ تنادارٱن\n*دونسمٱنیا ناموناسب شٱخسی\n*: <em>تیرنشوݩ هونٱ، شمارٱ تلٛفوݩ، رازیٱ زایاراٛیی ۉ چیا تر</em>",
+       "revdelete-legend": "میزونکاری مٱئدۊدؽٱتؽا دؽار بیئن.",
+       "revdelete-hide-text": "متن دوئارٱ دیئن",
+       "revdelete-hide-image": "چی یا مؽن جانؽا ناْ قایم کو",
+       "revdelete-hide-name": "آرموݩ ۉ ٱنجومگر ناْ قایم بٱکؽت",
+       "revdelete-hide-comment": "Ú\86کسٱ Ù\86اÙ\92 Ú¤Û\8cراÛ\8cØ´ Ø¨Ù±Ú©Ø½Øª",
+       "revdelete-hide-user": "نوم کاریاری ڤیرایشگٱر/تیرنشوݩ آی پی",
+       "revdelete-hide-restricted": "پاکساگری کردن رٱسینٱیا سی دیڤوندارؽا ۉ کٱسونؽا تر",
+       "revdelete-radio-same": "آلشت نٱکؽت",
+       "revdelete-radio-set": "قایم بیٱ",
+       "revdelete-radio-unset": "دیئنی",
        "revdelete-suppress": "پاکساگری کردن رسینه یا سی دیوونداریا و کسونا تر",
        "revdelete-unsuppress": "محدودیتیانه د وانیریا امباربیه جا وه جا بکید",
        "revdelete-log": "دألیل:",
        "newtitle": "سی سرون هنی:",
        "move-watch": "دیئن بٱلگٱ سرچشمٱ ۉ بٱلگٱ هاستنی",
        "movepagebtn": "بٱلگٱ جا ڤ جا کو",
-       "pagemovedsub": "د خوئی جا وه جا بیه",
+       "pagemovedsub": "ڤ خۊیی جا ڤ جا بی",
        "movepage-moved": "<strong>\"$1\" جا وه جا بیه سی \"$2\"</strong>",
        "movepage-moved-redirect": "یاٛ ڤاگٱردونی دۏرس بیٱ.",
        "movepage-moved-noredirect": "د دروس کردن واگردونی جلوگری بیه.",
index f9b47fa..1ecabd7 100644 (file)
        "right-editmyusercss": "Уредување на сопствените кориснички каскадни стилски податотеки (CSS)",
        "right-editmyuserjson": "Уредување на сопствените кориснички JSON-податотеки",
        "right-editmyuserjs": "Уредување на сопствените кориснички податотеки со JavaScript",
+       "right-editmyuserjsredirect": "Уредување на сопствените кориснички JavaScript-податотеки кои се пренасочувања",
        "right-viewmywatchlist": "Преглед на вашиот список на набљудувања",
        "right-editmywatchlist": "Уредување на вашите набљудувани. Извесни дејства сепак ќе ставаат страници во нив и без да го имате ова право.",
        "right-viewmyprivateinfo": "Преглед на сопствените лични податоци (на пр. е-пошта, вистинско име и презиме)",
        "action-editmyusercss": "уредување на сопствените кориснички каскадни стилски податотеки (CSS)",
        "action-editmyuserjson": "уредување на сопствените кориснички JSON-податотеки",
        "action-editmyuserjs": "уредување на сопствените кориснички податотеки со JavaScript",
+       "action-editmyuserjsredirect": "уредување на сопствените кориснички JavaScript-податотеки кои се пренасочувања",
        "action-viewsuppressed": "преглед на преработки скриени од било кој корисник",
        "action-hideuser": "блокирање корисници, сокривање од јавноста",
        "action-ipblock-exempt": "заобиколување на IP-блокови, автоблокови и опсежни блокови",
        "specialmute-success": "Промените се успешно направени. Погледајте ги сите исклучени корисници во [[Special:Preferences|вашите нагодувања]].",
        "specialmute-submit": "Потврди",
        "specialmute-label-mute-email": "Исклучи е-пошта од корисников",
-       "specialmute-header": "Изберете поставки за известувања од {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Изберете поставки за исклучување на известувања од <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "Не можев да го најдам корисничкото име.",
-       "specialmute-error-email-blacklist-disabled": "Исклучувањето на е-пошта од корисници не е овозможено.",
-       "specialmute-error-email-preferences": "Ќе мора да ја потврдите вашата е-пошта пред да исклучите известувања од други. Тоа се прави на страницата [[Special:Preferences]].",
-       "specialmute-email-footer": "За нагодување на поставките за {{BIDI:$2}}, појдете на <$1>.",
+       "specialmute-error-no-options": "Исклучувањето на известувања е недостапно. Ова може да биде бидејќи ја немате потврдено е-поштата, или пак бидејќи администраторот оневозможил можности за е-пошта и/или го оневозможил црниот список на ова вики.",
+       "specialmute-email-footer": "За нагодување на поставките за корисникот {{BIDI:$2}}, појдете на <$1>.",
        "specialmute-login-required": "Најавете се за да ги направите промените.",
        "mute-preferences": "Нагодувања за исклучување",
        "revid": "преработка $1",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Лозинката не може да биде меѓу 100.000-те најчести лозинки.",
        "passwordpolicies-policyflag-forcechange": "мора да се промени при најава",
        "passwordpolicies-policyflag-suggestchangeonlogin": "предложи измена при најава",
+       "mycustomjsredirectprotected": "Немате дозвола да ја уредувате оваа страница со JavaScript бидејќи претставува пренасочување и не води кон вашиот именски простор.",
        "easydeflate-invaliddeflate": "Содржината не е соодветно прочистена",
        "unprotected-js": "JavaScript не може да се вчита од незаштитени страници од безбедносни причини. Создавајте JavaScript само во именскиот простор МедијаВики: или како корисничка потстраница",
        "userlogout-continue": "Дали сакате да се одјавите?"
index 565a91d..2bbc077 100644 (file)
        "autoblockedtext": "താങ്കളുടെ ഐ.പി. വിലാസം സ്വയം തടയപ്പെട്ടിരിക്കുന്നു, മറ്റൊരു ഉപയോക്താവ് ഉപയോഗിച്ച കാരണത്താൽ $1 എന്ന കാര്യനിർവാഹകനാണ് തടഞ്ഞുവെച്ചത്.\nഇതിനു കാരണമായി നൽകിയിട്ടുള്ളത്:\n\n:<em>$2</em>\n\n* തടയൽ തുടങ്ങിയത്: $8\n* തടയൽ അവസാനിക്കുന്നത്: $6\n* തടയാൻ ഉദ്ദേശിച്ചത്: $7\n\nഈ തടയലിനെ കുറിച്ച് ചർച്ച ചെയ്യാൻ താങ്കൾക്കു $1 എന്ന കാര്യനിവാഹകനേയോ മറ്റു [[{{MediaWiki:Grouppage-sysop}}|കാര്യനിർവാഹകരെയോ]] ബന്ധപ്പെടാവുന്നതാണ്.\n\nശ്രദ്ധിക്കുക [[Special:Preferences|താങ്കളുടെ ക്രമീകരണങ്ങളിൽ]] സാധുവായ ഇമെയിൽ വിലാസം രേഖപ്പെടുത്താതിരിക്കുകയോ, അത് ഉപയോഗിക്കുന്നതിൽ നിന്ന് താങ്കളെ തടയുകയോ ചെയ്തിട്ടുണ്ടെങ്കിൽ \"{{int:emailuser}}\" എന്ന സം‌വിധാനം പ്രവർത്തന രഹിതമായിരിക്കും.\n\nതാങ്കളുടെ നിലവിലുള്ള ഐ.പി. വിലാസം $3 ആണ്, താങ്കളുടെ തടയലിന്റെ ഐ.ഡി. #$5 ആകുന്നു.\nദയവായി മുകളിൽ കൊടുത്തിരിക്കുന്ന വിവരങ്ങളെല്ലാം താങ്കൾ നടത്തുന്ന അന്വേഷണങ്ങളിൽ ഉൾപ്പെടുത്തുവാൻ ശ്രദ്ധിക്കുക.",
        "systemblockedtext": "താങ്കളുടെ ഉപയോക്തൃനാമം അല്ലെങ്കിൽ ഐ.പി. വിലാസം മീഡിയവിക്കി സ്വയം തടഞ്ഞിരിക്കുന്നു.\nതടയാനുള്ള കാരണം:\n\n:<em>$2</em>\n\n* തടയൽ തുടങ്ങിയത്: $8\n* തടയൽ കാലഹരണപ്പെടുന്നത്: $6\n* തടയാനുദ്ദേശിച്ചയാൾ: $7\n\nതാങ്കളുടെ നിലവിലെ ഐ.പി. വിലാസം $3 ആണ്.\nതാങ്കൾക്കെന്തെങ്കിലും ചോദ്യങ്ങളുണ്ടെങ്കിൽ മുകളിലെ എല്ലാ വിവരങ്ങളും ഉൾപ്പെടുത്തുക.",
        "blockednoreason": "കാരണമൊന്നും സൂചിപ്പിച്ചിട്ടില്ല",
+       "blockedtext-composite-no-ids": "താങ്കളുടെ ഐ.പി. വിലാസം വിവിധ കരിമ്പട്ടികകളിൽ ഉൾപ്പെട്ടിരിക്കുന്നു",
+       "blockedtext-composite-reason": "താങ്കളുടെ അംഗത്വത്തിന് അല്ലെങ്കിൽ ഐ.പി. വിലാസത്തിന് വിവിധ തടയലുകൾ നിലവിലുണ്ട്.",
        "whitelistedittext": "താളുകൾ തിരുത്താൻ താങ്കൾ $1 ചെയ്യേണ്ടതാണ്",
        "confirmedittext": "താളുകൾ തിരുത്തുന്നതിനു മുൻപ് താങ്കൾ താങ്കളുടെ ഇമെയിൽ വിലാസം സ്ഥിരീകരിക്കേണ്ടതാണ്‌. ഇമെയിൽ വിലാസം ക്രമപ്പെടുത്തി സാധുത പരിശോധിക്കാൻ [[Special:Preferences|എന്റെ ക്രമീകരണങ്ങൾ]] എന്ന സം‌വിധാനം ഉപയോഗിക്കുക.",
        "nosuchsectiontitle": "ഉപവിഭാഗം കണ്ടെത്താനായില്ല",
        "right-editmyusercss": "താങ്കളുടെ സ്വന്തം ഉപയോക്തൃ സി.എസ്.എസ്. പ്രമാണങ്ങൾ തിരുത്തുക",
        "right-editmyuserjson": "താങ്കളുടെ സ്വന്തം ഉപയോക്തൃ ജെസൺ പ്രമാണങ്ങൾ തിരുത്തുക",
        "right-editmyuserjs": "താങ്കളുടെ സ്വന്തം ഉപയോക്തൃ ജാവാസ്ക്രിപ്റ്റ് പ്രമാണങ്ങൾ തിരുത്തുക",
+       "right-editmyuserjsredirect": "തിരിച്ചുവിടലുകൾ ആയ താങ്കളുടെ സ്വന്തം ഉപയോക്തൃ ജാവാസ്ക്രിപ്റ്റ് പ്രമാണങ്ങൾ തിരുത്തുക",
        "right-viewmywatchlist": "താങ്കളുടെ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക സ്വയം കാണുക",
        "right-editmywatchlist": "താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക സ്വയം തിരുത്തുക. ഈ അവകാശമില്ലാതെതന്നെ ചില പ്രവൃത്തികൾ താളുകൾ കൂട്ടിച്ചേർക്കുമെന്ന് അറിഞ്ഞിരിക്കുക.",
        "right-viewmyprivateinfo": "താങ്കളുടെ സ്വകാര്യവിവരങ്ങൾ കാണുക (ഉദാ: ഇമെയിൽ വിലാസം, യഥാർത്ഥനാമം)",
        "uploadstash-bad-path-unknown-type": "അപരിചിതമായ തരം \"$1\".",
        "uploadstash-file-not-found-no-thumb": "ലഘുചിത്രം സംഘടിപ്പിക്കാൻ കഴിഞ്ഞില്ല.",
        "uploadstash-file-not-found-no-remote-thumb": "ലഘുചിത്രം എടുക്കൽ പരാജയപ്പെട്ടു: $1\nയു.ആർ.എൽ.= $2",
+       "uploadstash-file-too-large": "$1 ബൈറ്റുകളിലും വലിയ പ്രമാണം സെർവ് ചെയ്യാൻ കഴിയില്ല.",
+       "uploadstash-not-logged-in": "ഉപയോക്താവ് പ്രവേശിച്ചിട്ടില്ല, പ്രമാണം ഉപയോക്താക്കളെ പ്രതിനിധീകരിക്കുന്നു.",
        "uploadstash-no-extension": "എക്സ്റ്റെൻഷൻ ശൂന്യമാണ്.",
        "uploadstash-zero-length": "പ്രമാണത്തിന്റെ നീളം ശൂന്യമാണ്.",
        "img-auth-accessdenied": "പ്രവേശനമില്ല",
        "apisandbox-dynamic-parameters-add-label": "ചരം ചേർക്കുക:",
        "apisandbox-dynamic-parameters-add-placeholder": "ചരത്തിന്റെ പേര്",
        "apisandbox-dynamic-error-exists": "\"$1\" എന്ന പേരിലുള്ള ചരം നിലവിലുണ്ട്.",
+       "apisandbox-deprecated-parameters": "ഒഴിവാക്കപ്പെട്ട ചരങ്ങൾ",
        "apisandbox-add-multi": "കൂട്ടിച്ചേർക്കുക",
        "apisandbox-submit-invalid-fields-title": "ചില മണ്ഡലങ്ങൾ അസാധുവാണ്",
        "apisandbox-results": "ഫലങ്ങൾ",
+       "apisandbox-request-format-url-label": "യു.ആർ.എൽ. ക്വറി പദശകലം",
        "apisandbox-request-url-label": "അഭ്യർത്ഥനാ യൂ.ആർ.എൽ.:",
        "apisandbox-request-json-label": "ജെസൺ അപേക്ഷിക്കുക:",
        "apisandbox-request-time": "അഭ്യർത്ഥനയുടെ സമയം: {{PLURAL:$1|$1 മി.സെ.}}",
        "activeusers-intro": "ഇത് കഴിഞ്ഞ {{PLURAL:$1|ദിവസം|$1 ദിവസങ്ങളിൽ}} ഏതെങ്കിലും വിധത്തിലുള്ള പ്രവർത്തനങ്ങൾ ചെയ്ത ഉപയോക്താക്കളുടെ പട്ടികയാണ്.",
        "activeusers-count": "കഴിഞ്ഞ {{PLURAL:$3|ഒരു ദിവസം|$3 ദിവസങ്ങളിൽ}} {{PLURAL:$1|ഒരു പ്രവൃത്തി|$1 പ്രവൃത്തികൾ}}",
        "activeusers-from": "ഇങ്ങനെ തുടങ്ങുന്ന ഉപയോക്താക്കളെ കാട്ടുക:",
+       "activeusers-groups": "സംഘങ്ങളിൽ ഉൾപ്പെട്ട ഉപയോക്താക്കളെ പ്രദർശിപ്പിക്കുക:",
+       "activeusers-excludegroups": "സംഘങ്ങളിൽ ഉൾപ്പെടാത്ത ഉപയോക്താക്കളെ പ്രദർശിപ്പിക്കുക:",
        "activeusers-noresult": "ഉപയോക്താക്കളില്ല",
        "activeusers-submit": "സജീവ ഉപയോക്താക്കളെ പ്രദർശിപ്പിക്കുക",
        "listgrouprights": "ഉപയോക്തൃവിഭാഗത്തിന്റെ അവകാശങ്ങൾ",
        "trackingcategories-msg": "പിന്തുടരൽ വർഗ്ഗം",
        "trackingcategories-name": "സന്ദേശത്തിന്റെ പേര്",
        "trackingcategories-desc": "വർഗ്ഗം ഉൾപ്പെടുത്തുന്നതിനുള്ള മാനദണ്ഡം",
+       "restricted-displaytitle-ignored": "അവഗണിക്കപ്പെട്ട പ്രദർശന തലക്കെട്ടുകളോടു കൂടിയ താളുകൾ",
        "noindex-category-desc": "ഈ താളിൽ <code><nowiki>__NOINDEX__</nowiki></code> എന്ന മാന്ത്രികവാക്ക് ഉണ്ട്, അത് അനുവദിച്ചിട്ടുള്ള നാമമേഖലയിലും ആണ്, അതുകൊണ്ടിത് റോബോട്ടുകളാൽ സൂചികാവത്കരിക്കപ്പെടില്ല.",
        "index-category-desc": "ഈ താളിൽ <code><nowiki>__INDEX__</nowiki></code> എന്ന മാന്ത്രികവാക്ക് ഉണ്ട് (അത് അനുവദിച്ചിട്ടുള്ള നാമമേഖലയിലും ആണ്), അതുകൊണ്ടിത്, സാധാരണഗതിയിൽ പാടില്ലാത്തതാണെങ്കിലും റോബോട്ടുകളാൽ സൂചികാവത്കരിക്കപ്പെടുന്നതാണ്.",
        "post-expand-template-inclusion-category-desc": "എല്ലാ ഫലകങ്ങളും വികസിപ്പിച്ചു കഴിയുമ്പോൾ, താളിന്റെ വലിപ്പം <code>$wgMaxArticleSize</code> എന്നതിലും കൂടുതലാവുമെന്നതിനാൽ, ചില ഫലകങ്ങൾ വികസിപ്പിച്ചിരുന്നില്ല.",
        "contribsub2": "ഉപയോക്താവ് {{GENDER:$3|$1}} ($2)",
        "contributions-subtitle": "ഉപയോക്താവ് {{GENDER:$3|$1}}",
        "contributions-userdoesnotexist": "\"$1\" എന്ന ഉപയോക്തൃ അം‌ഗത്വം നിലവിലില്ല.",
+       "negative-namespace-not-supported": "നെഗറ്റീവ് വിലകളോടുകൂടിയ നാമമേഖലകൾ പിന്തുണയ്ക്കുന്നില്ല.",
        "nocontribs": "ഈ മാനദണ്ഡങ്ങളുമായി യോജിക്കുന്ന മാറ്റങ്ങൾ ഒന്നും കണ്ടില്ല.",
        "uctop": "നിലവിലുള്ളത്",
        "month": "മാസം:",
        "blocklink": "തടയുക",
        "unblocklink": "സ്വതന്ത്രമാക്കുക",
        "change-blocklink": "തടയലിൽ മാറ്റം വരുത്തുക",
+       "empty-username": "(ഉപയോക്തൃനാമം ഒന്നും ലഭ്യമല്ല)",
        "contribslink": "സംഭാവനകൾ",
        "emaillink": "ഇമെയിൽ അയയ്ക്കുക",
        "autoblocker": "താങ്കളുടെ ഐ.പി. വിലാസം \"[[User:$1|$1]]\" എന്ന ഉപയോക്താവ് ഈ അടുത്ത് ഉപയോഗിക്കുകയും പ്രസ്തുത ഉപയോക്താവിനെ വിക്കിയിൽ നിന്നു തടയുകയും ചെയ്തിട്ടുള്ളതാണ്‌. അതിനാൽ താങ്കളും യാന്ത്രികമായി തടയപ്പെട്ടിരിക്കുന്നു. $1 എന്ന ഉപയോക്താവിന്റെ തടയലിനു സൂചിപ്പിക്കപ്പെട്ട കാരണം \"$2\" എന്നാണ്‌",
        "authmanager-provider-temporarypassword": "താത്കാലിക രഹസ്യവാക്ക്",
        "authprovider-confirmlink-success-line": "$1: വിജയകരമായി കണ്ണി ചേർത്തു.",
        "authprovider-resetpass-skip-label": "മറികടക്കുക",
+       "authprovider-resetpass-skip-help": "രഹസ്യവാക്ക് പുനർസജ്ജീകരണം വിട്ടേക്കുക.",
        "authform-newtoken": "ചീട്ട് കാണുന്നില്ല. $1",
        "authform-notoken": "ചീട്ട് കാണുന്നില്ല",
        "authform-wrongtoken": "തെറ്റായ ചീട്ട്",
        "restrictionsfield-label": "അനുവദിച്ചിട്ടുള്ള ഐ.പി. പരിധികൾ:",
        "edit-error-short": "പിഴവ്: $1",
        "edit-error-long": "പിഴവുകൾ:\n\n$1",
+       "specialmute": "നിശബ്ദമാക്കുക",
+       "specialmute-submit": "സ്ഥിരീകരിക്കുക",
+       "specialmute-label-mute-email": "ഈ ഉപയോക്താവിൽ നിന്നുമുള്ള ഇമെയിലുകൾ നിശബ്ദമാക്കുക",
        "revid": "നാൾപ്പതിപ്പ് $1",
        "pageid": "താൾ ഐ.ഡി. $1",
        "interfaceadmin-info": "$1\n\nസൈറ്റ്‌വ്യാപക സി.എസ്.എസ്./ജെ.എസ്./ജെസൺ പ്രമാണങ്ങൾ തിരുത്താനുള്ള അവകാശം സമീപകാലത്ത് <code>editinterface</code> അവകാശത്തിൽനിന്നും വേർപെടുത്തിയതാണ്. ഈ പിഴവ് എന്തുകൊണ്ടാണ് പ്രദർശിക്കപ്പെടുന്നതെന്ന് താങ്കൾക്ക് മനസ്സിലാകുന്നില്ലെങ്കിൽ [[mw:MediaWiki_1.32/interface-admin]] കാണുക.",
index dd8c6d2..088c2e8 100644 (file)
        "blockedtext": "<strong>သင်၏ အသုံးပြုသူအမည် သို့မဟုတ် အိုင်ပီလိပ်စာသည် ပိတ်ပင်ခြင်း ခံထားရသည်။</strong>\n\nဤပိတ်ပင်မှုအား $1 က ဆောင်ရွက်ခဲ့သည်။\nအကြောင်းရင်းမှာ <em>$2</em> ဖြစ်သည်။\n\n* ပိတ်ပင်ခြင်း စတင်ချိန်: $8\n* ပိတ်ပင်ခြင်း သက်တမ်းကုန်ချိန်: $6\n* ရည်ရွယ်ရာ blockee: $7\n\nသင်သည် ပိတ်ပင်မှုအတွက် ဆွေးနွေးရန် $1 သို့မဟုတ် အခြား [[{{MediaWiki:Grouppage-sysop}}|စီမံခန့်ခွဲသူ]] အား ဆက်သွယ်နိုင်သည်။\nသင့်အနေဖြင့် [[Special:Preferences|အကောင့်၏ ရွေးချယ်စရာများ]]ထဲတွင် ရေရာသော အီးမေးလိပ်စာအား မထည့်သွင်းထားပါက \"{{int:emailuser}}\" လုပ်ဆောင်ချက်ကို အသုံးပြုနိုင်မည် မဟုတ်ပါ။ အလားတူ ယင်းလုပ်ဆောင်ချက်ကို ပိတ်ပင်မခံရမှ လုပ်ဆောင်နိုင်မည်ဖြစ်သည်။\nသင်၏ လက်ရှိ အိုင်ပီလိပ်စာမှာ $3 ဖြစ်ပြီး၊ ပိတ်ပင်မှုအိုင်ဒီမှာ #$5 ဖြစ်သည်။\nသင်ပြုလုပ်မည့် စုံစမ်းမေးမြန်းမှုများတွင် အထက်ပါ အချက်များ အားလုံး ပါဝင်နေပါစေ။",
        "blockednoreason": "အကြောင်းပြချက် မပေးထားပါ",
        "blockedtext-composite": "<strong>သင်၏အသုံးပြုသူအမည် သို့ အိုင်ပီလိပ်စာကို ပိတ်ပင်ထားပါသည်။</strong>\n\nပေးထားသော အကြောင်းပြချက်မှာ:\n\n:<em>$2</em>။\n\n* စတင်ပိတ်ပင်ခြင်း: $8\n* ပိတ်ပင်မှု ကုန်ဆုံးရက်: $6\n\n* $5\n\nသင်၏လက်ရှိအိုင်ပီလိပ်စာမှာ $3 ဖြစ်သည်။\nသင် တောင်းဆိုချက်များလုပ်ဆောင်ပါက အထက်ပါအချက်အလက်များကို ထည့်သွင်းပါ။",
+       "blockedtext-composite-reason": "သင်၏အကောင့် သို့မဟုတ် အိုင်ပီလိပ်စာနှင့်ပတ်သက်၍ တားဆီးမှုများစွာ ရှိနေသည်",
        "whitelistedittext": "စာမျက်နှာများကို တည်းဖြတ်ရန် $1ရမည်။",
        "nosuchsectiontitle": "အပိုင်းကို ရှာမရနိုင်ပါ",
        "loginreqtitle": "လော့ဂ်အင်ဝင်ထားရန် လိုသည်",
        "yourtext": "သင့်စာသား",
        "storedversion": "သိမ်းဆည်းထားသောမူ",
        "editingold": "<strong>သတိပေးချက်: သင်သည် ဤစာမျက်နှာ၏ ခေတ်နောက်ကျသောမူကို တည်းဖြတ်နေခြင်းဖြစ်သည်။</strong>\nသိမ်းဆည်းလိုက်ပါက ယခင်မူဟောင်းမှ မည်သည့်ပြောင်းလဲချက်များမဆို ပျောက်ဆုံးသွားမည်ဖြစ်သည်။",
+       "unicode-support-fail": "သင်၏ဘရောက်ဆာမှာ ယူနီကုဒ်ကို မထောက်ပံ့ထားသကဲ့သို့ဖြစ်နေသည်။ စာမျက်နှာမျယးကိုတည်းဖြတ်ရန် ယင်းအား လိုအပ်ပါသည်၊ သင်၏တည်းဖြတ်မှုများ မသိမ်းဆည်းပါ။",
        "yourdiff": "ကွဲပြားချက်များ",
        "copyrightwarning": "{{SITENAME}} တွင် ရေးသားမှုအားလုံးကို $2 အောက်တွင် ဖြန့်ဝေရန် ဆုံးဖြတ်ပြီး ဖြစ်သည်ကို ကျေးဇူးပြု၍ သတိပြုပါ။။ (အသေးစိတ်ကို $1 တွင်ကြည့်ပါ။)\nအကယ်၍ သင့်ရေးသားချက်များကို အညှာအတာမရှိ တည်းဖြတ်ခံရခြင်း၊ စိတ်တိုင်းကျ ဖြန့်ဝေခံရခြင်းတို့ကို အလိုမရှိပါက ဤနေရာတွင် မတင်ပါနှင့်။<br />\nသင်သည် ဤဆောင်းပါးကို သင်ကိုယ်တိုင်ရေးသားခြင်း၊ သို့မဟုတ် အများပြည်သူဆိုင်ရာဒိုမိန်းများ၊ ယင်းကဲ့သို့ လွတ်လပ်သည့် ရင်းမြစ်မှ ကူးယူထားခြင်း ဖြစ်ကြောင်းလည်း ဝန်ခံ ကတိပြုပါသည်။\n<strong>မူပိုင်ခွင့်ရှိသော စာ၊ပုံများကို ခွင့်ပြုချက်မရှိဘဲ မတင်ပါနှင့်။</strong>",
        "copyrightwarning2": "{{SITENAME}} တွင် ရေးသားမှုအားလုံးသည် အခြားပုံပိုးသူများ၏ တည်းဖြတ်၊ ပြောင်းလဲ၊ ဖယ်ရှားခံရနိုင်သည်ကို သတိပြုပါ။\nအကယ်၍ သင့်ရေးသားချက်များကို အညှာအတာမရှိ တည်းဖြတ်ခံရခြင်း၊ စိတ်တိုင်းကျ ဖြန့်ဝေခံရခြင်းတို့ကို အလိုမရှိပါက ဤနေရာတွင် မတင်ပါနှင့်။<br />\nသင်သည် ဤဆောင်းပါးကို သင်ကိုယ်တိုင်ရေးသားခြင်း၊ သို့မဟုတ် အများပြည်သူဆိုင်ရာဒိုမိန်းများ၊ ယင်းကဲ့သို့ လွတ်လပ်သည့် ရင်းမြစ်မှ ကူးယူထားခြင်း ဖြစ်ကြောင်းလည်း ဝန်ခံ ကတိပြုပါသည် (အသေးစိတ်ကို $1 တွင်ကြည့်ပါ)။\n<strong>မူပိုင်ခွင့်ရှိသော စာ၊ပုံများကို ခွင့်ပြုချက်မရှိဘဲ မတင်ပါနှင့်။</strong>",
index 58c5bb6..496bb0c 100644 (file)
        "specialmute-success": "Dempingsinnstillingene dine har blitt oppdatert. Se alle dempede brukere i [[Special:Preferences|innstillingene]].",
        "specialmute-submit": "Bekreft",
        "specialmute-label-mute-email": "Demp eposter fra denne brukeren",
-       "specialmute-header": "Velg dempingsinnstillenger som gjelder {{BIDI:[[User:$1|$1]]}}.",
+       "specialmute-header": "Velg dempingsinnstillenger som gjelder <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "Det forespurte brukernavnet ble ikke funnet.",
-       "specialmute-error-email-blacklist-disabled": "Muligheten for å hindre enkeltbrukere fra å sende deg epost er ikke slått på.",
-       "specialmute-error-email-preferences": "Du må bekrefte epostadressa di før du kan dempe en bruker. Du kan gjøre det fra [[Special:Preferences|innstillingene]].",
        "specialmute-email-footer": "Besøk <$1> for å behandle epostinnstillingene som gjelder {{BIDI:$2}}.",
        "specialmute-login-required": "Logg inn for å endre dempingsinnstillingene dine.",
        "revid": "revisjon $1",
index 62c46d5..7a7589c 100644 (file)
        "systemblockedtext": "Uw gebruikersaccount of IP-adres is automatisch geblokkeerd door MediaWiki.\nDe opgegeven reden is:\n\n:<em>$2</em>\n\n* Aanvang blokkade: $8\n* Einde blokkade: $6\n* Bedoeld te blokkeren: $7\n\nUw huidige IP-adres is $3.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
        "blockednoreason": "geen reden opgegeven",
        "blockedtext-composite": "Uw gebruikersaccount of IP-adres is geblokkeerd.\n\nDe opgegeven reden is:\n\n:<em>$2</em>\n\n* Aanvang blokkade: $8\n* Einde van de langste blokkade: $6\n\n* $5\n\nUw huidige IP-adres is $3.\nVermeld alle bovenstaande gegevens als u ergens op deze blokkade reageert.",
+       "blockedtext-composite-ids": "Relevante blokkade-IDs: $1 (uw IP-adres is mogelijk ook op een zwarte lijst geplaatst)",
+       "blockedtext-composite-no-ids": "Uw IP-adres bevindt zich in meerdere zwarte lijsten",
        "blockedtext-composite-reason": "Er zijn meerdere blokkades tegen uw account en/of IP-adres",
        "whitelistedittext": "U moet $1 om pagina's te bewerken.",
        "confirmedittext": "U moet uw e-mailadres bevestigen voor u kunt bewerken.\nVoer uw e-mailadres in en bevestig het via uw [[Special:Preferences|voorkeuren]].",
        "right-editmyusercss": "Uw eigen CSS-pagina's bewerken",
        "right-editmyuserjson": "Uw eigen JSON-pagina's bewerken",
        "right-editmyuserjs": "Uw eigen JavaScriptpagina's bewerken",
+       "right-editmyuserjsredirect": "Uw eigen doorverwijs-JavaScriptpagina's bewerken",
        "right-viewmywatchlist": "Uw eigen volglijst bekijken",
        "right-editmywatchlist": "Uw eigen volglijst bewerken. Via sommige handelingen kunnen nog steeds pagina's toegevoegd worden, zelfs zonder deze bevoegdheid",
        "right-viewmyprivateinfo": "Uw eigen privégegevens bekijken (bijvoorbeeld e-mailadres, echte naam)",
        "action-editmyusercss": "uw eigen CSS-pagina's te bewerken",
        "action-editmyuserjson": "uw eigen JSON-pagina's te bewerken",
        "action-editmyuserjs": "uw eigen JavaScriptpagina's te bewerken",
+       "action-editmyuserjsredirect": "ww eigen doorverwijs-JavaScriptpagina's te bewerken",
        "action-viewsuppressed": "versies verborgen voor elke gebruiker te bekijken",
        "action-hideuser": "een gebruiker voor de overige gebruikers te verbergen",
        "action-ipblock-exempt": "IP-blokkades, automatische blokkades en IP-bereik blokkades te omzeilen",
        "specialmute-success": "Uw voorkeuren voor het negeren zijn bijgewerkt. Bekijk een lijst met alle genegeerde gebruikers in [[Special:Preferences|uw voorkeuren]].",
        "specialmute-submit": "Bevestig",
        "specialmute-label-mute-email": "Negeer e-mails van deze gebruiker",
-       "specialmute-header": "Selecteer uw voorkeur voor het negeren van {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Selecteer uw voorkeur voor het negeren van gebruiker <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "De ingevoerde gebruikersnaam kon niet worden gevonden.",
-       "specialmute-error-email-blacklist-disabled": "Het negeren van e-mails verstuurd door andere gebruikers is niet ingeschakeld.",
-       "specialmute-error-email-preferences": "U moet uw e-mailadres bevestigen voordat u een gebruiker kunt negeren. U kunt dit doen in [[Special:Preferences|uw voorkeuren]].",
-       "specialmute-email-footer": "Om uw e-mailvoorkeuren voor {{BIDI:$2}} te beheren gaat u naar <$1>.",
+       "specialmute-error-no-options": "De negeerfunctionaliteit is niet beschikbaar. Dit kan zijn omdat uw e-mailadres nog niet bevestigd is of omdat een administrator de e-mailfunctionaliteit en/of de zwarte lijst voor e-mails uitgeschakeld heeft.",
+       "specialmute-email-footer": "Om uw e-mailvoorkeuren voor gebruiker {{BIDI:$2}} te beheren gaat u naar <$1>.",
        "specialmute-login-required": "U moet aanmelden om voorkeuren voor het negeren van gebruikers in te stellen.",
        "mute-preferences": "Negeervoorkeuren",
        "revid": "versie $1",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Wachtwoorden mogen niet voorkomen in de lijst met 100.000 veelvoorkomende wachtwoorden.",
        "passwordpolicies-policyflag-forcechange": "moet gewijzigd worden bij het aanmelden",
        "passwordpolicies-policyflag-suggestchangeonlogin": "raad wijzigen aan bij het aanmelden",
+       "mycustomjsredirectprotected": "U hebt geen rechten om deze JavaScriptpagina te bewerken omdat het een doorverwijzing is en deze niet verwijst naar een pagina in uw gebruikersruimte.",
+       "easydeflate-invaliddeflate": "De opgegeven inhoud is onjuist gecomprimeerd",
        "unprotected-js": "Vanwege veiligheidsredenen kan er geen JavaScript geladen worden vanaf onbeveiligde pagina's. Gelieve alleen JavaScript pagina's aan te maken in de MediaWiki: naamruimte of als een subpagina van een gebruikerspagina.",
        "userlogout-continue": "Wilt u zich afmelden?"
 }
index fe65276..009a9e4 100644 (file)
        "systemblockedtext": "Twoja nazwa użytkownika lub adres IP zostały automatycznie zablokowane przez MediaWiki.\nPodany powód to:\n\n:<em>$2</em>\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n* Zamierzano zablokować: $7\n\nTwój obecny adres IP to $3.\nProsimy o dołączenie powyższych szczegółów w jakichkolwiek zadawanych pytaniach.",
        "blockednoreason": "nie podano przyczyny",
        "blockedtext-composite": "<strong>Twoja nazwa użytkownika lub adres IP zostały zablokowane.</strong>\n\nPodany powód to:\n\n:<em>$2</em>\n\n* Początek blokady: $8\n* Wygaśnięcie blokady: $6\n\n* $5\n\nTwój obecny adres IP to $3.\nProsimy o dołączenie powyższych szczegółów w jakichkolwiek zadawanych pytaniach.",
+       "blockedtext-composite-ids": "ID powiązanych blokad: $1 (twój adres IP może się także znajdować na czarnej liście)",
+       "blockedtext-composite-no-ids": "Twój adres IP znajduje się na wielu czarnych listach",
        "blockedtext-composite-reason": "Na twoje konto i/lub adresy IP nałożono wiele blokad.",
        "whitelistedittext": "Musisz $1, by edytować strony.",
        "confirmedittext": "Edytowanie jest możliwe dopiero po zweryfikowaniu adresu e‐mail.\nPodaj adres e‐mail i potwierdź go w swoich [[Special:Preferences|ustawieniach użytkownika]].",
        "right-editmyusercss": "Edycja własnych plików CSS",
        "right-editmyuserjson": "Edycja własnych plików JSON",
        "right-editmyuserjs": "Edycja własnych plików JavaScript",
+       "right-editmyuserjsredirect": "Edycja własnych plików JavaScript które są przekierowaniami",
        "right-viewmywatchlist": "Podgląd swojej listy obserwowanych stron",
        "right-editmywatchlist": "Edycja swojej listy obserwowanych stron. Niektóre akcje mogą dodawać strony do obserwowanych bez tego uprawnienia.",
        "right-viewmyprivateinfo": "Podgląd swoich prywatnych danych (np. adres e-mail, prawdziwe imię i nazwisko)",
        "action-editmyusercss": "edytowania własnych plików CSS",
        "action-editmyuserjson": "edytowania własnych plików JSON",
        "action-editmyuserjs": "edytowania własnych plików JavaScript",
+       "action-editmyuserjsredirect": "edytowania własnych plików JavaScript które są przekierowaniami",
        "action-viewsuppressed": "podglądu wersji ukrytych przed każdym użytkownikiem",
        "action-hideuser": "blokowania użytkownika i ukrywania go od publiczności",
        "action-ipblock-exempt": "obchodzenia blokad i blokad zakresów adresów IP",
        "specialmute-success": "Twoje preferencje ignorowania zostały zaktualizowane. Zobacz wszystkich ignorowanych użytkowników w [[Special:Preferences|swoich preferencjach]].",
        "specialmute-submit": "Potwierdź",
        "specialmute-label-mute-email": "Ignoruj e-maile od tego użytkownika",
-       "specialmute-header": "Wybierz swoje preferencje ignorowania dla {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Wybierz swoje preferencje ignorowania dla {{GENDER:$1|użytkownika|użytkowniczki}} <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "Pożądana nazwa użytkownika nie została odnaleziona.",
-       "specialmute-error-email-blacklist-disabled": "Ignorowanie e-maili od użytkowników nie jest włączone.",
-       "specialmute-error-email-preferences": "Musisz potwierdzić swój adres e-mail zanim będziesz {{GENDER:|mógł|mogła}} ignorować użytkownika. Możesz to zrobić w [[Special:Preferences|preferencjach]].",
-       "specialmute-email-footer": "Aby zarządzać preferencjami ignorowania dla {{BIDI:$2}} odwiedź <$1>.",
+       "specialmute-error-no-options": "Funkcje wyciszania są niedostępne. Jest tak dlatego że nie {{GENDER:|potwierdziłeś|potwierdziłaś}} swojego adresu e-mail, administrator wiki wyłączył funkcję wysyłania maili i/lub czarną listę adresów e-mail dla tej wiki.",
+       "specialmute-email-footer": "Aby zarządzać preferencjami ignorowania dla {{GENDER:$2|użytkownika|użytkowniczki}} {{BIDI:$2}} odwiedź <$1>.",
        "specialmute-login-required": "Zaloguj się, aby zmienić swoje preferencje wyignorowania.",
        "mute-preferences": "Ustawienia ignorowania",
        "revid": "wersja $1",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Hasło nie może znajdować się na liście 100 000 najczęściej używanych haseł.",
        "passwordpolicies-policyflag-forcechange": "musi zmienić po zalogowaniu",
        "passwordpolicies-policyflag-suggestchangeonlogin": "sugerowana zmiana po zalogowaniu",
+       "mycustomjsredirectprotected": "Nie masz uprawnień do edytowania tej strony JavaScript ponieważ jest ona przekierowaniem i nie wchodzi w skład twojej przestrzeni użytkownika.",
        "easydeflate-invaliddeflate": "Dostarczona zawartość nie jest poprawnie skompresowana",
        "unprotected-js": "Ze względów bezpieczeństwa kod JavaScript nie może zostać załadowany z niezabezpieczonych stron. Prosimy dodawać JavaScript w przestrzeni MediaWiki lub jako podstronę strony użytkownika.",
        "userlogout-continue": "Chcesz się wylogować?"
index 544ba68..00c631f 100644 (file)
        "right-editmyusercss": "Edite seu próprio arquivo CSS de usuário",
        "right-editmyuserjson": "Edite seus próprios arquivos JSON do usuário",
        "right-editmyuserjs": "Edite seu próprio arquivo JavaScript de usuário",
+       "right-editmyuserjsredirect": "Editar seus próprios arquivos JavaScript de usuários que são redirecionados",
        "right-viewmywatchlist": "Ver sua lista de vigiados",
        "right-editmywatchlist": "Editar sua lista de vigiados. Observe que algumas ações seguirão adicionando páginas, mesmo sem este direito.",
        "right-viewmyprivateinfo": "Ver seus próprios dados privados (por exemplo: endereço de e-mail, nome real)",
        "action-editmyusercss": "edite seus próprios arquivos CSS de usuário",
        "action-editmyuserjson": "editar seus próprios arquivos JSON do usuário",
        "action-editmyuserjs": "editar seus próprios arquivos JavaScript de usuário",
+       "action-editmyuserjsredirect": "editar seus próprios arquivos JavaScript de usuários que são redirecionados",
        "action-viewsuppressed": "ver revisões ocultas de qualquer usuário",
        "action-hideuser": "bloquear um nome de usuário, escondendo-o do público",
        "action-ipblock-exempt": "ignorar bloqueios IP, bloqueios automáticos e bloqueios de alcance",
        "specialmute-success": "Suas preferências de silêncio foram atualizadas com sucesso. Ver todos os usuários silenciados nas [[Special:Preferences|suas preferencias]].",
        "specialmute-submit": "Confirmar",
        "specialmute-label-mute-email": "Silenciar e-mails deste usuário",
-       "specialmute-header": "Por favor, selecione suas preferências de mudo para {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Por favor, selecione suas preferências de silenciar para usuário <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "O nome de usuário solicitado não foi encontrado.",
-       "specialmute-error-email-blacklist-disabled": "O silenciamento de usuários do envio de e-mails não está ativado.",
-       "specialmute-error-email-preferences": "Você deve confirmar seu endereço de e-mail antes de poder silenciar um usuário. Você pode fazer isso de [[Special:Preferences]].",
-       "specialmute-email-footer": "Para gerenciar as preferências de e-mail para {{BIDI:$2}} por favor visite <$1>.",
+       "specialmute-error-no-options": "Os recursos de silenciar estão indisponíveis. Isso pode ser porque: você não confirmou seu endereço de e-mail ou o administrador da wiki desabilitou os recursos de e-mail e/ou lista negra de e-mail para este wiki.",
+       "specialmute-email-footer": "Para gerenciar as preferências de e-mail para usuário {{BIDI:$2}} por favor visite <$1>.",
        "specialmute-login-required": "Por favor, entre para alterar suas preferências de mudo.",
        "mute-preferences": "Preferências do silenciador",
        "revid": "revisão $1",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "A senha não pode estar na lista de 100.000 senhas mais usadas.",
        "passwordpolicies-policyflag-forcechange": "deve mudar no login",
        "passwordpolicies-policyflag-suggestchangeonlogin": "sugerir mudança na entrada",
+       "mycustomjsredirectprotected": "Você não tem permissão para editar esta página JavaScript porque é um redirecionamento e não aponta dentro do seu espaço do usuário.",
        "easydeflate-invaliddeflate": "O conteúdo fornecido não está devidamente comprimido",
        "unprotected-js": "Por razões de segurança o JavaScript não pode ser carregado de páginas desprotegidas. Por favor, crie apenas javascript no MediaWiki: namespace ou como uma subpágina do usuário",
        "userlogout-continue": "Você quer sair?"
index b92e10f..658e7bc 100644 (file)
        "systemblockedtext": "O seu nome de utilizador ou endereço IP foram bloqueados automaticamente pelo MediaWiki.\nO motivo fornecido é:\n\n:<em>$2</em>\n\n* Início do bloqueio: $8\n* Expiração do bloqueio: $6\n* Destinatário do bloqueio: $7\n\nO seu endereço IP atual é $3.\nInclua todos os detalhes acima em quaisquer contactos sobre este assunto, por favor.",
        "blockednoreason": "sem motivo especificado",
        "blockedtext-composite": "<strong>O seu nome de utilizador ou endereço IP foram bloqueados.</strong>\n\nO motivo fornecido é:\n\n:<em>$2</em>.\n\n* Início do bloqueio: $8\n* Expiração do bloqueio mais longo: $6\n\n* $5\n\nO seu endereço IP atual é $3.\nInclua todos os detalhes acima em quaisquer contactos sobre este assunto, por favor.",
+       "blockedtext-composite-ids": "Identificadores de bloqueio relevantes: $1 (o seu endereço IP também pode estar na lista negra)",
+       "blockedtext-composite-no-ids": "O seu endereço IP aparece em várias listas negras",
        "blockedtext-composite-reason": "Existem vários bloqueios da sua conta ou endereço IP",
        "whitelistedittext": "Precisa de $1 para poder editar páginas.",
        "confirmedittext": "Precisa de confirmar o seu endereço de correio eletrónico antes de começar a editar páginas.\nIntroduza e valide o endereço através das suas [[Special:Preferences|preferências de utilizador]], por favor.",
        "right-editmyusercss": "Editar os seus próprios ficheiros CSS de utilizador",
        "right-editmyuserjson": "Editar os ficheiros JSON do próprio utilizador",
        "right-editmyuserjs": "Editar os seus próprios ficheiros JavaScript de utilizador",
+       "right-editmyuserjsredirect": "Editar os seus próprios ficheiros JavaScript de utilizador que são redirecionamentos",
        "right-viewmywatchlist": "Ver a sua lista de páginas vigiadas",
        "right-editmywatchlist": "Editar a sua própria lista de páginas vigiadas. Observe que algumas ações continuaram a adicionar páginas, mesmo sem este direito.",
        "right-viewmyprivateinfo": "Ver os seus próprios dados privados (ex.: endereço de correio eletrónico, nome real)",
        "action-editmyusercss": "editar os seus próprios ficheiros CSS de utilizador",
        "action-editmyuserjson": "editar os seus próprios ficheiros JSON de utilizador",
        "action-editmyuserjs": "editar os seus próprios ficheiros JavaScript de utilizador",
+       "action-editmyuserjsredirect": "editar os seus próprios ficheiros JavaScript de utilizador que são redirecionamentos",
        "action-viewsuppressed": "ver revisões ocultadas de todos os utilizadores",
        "action-hideuser": "bloquear um nome de utilizador, escondendo-o do público",
        "action-ipblock-exempt": "contornar bloqueios de IP, bloqueios automáticos e bloqueios de gamas de IP",
        "specialmute-success": "As suas preferências de silenciamento foram atualizadas. Ver todos os utilizadores silenciados nas [[Special:Preferences|suas preferências]].",
        "specialmute-submit": "Confirmar",
        "specialmute-label-mute-email": "Silenciar os correios eletrónicos deste utilizador",
-       "specialmute-header": "Selecione as suas preferências de silenciamento para {{BIDI:[[User:$1]]}}, por favor.",
+       "specialmute-header": "Selecione as suas preferências de silenciamento para o utilizador <b>{{BIDI:[[User:$1|$1]]}}</b>, por favor.",
        "specialmute-error-invalid-user": "Não foi possível encontrar o nome de utilizador pedido.",
-       "specialmute-error-email-blacklist-disabled": "O silenciamento de utilizadores para impedi-los de enviar-lhe correio eletrónico não está ativado.",
-       "specialmute-error-email-preferences": "Tem de confirmar o seu endereço de correio eletrónico antes de poder silenciar um utilizador. Pode fazê-lo em [[Special:Preferences]].",
-       "specialmute-email-footer": "Para gerir as preferências de correio eletrónico de {{BIDI:$2}} visite <$1>, por favor.",
+       "specialmute-error-no-options": "As funcionalidades de silenciamento estão indisponíveis. Isto pode ser porque: não confirmou o seu endereço de correio eletrónico ou o administrador da wiki desativou as funcionalidades de correio eletrónico e/ou a lista negra de endereços de correio eletrónico para esta wiki.",
+       "specialmute-email-footer": "Para gerir as preferências de correio eletrónico do utilizador {{BIDI:$2}} visite <$1>, por favor.",
        "specialmute-login-required": "Para alterar as suas preferências de silenciamento, inicie uma sessão, por favor.",
        "mute-preferences": "Preferências de silenciamento",
        "revid": "revisão $1",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "A palavra-passe não pode constar na lista das 100 000 palavras-passe usadas com mais frequência.",
        "passwordpolicies-policyflag-forcechange": "deve mudar ao iniciar sessão",
        "passwordpolicies-policyflag-suggestchangeonlogin": "sugerir alteração ao iniciar sessão",
+       "mycustomjsredirectprotected": "Não tem autorização para editar esta página de JavaScript porque ela é um redirecionamento e não aponta para o interior do seu espaço do utilizador.",
        "easydeflate-invaliddeflate": "O conteúdo fornecido não está devidamente comprimido",
        "unprotected-js": "Por motivos de segurança o JavaScript de páginas desprotegidas não pode ser carregado. Crie javascript só no espaço nominal/domínio MediaWiki: ou numa subpágina do utilizador",
        "userlogout-continue": "Quer sair?"
index 76d969d..c831a71 100644 (file)
        "parentheses-start": "{{optional}}",
        "parentheses-end": "{{optional}}",
        "brackets": "{{Optional}}\n{{Format|plain}}",
+       "brackets-start": "{{optional}}\n{{Format|plain}}",
+       "brackets-end": "{{optional}}\n{{Format|plain}}",
        "quotation-marks": "Quotation marks, for quoting, sometimes titles etc., depending on the language.\n\nSee: [[w:Quotation mark#Summary table|Non-English usage of quotation marks on Wikipedia]].\n\nParameters:\n* $1 - text to be wrapped in quotation marks",
        "imgmultipageprev": "{{Identical|Previous page}}",
        "imgmultipagenext": "{{Identical|Next page}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Password policy that enforces that a password is not in a list of 100,000 number of \"popular\" passwords.",
        "passwordpolicies-policyflag-forcechange": "Password policy flag that enforces changing invalid passwords on login.",
        "passwordpolicies-policyflag-suggestchangeonlogin": "Password policy flag that suggests changing invalid passwords on login.",
-       "mycustomjsredirectprotected": "Error message shown when user tries to edit their own JS page that is a foreign redirect without the 'mycustomjsredirectprotected' right. See also {{mw-msg|mycustomjsprotected}}.",
+       "mycustomjsredirectprotected": "Error message shown when user tries to edit their own JS page that is a foreign redirect without the 'mycustomjsredirectprotected' right. See also {{msg-mw|mycustomjsprotected}}.",
        "easydeflate-invaliddeflate": "Error message if the content passed to easydeflate was not deflated (compressed) properly",
        "unprotected-js": "Error message shown when trying to load javascript via action=raw that is not protected",
        "userlogout-continue": "Shown if user attempted to log out without a token specified. Probably the user clicked on an old link that hasn't been updated to use the new system. $1 - url that user should click on in order to log out."
index 14aaa08..db1bf05 100644 (file)
        "passwordreset-emailtext-user": "L'utende $1 sus a {{SITENAME}} ave richieste 'na mail pe arrecurdarse le dettaglie d'u cunde sue pe {{SITENAME}}\n($4). {{PLURAL:$3|'U cunde utende seguende jè|le cunde utinde seguende sonde}} associate cu st'indirizze e-mail:\n\n$2\n\n{{PLURAL:$3|Sta passuord temboranèe scade|Ste passuord temboranèe scadene}}  'mbrà {{PLURAL:$5|'nu sciurne|$5 sciurne}}.\nTu avissa trasè e scacchià 'na passuord nova. Ce quacchedun'otre ha fatte sta richieste, o ce tu t'è arrecurdate 'a passuord origgenale toje, e non g'a vuè ccu cange cchiù, tu puè ignorà stu messagge e condinuà ausanne 'a passuord vecchie.",
        "passwordreset-emailelement": "Nome utende: \n$1\n\nPassuord temboranèe: \n$2",
        "passwordreset-emailsentemail": "Ce queste éte 'n'e-mail pu cunde tune, allore 'na password azzerate ha state mannate addà.",
+       "passwordreset-emailsentusername": "Ce ste 'n'e-mail pu cunde tune, allore 'na passuord azzerate ha state mannate addà.",
        "passwordreset-nocaller": "'Nu chiamande adda essere mise",
        "passwordreset-nosuchcaller": "'U chiamande nnon g'esiste: $1",
        "passwordreset-ignored": "'A 'mbostazione nove d'a passuord non g'è gestite. Pò essere ca no ste nisciune provider configurate?",
        "expansion-depth-exceeded-warning": "Pàggene ca sbonnane 'a profonnetà de espanzione",
        "parser-unstrip-loop-warning": "Cicle infinite acchiate",
        "unstrip-depth-warning": "Limite de ricorsione infinite sbunnate ($1)",
+       "unstrip-size-warning": "Limite de lunghezze d'a scretture sbunnate ($1)",
+       "unstrip-size-category": "Pàggene addò 'u limite d'a lunghezze d'a scretture jè sbunnate",
        "converter-manual-rule-error": "Errore assute jndr'à le regole de conversione d'a lènghe manuale",
        "undo-success": "'U cangiamende pò essere annullate.\nPe piacere verifichesce 'u combronde sotte pe condrollà ca quiste ca tu vuè ccu face e pò reggistrè le cangiaminde aqquà sotte pe spiccià l'annullamende d'u cangiamende.",
        "undo-failure": "'U cangiamende non ge pò essere annullete purcè stè 'nu conflitte de cangiaminde indermedije.",
        "diff-multi-sameuser": "({{PLURAL:$1|'Na revisione de mmienze|$1 revisiune de mmienze}} da 'u stesse utende non g'avènene fatte vedè)",
        "diff-multi-otherusers": "({{PLURAL:$1|'Na revisione de mmienze|$1 revisiune de mmienze}} da {{PLURAL:$2|'n'otre utende|$2 utinde}} non g'avènene fatte vedè)",
        "diff-multi-manyusers": "({{PLURAL:$1|'Na revisione de 'mmienze|$1 revisiune de 'mmienze}} non g'è viste da cchiù de $2 {{PLURAL:$2|utende|utinde}})",
+       "diff-paragraph-moved-tonew": "'U paragrafe ha state spustate. Cazze pe passà a 'a posiziona nove.",
+       "diff-paragraph-moved-toold": "'U paragrafe ha state spustate. Cazze pe passà a 'a posiziona vecchie.",
        "difference-missing-revision": "{{PLURAL:$2|'Na revisione|$2 revisiune}} de sta differenze ($1) {{PLURAL:$2|non g'onne|non g'onne}} state acchiate.\n\nQuiste succede normalmende purcé 'u cunde jè collegate a 'na pàgene ca ha state scangellate.\nLe dettaglie le puè acchià jndr'à l'[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} archivije de le scangellaziune].",
        "searchresults": "Resultete d'a ricerche",
        "search-filter-title-prefix-reset": "Cirche tutte le pàggene",
index 4e53a38..cc12656 100644 (file)
        "systemblockedtext": "Ваше имя участника или IP-адрес были автоматически заблокированы MediaWiki.\nУказана следующая причина:\n\n:<em>$2</em>\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВаш текущий IP-адрес $3.\nПожалуйста, указывайте все эти сведения в любых своих обращениях.",
        "blockednoreason": "причина не указана",
        "blockedtext-composite": "<strong>Ваше имя участника или IP-адрес были заблокированы.</strong>\n\nУказана следующая причина:\n\n:<em>$2</em>\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n\n* $5\n\nВаш текущий IP-адрес $3.\nПожалуйста, указывайте все эти сведения в любых своих обращениях.",
+       "blockedtext-composite-ids": "Релевантные идентификаторы блокировок: $1 (ваш IP-адрес может быть в чёрном списке)",
+       "blockedtext-composite-no-ids": "Ваш IP-адрес присутствует в нескольких чёрных списках",
        "blockedtext-composite-reason": "Есть несколько блокировок вашей учётной записи и/или IP-адреса",
        "whitelistedittext": "Вы должны $1 для изменения страниц.",
        "confirmedittext": "Вы должны подтвердить свой адрес электронной почты перед правкой страниц.\nПожалуйста, введите и подтвердите свой адрес электронной почты в своих [[Special:Preferences|персональных настройках]].",
        "specialmute-success": "Изменения были успешно сделаны. Просмотрите всех отключённых участников на [[Special:Preferences|ваших настройках]].",
        "specialmute-submit": "Подтвердить",
        "specialmute-label-mute-email": "Отключить эл. почту от этого участника",
-       "specialmute-header": "Пожалуйста, выберите настройки уведомлений от {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Пожалуйста, выберите настройки уведомлений от <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "Указанное вами имя участника не может быть найдено.",
-       "specialmute-error-email-blacklist-disabled": "Не активирован функционал запрета участникам слать вам письма.",
-       "specialmute-error-email-preferences": "Вы должны подтвердить вашу электронную почту, прежде чем отключить уведомление от других. Это можно сделать на странице [[Special:Preferences]].",
        "specialmute-email-footer": "Для управления настройками эл. почты для {{BIDI:$2}}, пожалуйста, посмотрите <$1>.",
        "specialmute-login-required": "Пожалуйста, войдите, чтобы совершить изменения.",
+       "mute-preferences": "Настройки выключения",
        "revid": "версия $1",
        "pageid": "ID страницы $1",
        "interfaceadmin-info": "$1\n\nПрава на редактирование общесайтных CSS/JS/JSON-файлов были недавно вынесены из права <code>editinterface</code>. Если вы не понимаете, почему вы наткнулись на эту ошибку, см. [[mw:MediaWiki_1.32/interface-admin]].",
index 29da774..64968da 100644 (file)
@@ -39,7 +39,7 @@
        "tog-oldsig": "توھان جو موجوده دستخط:",
        "tog-fancysig": "صحيح کي وڪيٽيڪسٽ سمجھو (ڪنھن خوڪار ڳنڍڻي کانسواءِ)",
        "tog-uselivepreview": "صفحي کي ٻيھر اتارڻ سواءِ پيش نگاھ ڏيکاريو",
-       "tog-forceeditsummary": "جÙ\8aÚªÚ\8fÙ\87Ù\86 Ø®Ù\84اصÙ\88 Ø®Ø§Ù\84Ù\8a Ú\87Ú\8fÙ\8aÙ\84 Ù\87جÙ\8a ØªÙ\87 مونکي چتاءُ ڏيو",
+       "tog-forceeditsummary": "جÙ\8aÚªÚ\8fÙ\87Ù\86 ØªØ±Ù\85Ù\8aÙ\85Ù\8a ØªÙ\8eتÙ\8f Ø®Ø§Ù\84Ù\8a Ú\87Ú\8fÙ\8aÙ\84 Ù\87جÙ\8a ØªÛ\81 مونکي چتاءُ ڏيو",
        "tog-watchlisthideown": "نظر ۾ فھرست مان منھنجون ترميمون لڪايو",
        "tog-watchlisthidebots": "نظر ۾ فھرست تان بوٽ جون ترميمون لڪايو",
        "tog-watchlisthideminor": "نظر ۾ فھرست تان معمولي ترميمون لڪايو",
        "viewhelppage": "مددي صفحو ڏسو",
        "categorypage": "زمراتي صفحو ڏسو",
        "viewtalkpage": "بحث ڏسو",
-       "otherlanguages": "Ù»Ù\8aÙ\86 Ù»Ù\88Ù\84Ù\8aÙ\86 Û¾",
+       "otherlanguages": "Ù»Ù\8aÙ\88Ù\86 Ù»Ù\88Ù\84Ù\8aÙ\88Ù\86",
        "redirectedfrom": "($1 کان چوريل)",
        "redirectpagesub": "چوريل صفحو",
        "redirectto": "ڏانھن چوريو:",
        "resetpass-temp-emailed": "توهان برقٽپال ذريعي اماڻيل عارضي ڳجھي لفظ سان داخل ٿيا آهيو. داخل ٿيڻ کي مڪمل ڪرڻ لاءِ توهان کي هتي نئون ڳجھولفظ طَي ڪرڻو ئي پوندو:",
        "resetpass-temp-password": "عارضي ڳجھولفظ:",
        "resetpass-expired": "توهان جو ڳجھولفظ مدي خارج ٿي چڪو آهي. نئون ڳجھولفظ مقرر ڪريو ۽ داخل ٿيو.",
-       "resetpass-expired-soft": "توهان جو ڳجھو لفظ مدي خارج ٿي چڪو آهي. مهرباني ڪري نئون ڳجھو لفظ چونڊيو، يا ساڳيو ڪم ڪنهن ٻي وقت ڪرڻ لاءِ \"{{int:authprovider-resetpass-skip-label}}\" تي ڪلڪ ڪريو.",
+       "resetpass-expired-soft": "توهان جو ڳجھولفظ مدي خارج ٿي چڪو آهي ۽ ان کي تبديليءَ جي ضرورت آھي. مھرباني ڪري ھاڻي ڪو نئون ڳجھولفظ چونديو يا انکي بعد ۾ بدلائڻ لاءِ \"{{int:authprovider-resetpass-skip-label}}\" تي ٽڙڪ ڪريو.",
        "resetpass-validity-soft": "توهان جو ڳجھولفظ ناقابلڪار آهي: $1\n\nمھرباني ڪري نئون ڳجھولفظ چونڊيو، يا ان کي پوءِ بدلائڻ لاءِ \"{{int:authprovider-resetpass-skip-label}}\" تي ٽڙڪ ڪريو.",
        "passwordreset": "ڳجھولفظ مَٽايو",
        "passwordreset-text-one": "برقٽپال ذريعي عارضي ڳجھولفظ حاصل ڪرڻ لاءِ هيءُ فارم پُر ڪريو.",
        "media_tip": "فائيل جو ڳنڍڻو",
        "sig_tip": "توھان جي صحيح بمع اوقاتي مھر",
        "hr_tip": "افقي لڪير (ڪفايت سان استعمال ڪريو)",
-       "summary": "Ø®Ù\84اصÙ\88:",
+       "summary": "تÙ\8eتÙ\8f:",
        "subject": "موضوع:",
        "minoredit": "ھيءَ ھڪ معمولي ترميم آھي",
        "watchthis": "هيءُ صفحو نظر ۾ رکو",
        "postedit-confirmation-saved": "توهان جي ترميم سانڍجي چڪي آهي.",
        "edit-already-exists": "نئون صفحو سرجي نہ سگھيو. اهو اڳ ۾ ئي وجود رکي ٿو.",
        "invalid-content-data": "ناقابل ڪار موادي اعداد",
-       "content-not-allowed-here": "\"$1\" مواد هن صفحي [[:$2]] تي رکي نہ ٿو سگھجي.",
+       "content-not-allowed-here": "\"$1\" مواد جي هن صفحي [[:$2]] جي جڳھ \"$3\" تي اجازت ناھي.",
        "content-model-wikitext": "وڪي‌ٽيڪسٽ",
        "content-model-text": "سادو ٽيڪسٽ",
        "content-model-javascript": "جاوا اسڪرپٽ",
        "last": "پويون",
        "page_first": "پهريون",
        "page_last": "آخري",
-       "history-fieldset-title": "Ù\85سÙ\88دا Ú³Ù\88Ù\84يو",
+       "history-fieldset-title": "Ù\85سÙ\88دا Ú\87اڻيو",
        "history-show-deleted": "رڳو ڊاٺل مسودا",
        "histfirst": "اوائلي ترين",
        "histlast": "تازه ترين",
        "historysize": "({{PLURAL:$1|1 بائيٽ|$1 بائيٽس}})",
-       "historyempty": "(خالي)",
+       "historyempty": "خالي",
        "history-feed-title": "ترميمي سوانح",
        "history-feed-description": "وڪي جي هن صفحي جي ترميمي سوانح",
        "history-feed-item-nocomment": "$2 تي $1",
-       "rev-deleted-comment": "(ترÙ\85Ù\8aÙ\85Ù\8a Ø®Ù\84اصÙ\88 ھٽايل)",
+       "rev-deleted-comment": "(ترÙ\85Ù\8aÙ\85Ù\8a ØªÙ\8eتÙ\8f ھٽايل)",
        "rev-deleted-user": "(واپرائيندڙ-نانءُ ڊاٿو ويو)",
        "rev-deleted-event": "(لاگ تفصيل هٽايا ويا)",
        "rev-deleted-user-contribs": "[واپرائيندڙ-نانءُ يا آءِپِي پتو مِٽايو ويو - ڀاڱيدارين مان ترميمون لڪايون ويون]",
        "rcfilters-savedqueries-add-new-title": "ھاڻوڪيون ڇاڻين جون ترتيبون سانڍيو",
        "rcfilters-restore-default-filters": "ڏنل ڇاڻيون ريسٽور ڪريو",
        "rcfilters-clear-all-filters": "سڀئي لڳل ڇاڻيو هٽايو",
-       "rcfilters-show-new-changes": "نيون ترين تبديليون ڏيکاريو",
+       "rcfilters-show-new-changes": "$1 کان نيون تبديليون ڏسو",
        "rcfilters-search-placeholder": "تبديليون ڇاڻيو (مينيو استعمال ڪريو يا ڇاڻيءَ جي ڳولا ڪريو)",
        "rcfilters-invalid-filter": "ناقابلِڪار ڇاڻي",
        "rcfilters-empty-filter": "ڪي بہ سرگرم ڇاڻيون ناھن. سڀ ڀاڱيداريون ڏيکاريل آھن.",
        "rcfilters-filter-user-experience-level-newcomer-label": "نوان ايندڙ",
        "rcfilters-filter-user-experience-level-learner-label": "سکندڙ",
        "rcfilters-filter-user-experience-level-experienced-label": "تجربيڪار واپرائيندڙ",
+       "rcfilters-filtergroup-automated": "خودڪار ڀاڱيداريون",
        "rcfilters-filter-bots-label": "بوٽ",
        "rcfilters-filter-bots-description": "خودڪار اوزارن پاران ڪيل ترميمون.",
        "rcfilters-filter-humans-label": "انسان (بوٽ نہ)",
        "uploadtext": "فائل چاڙهڻ لاءِ هيٺيون فارم استعمال ڪيو.\nپراڻا چاڙهيل فائل ڏسڻ يا ڳولڻ لاءِ [[Special:FileList|چاڙهيل فائلن جي فهرست]] تي وڃو، ٻهير چاڙهيل فائل [[Special:Log/upload|چاڙهيل لاگ]] ۽ ختم ڪيل [[Special:Log/delete|ڊاٺ لاگ]] تي ڏسي سگھجن ٿا.\n\nفائل جي استعمال لاءِ هيٺ ڏيکاريل طريقو استعمال ڪري سگھجي ٿو:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:فائل جو نالو.jpg]]</nowiki></code></strong> فائل جي مڪمل استعمال لاءِ\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:فائل جو نالو.png|200px|thumb|left|متبادل اکر]]</nowiki></code></strong> هن جي مدد سان تصوير جي سائيز ڏئي سگھجي ٿي جيئن 200 پگزل\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code></strong> فائل کي ڏيکارڻ کان بغير شامل ڪرڻ",
        "uploadlogpage": "چاڙھ لاگ",
        "filename": "فائيل نانءُ",
-       "filedesc": "Ø®Ù\84اصÙ\88",
-       "fileuploadsummary": "Ø®Ù\84اصÙ\88:",
+       "filedesc": "تÙ\8eتÙ\8f",
+       "fileuploadsummary": "تÙ\8eتÙ\8f:",
        "filereuploadsummary": "فائيل تبديليون:",
        "filesource": "ذريعو:",
        "ignorewarnings": "چتائن کي نظرانداز ڪريو",
        "delete-confirm": "\"$1\" ڊهي چڪو",
        "delete-legend": "ڊاهيو",
        "historywarning": "<strong>خبردار:</strong> جيڪو صفحو توهان ڊاهڻ وڃي رهيا آهيو ان ساڻ هڪ تاريخ آهي $1 {{PLURAL:$1|revision|revisions}}:",
-       "historyaction-submit": "ڏيکاريو",
+       "historyaction-submit": "ورجاءَ ڏيکاريو",
        "confirmdeletetext": "توهان هڪ صفحي کي ان جي سموري سوانح سميت ڊاهڻ وارا آهيو. مهرباني ڪري پڪ ڪندا ته توهان اهو ئي ڪرڻ گھرو ٿا، ۽ اهو ته توهان ان جي نتيجن کان واقف آهيو، ۽ اهو پڻ ته توهان اهو ڪم [[{{MediaWiki:Policy-url}}|پاليسي]]ءَ مطابق ڪري رهيا آهيو.",
        "actioncomplete": "ڪم پُورو",
        "actionfailed": "عمل ناڪام",
        "tooltip-rollback": "\"واپس ورايو\" ھن صفحي ۾ پوئين ڀاڱيدار جي ڪيل ترميم(ن) کي ھڪ ٽڙڪ سان اڻڪري ٿو",
        "tooltip-undo": "\"اڻڪريو\" هن ترميم کي واپس ڪيو ۽ پيش نگاه ۾ ترميم کي کوليو. اهو اوهان کي تت شامل ڪرڻ جو موقعو ڏيندو.",
        "tooltip-preferences-save": "ترجيحون سانڍيو",
-       "tooltip-summary": "Ù\86Ù\86Ú\8dÙ\88 Ø®Ù\84اصÙ\88 ڏيو",
+       "tooltip-summary": "Ù\86Ù\86Ú\8dÙ\88 ØªÙ\8eتÙ\8f ڏيو",
        "anonymous": "{{SITENAME}} جا گمنام {{PLURAL:$1|واپرائيندڙ|واپرائيندڙَ}}",
        "simpleantispam-label": "اينٽي-اسپام روڪ.\nھن کي <strong>نہ</strong> ڀريو!",
        "pageinfo-title": "\"$1\" لاءِ معلومات",
index ca66e64..edc79a2 100644 (file)
        "view-foreign": "Vedi innantu $1",
        "edit": "Mudifigga",
        "create": "Cria",
+       "create-local": "Aggiugnì deschrizioni lucari",
        "delete": "Canzella",
        "undelete_short": "Ricùpara {{PLURAL:$1|una ribisioni|$1 ribisioni}}",
        "protect": "Brocca",
        "permissionserrorstext-withaction": "Nò si diponi di li primmissi nezzessàri pa $2, pa {{PLURAL:$1|lu sighenti mutibu|li sighenti mutibi}}:",
        "recreate-moveddeleted-warn": "'''Attinzioni: s'è pa ricrià una pàgina già canzilladda in passadu.'''\n\nS'azzirthà chi sia avveru opporthunu continuà a mudìfiggà chistha pàgina. L'erencu di li reratibi canzilladduri vèni ripurthaddu inogghi pa cumudiddai:",
        "moveddeleted-notice": "No z'è più chista pàgina.\nThe deletion, protection, and move log for the page are provided below for reference.",
+       "content-model-wikitext": "wikitext",
        "undo-success": "Chistha mudìfigga pò assé annulladda. Verifiggà lu sighenti cuntrasthu prisintaddu pa s'azzirthà chi lu cuntinuddu curripundi a cantu disizaddu e dunca saivvà li mudìfigghi pa cumprità la procedura di annullamentu.",
        "undo-failure": "Impussìbiri annullà la mudìfigga a càusa d'un cuntrasthu cun mudìfigghi intermédi.",
        "undo-summary": "Annulladda la mudìfigga $1 di [[Special:Contributions/$2|$2]] ([[User talk:$2|Dischussioni]])",
        "filehist-datetime": "Data/Ora",
        "filehist-thumb": "Miniadduri",
        "filehist-thumbtext": "Miniadduri di la virsioni di li $1",
+       "filehist-nothumb": "Nisciuna miniaddura",
        "filehist-user": "Utenti",
        "filehist-dimensions": "Misuri",
        "filehist-filesize": "Misuri di lu file",
        "sharedupload-desc-here": "Chisthu file prubeni da $1 e pó assé utirizaddu da althri prugetti. La deschrizioni di la [$2 pàgina di deschrizioni] è indicadda in giossu.",
        "filepage-nofile": "No esisthi nisciun ischedàriu cu' kisthu nommu.",
        "uploadnewversion-linktext": "Carrigga una nóba versioni di chistu file",
+       "upload-disallowed-here": "No poi sobbraschribì kisthu ischedàriu",
        "filerevert": "Turra che primma $1",
        "filerevert-legend": "Ricupara file",
        "filerevert-intro": "N'isthai pa ricuparà lu file '''[[Media:$1|$1]]''' a la [versioni $4 di lu $2, $3].",
        "undelete-show-file-submit": "Sì",
        "namespace": "Tipu di pàgina:",
        "invert": "invirthi la isciubaradda",
+       "namespace_association": "tipu di pàgina reratibu",
        "blanknamespace": "(Prinzipari)",
        "contributions": "{{GENDER:$1|Cuntributi utenti}}",
        "contributions-title": "Cuntributi di $1",
        "pageinfo-language": "Linga di cuntinuddu di ra pàgina",
        "pageinfo-content-model": "Mudellu di cuntinuddu di ra pàgina",
        "pageinfo-robot-index": "Primmissu",
+       "pageinfo-robot-noindex": "Migga primmissu",
        "pageinfo-redirects-name": "Innùmaru di cullegamenti a kistha pàgina",
        "pageinfo-subpages-name": "Innùmaru di sottupàgini di chistha pàgina",
        "pageinfo-firstuser": "Criadori di pàgini",
        "pageinfo-edits": "Innùmaru totari di modìfichi",
        "pageinfo-authors": "Innùmaru tutari d'autori dibessi",
        "pageinfo-recent-authors": "Ùlthimu innùmaru d'autori dibessi",
+       "pageinfo-magic-words": "{{PLURAL:$1|Paràura màgica|Paràuri màgichi}} ($1)",
        "pageinfo-hidden-categories": "{{PLURAL:$1|categuria cuadda|categurì cuaddi}}",
        "pageinfo-toolboxlink": "Iffuimmaziòni pa la pàgina",
        "pageinfo-contentpage-yes": "Sì",
        "svg-long-desc": "file in fuimmaddu SVG, misuri nominari $1 × $2 punti, misuri di lu file: $3",
        "show-big-image": "File d'orìgini",
        "show-big-image-preview": "Tàglia di kistha antiprimma: $1.",
+       "show-big-image-other": "{{PLURAL:$2|Althra difinizioni|Althri difinizioni}}: $1.",
        "show-big-image-size": "$1 × $2 punti",
        "newimages": "Galleria di li file nobi",
        "imagelisttext": "Inogghi una listha di '''$1''' {{PLURAL:$1|file|file}} ordhinaddi pa $2.",
index 467ffd6..f951e8a 100644 (file)
        "systemblockedtext": "MediaWiki je automatski blokirao Vaše korisničko ime ili IP-adresu.\nDat je sljedeći razlog:\n\n:<em>$2</em>\n\n* Početak bloka: $8\n* Istek bloka: $6\n* Blok je namijenjen za: $7\n\nVaša trenutna IP-adresa je $3.\nPrepišite sve gorenavedene pojedinosti ukoliko želite da vlasti pitaju za blok.",
        "blockednoreason": "razlog nije naveden",
        "blockedtext-composite": "<strong>Vaše korisničko ime ili IP-adresa je blokirano.</strong>\n\nDat je sljedeći razlog:\n\n:<em>$2</em>.\n\n* Početak bloka: $8\n* Istek najdužeg bloka: $6\n\n* $5\n\nVaša trenutna IP-adresa je $3.\nPrepišite sve gorenavedene pojedinosti ukoliko želite da vlasti pitaju za blok.",
+       "blockedtext-composite-ids": "Relevatne naznake blokova: $1 (vaša IP adresa može ujedno biti i na crnoj listi)",
+       "blockedtext-composite-no-ids": "Vaša IP adresa stoji na više crnih popisa",
        "blockedtext-composite-reason": "Vaš račun i/ili IP adresa ima nekoliko blokova",
        "whitelistedittext": "Da bi ste uređivali stranice, morate se $1.",
        "confirmedittext": "Morate potvrditi Vašu e-mail adresu prije nego počnete mijenjati stranice.\nMolimo da postavite i verifikujete Vašu e-mail adresu putem Vaših [[Special:Preferences|korisničkih opcija]].",
        "right-editmyusercss": "Uredite svoje vlastite CSS datoteke",
        "right-editmyuserjson": "Uređivanje vlastitih JSON datoteka",
        "right-editmyuserjs": "Uredite vlastite korisničke JavaScript datoteke",
+       "right-editmyuserjsredirect": "Uređivanje vlastitih JavaScript datoteka koje su preusmjeravanja",
        "right-viewmywatchlist": "Pregled vlastitog popisa praćenih stranica",
        "right-editmywatchlist": "Uređivanje vlastitih praćenih. Obratite pažnju da će neke akcije dodati stranice čak bez ovog prava.",
        "right-viewmyprivateinfo": "Pregledanje vlastitih ličnih podataka (npr. adresa e-pošte, stvarno ime)",
        "action-editmyusercss": "uređivanje vlastitih CSS datoteka",
        "action-editmyuserjson": "uređivanje vlastitih JSON datoteka",
        "action-editmyuserjs": "uređivanje vlastitih JavaScript datoteka",
+       "action-editmyuserjsredirect": "uređivanje vlastitih JavaScript datoteka koje su preusmjeravanja",
        "action-viewsuppressed": "pregledaj izmjene skrivene od svih korisnika",
        "action-hideuser": "blokiranje korisničkog imena, i njegovo sakrivanje od javnosti",
        "action-ipblock-exempt": "zaobilaženje IP blokova, autoblokova i opsežnih blokova",
        "edit-error-short": "Greška: $1",
        "edit-error-long": "Greške:\n\n$1",
        "specialmute": "Iskl. obavještenja",
-       "specialmute-success": "Promjene su uspješno napravljene. Pogledajte sve isključene korisnike na [[Special:Preferences]].",
+       "specialmute-success": "Promjene su uspješno napravljene. Pogledajte sve isključene korisnike u [[Special:Preferences|Vašim podešavanjima]].",
        "specialmute-submit": "Potvrdi / Потврди",
        "specialmute-label-mute-email": "Isključi e-poštu od ovog korisnika",
-       "specialmute-header": "Izaberite postavke za obavještenja od {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Izaberite postavke za isključavanje obavještenja od <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "Nisam mogao naći korisničko ime.",
-       "specialmute-error-email-blacklist-disabled": "Isključavanje e-pošte od korisnika nije omogućeno.",
-       "specialmute-error-email-preferences": "Morat ćete potvrditi svoju e-poštu prije isključivanja obavijesti od drugih. To je učinjeno na stranici [[Special:Preferences]].",
-       "specialmute-email-footer": "[$1 Upravljanje postavkama e-pošte od {{BIDI:$2}}.]",
+       "specialmute-error-no-options": "Isključivanje obavještenja je nedostupno. Ovo može biti jer nemate potvrđenu e-poštu, ili pak jer je administrator onemogućio mogućnosti e-pošte i/ili onemogućio crnu listu na ovom wikiju.",
+       "specialmute-email-footer": "Za postavljanje postavki za korisnika {{BIDI:$2}}, idite na <$1>.",
        "specialmute-login-required": "Molimo Vas prijavite se da biste napravili promjene.",
+       "mute-preferences": "Preferencije za isključavanje",
        "revid": "izmjena $1",
        "pageid": "ID stranice $1",
        "interfaceadmin-info": "$1\n\nDozvole za uređivanje CSS/JS/JSON datoteka preko cijelog wikija nedavno su odvojene od prava <code>editinterface</code>. Ako ne razumijete zašto ste dobili ovu grešku, pogl. [[mw:MediaWiki_1.32/interface-admin]].",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Lozinka ne može biti na listi 100.000 najčešće korišćenih lozinki.",
        "passwordpolicies-policyflag-forcechange": "mora se promjeniti pri prijavi",
        "passwordpolicies-policyflag-suggestchangeonlogin": "predloži izmjenu pri prijavi",
+       "mycustomjsredirectprotected": "Nemate dopuštenje za uređivanje ove JavaScript stranice jer predstavlja preusmjeravanje i ne vodi do vašeg imenskog prostora.",
        "easydeflate-invaliddeflate": "Sadržaj nije ispravno pročišćen",
        "unprotected-js": "JavaScript ne može da se učita sa nezaštićenih stranica iz bezbednosnih razloga. Samo napravite JavaScript u imenskom prostoru MediaWiki: ili kao korisničku podstranicu",
        "userlogout-continue": "Ako se želite odjaviti, [$1 nastavite na odjavnoj strnaici]."
index a330658..0dc68bc 100644 (file)
@@ -40,7 +40,8 @@
                        "Fitoschido",
                        "Matěj Suchánek",
                        "Vlad5250",
-                       "Robert Važan"
+                       "Robert Važan",
+                       "Vegetator"
                ]
        },
        "tog-underline": "Podčiarkovať odkazy:",
        "diff-multi-manyusers": "({{PLURAL:$1|$1 medziľahlá revízia|$1 medziľahlé revízie|$1 medziľahlých revízií}} od viac ako {{PLURAL:$2|$2 používateľa|$2 používateľov}} {{PLURAL:$1|nie je zobrazená|nie sú zobrazené|nie je zobrazených}})",
        "difference-missing-revision": "{{PLURAL:$2|$2 revízia|$2 revízie|$2 revízií}} pre požadovaný rozdiel ($1) {{PLURAL:$2|neexistuje|neexistujú|neexistuje}}.\n\nPravdepodobne ste nasledovali zastaraný odkaz na rozdiel revízií, z ktorých niektorá bola medzičasom odstránená.\nPodrobnosti nájdete v [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} zázname zmazaní].",
        "searchresults": "Výsledky vyhľadávania",
+       "search-filter-title-prefix-reset": "Vybrať na všetkých stránkach",
        "searchresults-title": "Výsledky hľadania „$1“",
        "titlematches": "Vyhovujúce názvy stránok",
        "textmatches": "Zhody v textoch stránok",
index 42e2934..ea6035c 100644 (file)
        "systemblockedtext": "Vaše uporabniško ime ali IP-naslov je MediaWiki samodejno blokiral.\nPodani razlog je:\n\n:<em>$2</em>\n\n* Začetek blokade: $8\n* Potek blokade: $6\n* Blokirani uporabnik: $7\n\nVaš trenutni IP-naslov je $3.\nProsimo, da v svoje poizvedbe vključite vse zgornje podatke.",
        "blockednoreason": "razlog ni podan",
        "blockedtext-composite": "<strong>Vaše uporabniško ime ali IP-naslov je bil blokiran.</strong>\n\nPodani razlog je:\n\n:<em>$2</em>\n\n* Začetek blokade: $8\n* Potek najdaljše blokade: $6\n\n* $5\n\nVaš trenutni IP-naslov je $3.\nProsimo, da v svoje poizvedbe vključite vse zgornje podatke.",
+       "blockedtext-composite-ids": "Relevantni ID-ji blokad: $1 (vaš IP-naslov je tudi lahko na črnem seznamu)",
+       "blockedtext-composite-no-ids": "Vaš IP-naslov je na več črnih seznamih",
        "blockedtext-composite-reason": "Za vaš račun in/ali IP-naslov je nastavljenih več blokad.",
        "whitelistedittext": "Za urejanje strani se morate $1.",
        "confirmedittext": "Pred urejanjem strani morate potrditi svoj e-poštni naslov.\nProsimo, da ga z uporabo [[Special:Preferences|uporabniških nastavitev]] vpišete in potrdite.",
        "right-editmyusercss": "Urejanje svojih uporabniških datotek CSS",
        "right-editmyuserjson": "Urejanje svojih uporabniških datotek JSON",
        "right-editmyuserjs": "Urejanje svojih uporabniških datotek JavaScript",
+       "right-editmyuserjsredirect": "Urejanje svojih uporabniških datotek JavaScript, ki so preusmeritve",
        "right-viewmywatchlist": "Ogledovanje svojega spiska nadzorov",
        "right-editmywatchlist": "Urejanje vašega spiska nadzorov. Vedite, da bodo nekatera dejanja dodala strani nanj tudi brez te pravice.",
        "right-viewmyprivateinfo": "Ogled svojih zasebnih podatkov (npr. e-poštnega naslova, pravega imena)",
        "action-editmyusercss": "urejanje svojih uporabniških datotek CSS",
        "action-editmyuserjson": "urejanje svojih uporabniških datotek JSON",
        "action-editmyuserjs": "urejanje svojih uporabniških datotek JavaScript",
+       "action-editmyuserjsredirect": "urejanje svojih uporabniških datotek JavaScript, ki so preusmeritve,",
        "action-viewsuppressed": "ogled redakcij skritih pred vsemi uporabniki",
        "action-hideuser": "blokiranje uporabnika in skritje pred javnostjo",
        "action-ipblock-exempt": "izogib blokadam IP-naslova, samodejnim blokadam in blokadam območij",
        "specialmute-success": "Vaše nastavitve utišanja smo uspešno posodobili. Oglejte si vse utišane uporabnike v [[Special:Preferences|svojih nastavitvah]].",
        "specialmute-submit": "Potrdi",
        "specialmute-label-mute-email": "Utišaj e-pošto tega uporabnika",
-       "specialmute-header": "Prosimo, izberite svoje nastavitve utišanja za uporabnika {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Prosimo, izberite svoje nastavitve utišanja za uporabnika <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "Navedenega uporabniškega imena ni bilo mogoče najti.",
-       "specialmute-error-email-blacklist-disabled": "Utišanje uporabnikov pred pošiljanjem e-pošte ni omogočeno.",
-       "specialmute-error-email-preferences": "Preden lahko utišate uporabnika morate potrditi svoj e-poštni naslov. To lahko storite na strani [[Special:Preferences]].",
+       "specialmute-error-no-options": "Funkcionalnosti utišanja niso na voljo. Možni razlogi so: niste potrdili svojega e-poštnega naslova ali pa je administrator wikija onemogočil funkcionalnosti e-pošte in/ali črni seznam e-pošte za ta wiki.",
        "specialmute-email-footer": "Za upravljanje e-poštnih nastavitev za uporabnika {{BIDI:$2}} obiščite <$1>.",
        "specialmute-login-required": "Prosimo, prijavite se, da spremenite svoje nastavitve utišanja.",
+       "mute-preferences": "Nastavitve utišanja",
        "revid": "redakcija $1",
        "pageid": "ID strani $1",
        "interfaceadmin-info": "$1\n\nDovoljenja za urejanje datotek CSS/JS/JSON spletišča smo nedavno ločili od dovoljenja <code>editinterface</code>. Če ne razumete, zakaj smo vam izpisali to napako, si oglejte [[mw:MediaWiki_1.32/interface-admin]].",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Geslo ne more biti na seznamu 100.000 najpogosteje uporabljenih gesel.",
        "passwordpolicies-policyflag-forcechange": "treba spremeniti ob prijavi",
        "passwordpolicies-policyflag-suggestchangeonlogin": "predlagaj zamenjavo ob prijavi",
+       "mycustomjsredirectprotected": "Nimate pravic za urejanje te strani z JavaScriptom, ker je preusmeritev in ne kaže v vaš uporabniški prostor.",
        "easydeflate-invaliddeflate": "Dana vsebina ni pravilno stisnjena",
        "unprotected-js": "Iz varnostnih razlogov JavaScripta ni možno naložiti z nezaščitenih strani. Prosimo, da JavaScript ustvarite samo v imenskem prostoru MediaWiki ali kot uporabniško podstran.",
        "userlogout-continue": "Se želite odjaviti?"
index 321962f..7574f53 100644 (file)
@@ -44,7 +44,7 @@
                ]
        },
        "tog-underline": "Nënvizimi i lidhjes:",
-       "tog-hideminor": "Fshih redaktimet e vogla nga ndryshimet më të fundit fundit",
+       "tog-hideminor": "Fshih redaktimet e vogla nga ndryshimet më të fundit",
        "tog-hidepatrolled": "Fshih redaktimet e kontrolluara nga ndryshimet më të fundit",
        "tog-newpageshidepatrolled": "Fshih faqet e kontrolluara nga lista e faqeve të reja",
        "tog-hidecategorization": "Fshih kategorizimin e faqeve",
        "virus-scanfailed": "skanimi dështoi (code $1)",
        "virus-unknownscanner": "antivirus i pa njohur:",
        "logouttext": "'''Ju keni dalë jashtë.''' \n \nKini parasysh që disa faqe mund të shfaqen sikur të ishit i/e identifikuar derisa të fshini ''cache''-in e shfletuesit tuaj.",
+       "logging-out-notify": "Po dilni nga llogaria juaj. Ju lutemi, prisni.",
+       "logout-failed": "Nuk mund të dilni nga llogaria juaj aktualisht: $1",
        "cannotlogoutnow-title": "Nuk mund të çkyçeni tani",
        "cannotlogoutnow-text": "Çregjistrimi nuk është i mundur kur përdorni $1.",
        "welcomeuser": "Mirë se vini, $1!",
        "group-autoconfirmed": "Përdorues të vërtetuar automatikisht",
        "group-bot": "Robot",
        "group-sysop": "Administrues",
+       "group-interface-admin": "Administratorët e ndërfaqes",
        "group-bureaucrat": "Burokrat",
        "group-suppress": "Shtypësit",
        "group-all": "(të gjitha)",
        "grouppage-autoconfirmed": "{{ns:project}}:Përdorues të vërtetuar automatikisht",
        "grouppage-bot": "{{ns:project}}:Robotë",
        "grouppage-sysop": "{{ns:project}}:Administruesit",
+       "grouppage-interface-admin": "{{ns:project}}:Wikipedia:Administratorët e ndërfaqes",
        "grouppage-bureaucrat": "{{ns:project}}:Burokratë",
        "grouppage-suppress": "{{ns:project}}:Shtypur",
        "right-read": "Lexo faqe",
index e165fe0..918a8be 100644 (file)
        "systemblockedtext": "Ditt användarnamn eller IP-adress h    ar blockerats automatiskt av MediaWiki.\n\nMotiveringen av blockeringen var:\n\n:<em>$2</em>\n\n* Blockeringen startade: $8\n* Blockeringen gäller till: $6\n* Blockeringen är avsedd för: $7\n\nDin nuvarande IP-adress är $3.\nVänligen ange informationen ovan i alla förfrågningar som du gör i ärendet.",
        "blockednoreason": "ingen motivering angavs",
        "blockedtext-composite": "<strong>Ditt användarnamn eller din IP-adress har blockerats.</strong>\n\nMotiveringen till detta är:\n\n<em>$2</em>.\n\n* Blockeringen startade: $8\n* Den längsta blockeringen gäller till: $6\n\n* $5\n\nDin nuvarande IP-adress är $3.\n\nVänligen ange all informationen ovan i förfrågningar som du gör i ärendet.",
+       "blockedtext-composite-ids": "Relevanta blockerings-ID:n: $1 (din IP-adress kan också vara svartlistad)",
+       "blockedtext-composite-no-ids": "Din IP-adress finns i flera svartlistor",
        "blockedtext-composite-reason": "Det föreligger flera blockeringar mot ditt konto eller din IP-adress.",
        "whitelistedittext": "Vänligen $1 för att redigera sidor.",
        "confirmedittext": "Du måste bekräfta din e-postadress innan du kan redigera sidor. Var vänlig ställ in och validera din e-postadress genom dina [[Special:Preferences|användarinställningar]].",
        "right-editmyusercss": "Redigera din egen användares CSS-filer",
        "right-editmyuserjson": "Redigera dina egna JSON-filer",
        "right-editmyuserjs": "Redigera din egen användares JavaScript-filer",
+       "right-editmyuserjsredirect": "Redigera dina egna JavaScript-filer som är omdirigeringar",
        "right-viewmywatchlist": "Visa din egen bevakningslista",
        "right-editmywatchlist": "Redigera din egen bevakningslista. Observera att en del åtgärder kommer fortfarande lägga till sidor även utan denna rättighet.",
        "right-viewmyprivateinfo": "Visa dina egna privata data (t.ex. e-postadress, riktiga namn)",
        "action-editmyusercss": "redigera dina egna CSS-filer",
        "action-editmyuserjson": "redigera dina egna JSON-filer",
        "action-editmyuserjs": "redigera dina egna JavaScript-filer",
+       "action-editmyuserjsredirect": "redigera dina egna JavaScript-filer som är omdirigeringar",
        "action-viewsuppressed": "se sidversioner som dolts från alla användare",
        "action-hideuser": "blockera ett användarnamn och dölj det från allmänheten",
        "action-ipblock-exempt": "kringgå IP-blockeringar, autoblockeringar och IP-intervallsblockeringar",
        "specialmute-success": "Dina tystnadsinställningar har uppdateras. Se alla tystade användare i [[Special:Preferences|dina inställningarna]].",
        "specialmute-submit": "Bekräfta",
        "specialmute-label-mute-email": "Tysta e-post från denna användare",
-       "specialmute-header": "Välj dina tystnadsinställningar för {{BIDI:[[User:$1]]}}.",
+       "specialmute-header": "Välj dina tystnadsinställningar för användaren <b>{{BIDI:[[User:$1]]}}</b>.",
        "specialmute-error-invalid-user": "Det begärda användarnamnet kunde inte hittas.",
-       "specialmute-error-email-blacklist-disabled": "Att förhindra användare från att skicka e-post till dig har inte aktiverats.",
-       "specialmute-error-email-preferences": "Du måste bekräfta din e-postadress innan du kan tysta en användare. Du kan göra det i [[Special:Preferences|inställningarna]].",
-       "specialmute-email-footer": "För att hantera e-postinställningar för {{BIDI:$2}}, besök <$1>.",
+       "specialmute-error-no-options": "Tystnadsfunktioner är inte tillgängliga. Detta kan bero på att: du inte har bekräftat din e-postadress eller wikiadministratören har inaktiverat e-postfunktioner och/eller svartlistan för e-post på denna wiki.",
+       "specialmute-email-footer": "För att hantera e-postinställningar för användaren {{BIDI:$2}}, besök <$1>.",
        "specialmute-login-required": "Logga in för att ändra dina tystnadsinställningar.",
+       "mute-preferences": "Tystnadsinställningar",
        "revid": "sidversion $1",
        "pageid": "sid-ID $1",
        "interfaceadmin-info": "$1\n\nBehörigheter för att redigera CSS/JS/JSON-filer för hela webbplatsen separerades nyligen från rättigheten <code>editinterface</code>. Om du inte förstår varför du får detta felmeddelande, se [[mw:MediaWiki_1.32/interface-admin]].",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Lösenordet kan inte vara med i listan över de 100 000 vanligaste lösenorden.",
        "passwordpolicies-policyflag-forcechange": "måste ändras vid inloggning",
        "passwordpolicies-policyflag-suggestchangeonlogin": "föreslå ändring vid inloggning",
+       "mycustomjsredirectprotected": "Du har inte behörighet att redigera denna JavaScript-sida eftersom det är en omdirigering och leder inte någonstans inom din användarnamnrymd.",
        "easydeflate-invaliddeflate": "Innehåll som tillhandahålls är inte helt komprimerat",
        "unprotected-js": "Av säkerhetsskäl kan inte JavaScript läsas in från oskyddade sidor. Skapa endast JavaScript i namnrymden MediaWiki: eller som en användarundersida.",
        "userlogout-continue": "Vill du logga ut?"
index 99cfe94..cb1929a 100644 (file)
        "history": "పేజీ చరిత్ర",
        "history_short": "చరిత్ర",
        "history_small": "చరిత్ర",
-       "updatedmarker": "à°¨à±\87à°¨à±\81 à°\95à°¿à°\82à°¦à°\9fిసారి à°µà°\9aà±\8dà°\9aిన తరువాత జరిగిన మార్పులు",
+       "updatedmarker": "à°®à±\80à°°à±\81 à°\95à°¿à°\82à°¦à°\9fిసారి à°µà°\9aà±\8dà°\9aà°¿ à°µà±\86à°³à±\8dà°³ిన తరువాత జరిగిన మార్పులు",
        "printableversion": "అచ్చుతీయదగ్గ కూర్పు",
        "permalink": "శాశ్వత లంకె",
        "print": "ముద్రించు",
        "defaultmessagetext": "అప్రమేయ సందేశపు పాఠ్యం",
        "content-failed-to-parse": "$1 మోడల్ కొరకు $2 పాఠ్యాన్ని పార్స్ చెయ్యలేకపోయాం: $3",
        "invalid-content-data": "చెల్లని కంటెంటు డేటా",
-       "content-not-allowed-here": "[[:$2]] పేజీలో పాఠ్యం \"$1\" కి అనుమతి లేదు",
+       "content-not-allowed-here": "స్లాట్ \"$3\" లో [[:$2]] పేజీలో పాఠ్యం \"$1\" కి అనుమతి లేదు",
        "editwarning-warning": "ఈ పేజీని వదిలివెళ్ళడం వల్ల మీరు చేసిన మార్పులను కోల్పోయే అవకాశం ఉంది.\nమీరు లాగిన్ అయివుంటే, ఈ హెచ్చరికని మీ అభిరుచులలోని \"{{int:prefs-editing}}\"  విభాగంలో అచేతనం చేసుకోవచ్చు.",
        "editpage-notsupportedcontentformat-title": "పాఠ్యపు ఆకృతికి మద్దతు లేదు",
        "editpage-notsupportedcontentformat-text": "$2 పాఠ్యపు మోడల్, పాఠ్యపు ఆకృతి $1 కి మద్దతు ఇవ్వదు",
        "right-reupload-own": "తానే ఇదివరలో అప్‌లోడు చేసిన ఫైలును తిరగరాయి",
        "right-reupload-shared": "స్థానికంగా ఉమ్మడి మీడియా సొరుగులోని ఫైళ్ళను అధిక్రమించు",
        "right-upload_by_url": "URL అడ్రసునుండి ఫైలును అప్‌లోడు చెయ్యడం",
-       "right-purge": "పేజీకి సంబంధించిన సైటు కాషెను, నిర్ధారణ కోరకుండానే తొలగించు",
+       "right-purge": "పేజీకి సంబంధించిన సైటు కాషెను తొలగించు",
        "right-autoconfirmed": "ఐపీ ఆధారిత రేటు పరిమితులు ప్రభావం చూపవు",
        "right-bot": "ఆటోమాటిక్ ప్రాసెస్ లాగా భావించబడు",
        "right-nominornewtalk": "చర్చా పేజీల్లో చేసే చిన్న మార్పులకు కొత్తసందేశపు సూచన పంపకూడదు",
        "grant-delete": "పేజీలు, కూర్పులు, లాగ్ ఎంట్రీల తొలగింపు",
        "grant-editinterface": "MediaWiki పేరుబరిలోను, సైటువ్యాప్త/వాడుకరి JSON కూ దిద్దుబాట్లు చెయ్యడం",
        "grant-editmycssjs": "మీ వాడుకరి CSS/JSON/JavaScript దిద్దడం",
-       "grant-editmyoptions": "మీ అభిరుచుల దిద్దుబాటు",
+       "grant-editmyoptions": "మీ అభిరుచులను, JSON కాన్ఫిగరేషన్నూ మార్చుకోండి",
        "grant-editmywatchlist": "మీ వీక్షణజాబితా దిద్దుబాటు",
        "grant-editsiteconfig": "సైటువ్యాప్త/వాడుకరి CSS/JS దిద్దడం",
        "grant-editpage": "ఉనికిలో ఉన్న పేజీల దిద్దుబాటు",
        "rcfilters-savedqueries-already-saved": "ఈ వడపోతలను ఈసరికే భద్రపరచారు. కొత్త వడపోతను సృష్టించేందుకు సెట్టింగులను మార్చండి.",
        "rcfilters-restore-default-filters": "డిఫాల్టు వడపోతకాలను పునఃస్థాపించు",
        "rcfilters-clear-all-filters": "వడపోతకాలన్నింటినీ తుడిచెయ్యి",
-       "rcfilters-show-new-changes": "సరికొత్త మార్పులను చూడండి",
+       "rcfilters-show-new-changes": "$1 నుండి జరిగిన సరికొత్త మార్పులను చూడండి",
        "rcfilters-search-placeholder": "మార్పులను వడకట్టండి (మెనూను వాడండి లేదా వడపోత పేరు కోసం వెతకండి)",
        "rcfilters-invalid-filter": "తప్పు వడపోతకం",
        "rcfilters-empty-filter": "చేతనంగా ఉన్న వడపోతకాలేమీ లేవు. మార్పుచేర్పు లన్నిటినీ చూపించాం.",
index 004e9bc..b016fc5 100644 (file)
@@ -24,6 +24,7 @@
        "tog-hideminor": "Пӯшидани вироишоти ҷузъи дар тағйироти охирин",
        "tog-hidepatrolled": "Пинҳон кардани вироишҳои гаштхӯрда дар тағйироти охир",
        "tog-newpageshidepatrolled": "Пинҳони саҳифаҳои гаштхӯрда аз феҳристи саҳифаҳои нав",
+       "tog-hidecategorization": "Пинҳон кардани гурӯҳбандии саҳифаҳо",
        "tog-extendwatchlist": "Густариши феҳристи пайгириҳо барои нишон додани ҳамаи тағйирот, на танҳо аз ҳама охирин",
        "tog-usenewrc": "Гурӯҳбандии тағийрот бар пояи сафҳа дар тағийроти охир ва феҳристи пайгириҳо",
        "tog-numberheadings": "шуморагузори~и худкори инвонҳо",
@@ -41,9 +42,9 @@
        "tog-enotifminoredits": "Барои тағийроти ҷузъӣ дар сафҳаҳо ва парвандаҳо ҳам ба ман номае фиристода шавад",
        "tog-enotifrevealaddr": "Нишонаи почтаи электронии ман дар номаҳои иттилорасонӣ қайд шавад",
        "tog-shownumberswatching": "Нишон додани шумораи корбарони пайгир",
-       "tog-oldsig": "Имзои вуҷуддошта:",
+       "tog-oldsig": "Имзои вуҷуддоштаи шумо:",
        "tog-fancysig": "Имзоро ба сурати викиматн ба назар бигир (бе пайванди худкор)",
-       "tog-uselivepreview": "Истифода аз пешнамоиши зинда(озмоишӣ)",
+       "tog-uselivepreview": "Истифода аз пешнамоиши зинда",
        "tog-forceeditsummary": "Ҳангоме ки хулосаи вироиш нанавиштаам юа ман ислоҳ бидеҳ",
        "tog-watchlisthideown": "Пинҳон намудани вироишҳои ман дар феҳристи назарот",
        "tog-watchlisthidebots": "Пинҳон намудани вироишҳои бот дар феҳристи назарот",
        "october-gen": "октябри",
        "november-gen": "ноябри",
        "december-gen": "декабри",
-       "jan": "Ян",
+       "jan": "Янв",
        "feb": "Фев",
        "mar": "Мар",
        "apr": "Апр",
        "aug": "Авг",
        "sep": "Сент",
        "oct": "Окт",
-       "nov": "Нов",
+       "nov": "Ноя",
        "dec": "Дек",
        "january-date": "$1 январ",
        "february-date": "$1 феврал",
        "returnto": "Бозгашт ба $1.",
        "tagline": "Аз {{SITENAME}}",
        "help": "Роҳнамо",
+       "help-mediawiki": "Дар бораи Медиавики",
        "search": "Ҷустуҷӯ",
        "searchbutton": "Ҷустуҷӯ",
        "go": "Рав",
        "searcharticle": "Бирав",
        "history": "Таърих",
        "history_short": "Таърих",
+       "history_small": "таърих",
        "updatedmarker": "барӯзшуда аз рӯзи охирин ташрифам",
        "printableversion": "Нусхаи чопӣ",
        "permalink": "Пайванди доимӣ",
        "redirectedfrom": "(Тағйири масир аз $1)",
        "redirectpagesub": "Саҳифаи равонакунӣ",
        "redirectto": "Тағйири масир ба:",
-       "lastmodifiedat": "Ин саҳифа бори охир $2, $1 дигаргун карда шудааст.",
+       "lastmodifiedat": "Ин саҳифапо бори охир дар $1, $2 вироиш карда буданд.",
        "viewcount": "Ин саҳифа {{PLURAL:$1|бор|$1 бор}} дида шудааст.",
        "protectedpage": "Саҳифаи муҳофизатшуда",
        "jumpto": "Ҷаҳиш ба:",
        "copyright": "Муҳтаво таҳти иҷозатномаи $1 ва ё дигар дастрас аст.",
        "copyrightpage": "{{ns:project}}:Copyrights",
        "currentevents": "Рӯйдодҳои кунунӣ",
-       "currentevents-url": "Лоиҳа:Рӯйдодҳои кунунӣ",
+       "currentevents-url": "Project:Рӯйдодҳои кунунӣ",
        "disclaimers": "Такзибнома",
-       "disclaimerpage": "Википедия:Такзибномаи умумӣ",
+       "disclaimerpage": "Project:Такзибномаи умумӣ",
        "edithelp": "Роҳнамои вироиш",
+       "helppage-top-gethelp": "Кӯмак",
        "mainpage": "Саҳифаи аслӣ",
        "mainpage-description": "Саҳифаи аслӣ",
        "policy-url": "Project:Сиёсатҳо",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "retrievedfrom": "Баргирифта аз \"$1\"",
        "youhavenewmessages": "Шумо $1 ($2) доред.",
+       "newmessageslinkplural": "{{PLURAL:$1|паёми|паёмҳои}} нав",
        "youhavenewmessagesmulti": "Шумо номаҳои нав дар $1 доред.",
        "editsection": "вироиш",
        "editold": "вироиш",
        "hidetoc": "Пинҳон кардани",
        "collapsible-collapse": "Фурукаш",
        "collapsible-expand": "Густариш",
+       "confirmable-confirm": "Шумо {{GENDER:$1|боварӣ}} доред?",
+       "confirmable-yes": "Бале",
+       "confirmable-no": "Не",
        "thisisdeleted": "Намоиш ё эҳёи $1?",
        "viewdeleted": "Намоиши $1?",
        "restorelink": "{{PLURAL:$1|вироиши ҳазфшуда|$1 вироишоти ҳазфшудаҳо}}",
        "site-atom-feed": "Барои $1 Atom Хабархон",
        "page-rss-feed": "Барои \"$1\" RSS Хабархон",
        "page-atom-feed": "Барои \"$1\" Atom Хабархон",
+       "feed-atom": "Атом",
        "red-link-title": "$1 (саҳифа вуҷуд надорад)",
        "nstab-main": "Мақола",
        "nstab-user": "Саҳифаи корбар",
        "createacct-yourpasswordagain-ph": "Гузарвожаро бори дигар ворид кунед",
        "userlogin-remembermypassword": "Вурудшуда манро нигоҳ дор",
        "userlogin-signwithsecure": "Истифодаи пайвастшавии амн",
+       "cannotlogin-title": "Наметавонед дохил шавед",
        "yourdomainname": "Домейни Шумо",
        "password-change-forbidden": "Шумо гузарвожаро дар ин вики тағийр дода наметавонед.",
        "externaldberror": "Хатое дар иртибот бо пойгоҳи дода рух дода аст ё ин ки шумо иҷозат ба рӯзрасонии ҳисоби берунии худро надоред.",
        "loginlanguagelabel": "Забон: $1",
        "pt-login": "Вуруд",
        "pt-login-button": "Вуруд",
+       "pt-login-continue-button": "Идомаи вуруд",
        "pt-createaccount": "Эҷоди ҳисоб",
        "pt-userlogout": "Хуруҷ",
        "changepassword": "Иваз намудани калимаи убур",
        "retypenew": "Калимаи нави убурро такроран нависед:",
        "resetpass_submit": "Калимаи убурро танзим карда ба систем вуруд кунед",
        "changepassword-success": "Гузарвожаи шумо бо муваффақият тағйир дода шуд!",
+       "botpasswords-label-appid": "Номи бот:",
+       "botpasswords-label-create": "Эҷод",
+       "botpasswords-label-update": "Азнав бор кардан",
        "botpasswords-label-cancel": "Пӯшидан",
+       "botpasswords-label-delete": "Ҳазф намудан",
        "resetpass_forbidden": "Гузарвожаҳоро наметавон тағйир дод",
        "resetpass-no-info": "Барои дастрасии мустақим ба ин саҳифа шумо бояд ба систем ворид шуда бошед.",
        "resetpass-submit-loggedin": "Тағйири гузарвожа",
        "headline_tip": "Унвони сатҳи 2",
        "nowiki_sample": "Инҷо матни қолаббанди-нашударо дохил кунед",
        "nowiki_tip": "Рад кардани қолаббандии вики",
+       "image_sample": "Намуна.jpg",
        "image_tip": "Тасвири дохили матн",
+       "media_sample": "Намуна.ogg",
        "media_tip": "Пайванди парвандаи расона",
        "sig_tip": "Имзои Шумо бо мӯҳри сана",
        "hr_tip": "Хати уфуқӣ (сарфакорона истифода кунед)",
        "summary": "Хулоса:",
-       "subject": "Мавзӯъ/сарлавҳа:",
+       "subject": "Мавзӯъ:",
        "minoredit": "Ин вироиши хурд аст",
        "watchthis": "Назар кардани ин саҳифа",
        "savearticle": "Саҳифа захира шавад",
        "savechanges": "Захира кардан",
+       "publishpage": "Нашри саҳифа",
+       "publishchanges": "Нашри тағйирот",
+       "savearticle-start": "Захираи саҳифа...",
+       "savechanges-start": "Захираи тағйирот...",
+       "publishpage-start": "Нашри саҳифа...",
+       "publishchanges-start": "Нашри тағйирот...",
        "preview": "Пешнамоиш",
        "showpreview": "Пешнамоиш",
        "showdiff": "Намоиши тағйирот",
        "edit-gone-missing": "Наметавон саҳифаро барӯз кард.\nБа назар мерасад, ки ҳазв шуда бошад.",
        "edit-conflict": "Бархурди вироиш.",
        "edit-no-change": "Вироиши шумо нодида гирифта шуд, зеро тағйире дар матн дода нашуда буд.",
+       "postedit-confirmation-created": "Саҳифа эҷод шуд.",
+       "postedit-confirmation-restored": "Саҳифа барқарор кард шуд.",
        "postedit-confirmation-saved": "Вироиши шумо захира шуд.",
+       "postedit-confirmation-published": "Вироиши шумо нашр шуд.",
        "edit-already-exists": "Саҳифаи нав эҷод нашуд.\nҚаблан ин саҳифа вуҷуд дорад.",
        "defaultmessagetext": "Матни пайёми пешфарз",
+       "slot-name-main": "Асосӣ",
        "content-model-wikitext": "вики-матн",
        "content-model-text": "матни содда",
        "content-model-javascript": "ҶаваСкрипт",
+       "content-json-empty-object": "Ашёи холӣ",
        "post-expand-template-inclusion-warning": "<strong>Огоҳӣ:</strong> Шаблони дар баргирифта хеле калон аст. Баъзе аз шаблонҳо дар бар гирифта намешавад.",
        "post-expand-template-inclusion-category": "Саҳифаҳое ки дар он ҳаҷми шаблон беш аз ҳад аст",
        "post-expand-template-argument-warning": "<strong>Огоҳӣ:</strong> Ин саҳифа ҳаддиақал як шаблоне дорад, ки хосияти ҳаҷм калони васеъшавӣ дорад.\nИн хосият аз байр гирифта шуд.",
        "histfirst": "кӯҳнатарин",
        "histlast": "навтарин",
        "historysize": "({{PLURAL:$1|1 байт|$1 байт}})",
-       "historyempty": "(холӣ)",
+       "historyempty": "холӣ",
        "history-feed-title": "Таърихи вироишҳо",
        "history-feed-description": "Таърихи вироишҳои ин саҳифа дар вики",
        "history-feed-item-nocomment": "$1 дар $2",
        "revertmerge": "Вогардонии идғом",
        "mergelogpagetext": "Дар зер феҳристи идғоми охирини таърихи як саҳифаро ба дигар саҳифаро мебинед.",
        "history-title": "Таърихчаи вироишҳои \"$1\"",
+       "difference-title": "Фарқият байни намунаҳои \"$1\"",
+       "difference-title-multipage": "Фарқият байни саҳифаҳои \"$1\" ва \"$2\"",
        "difference-multipage": "(Тафовут байни саҳифаҳо)",
        "lineno": "Сатри $1:",
        "compareselectedversions": "Нусхаҳои интихобшударо муқоиса кунед",
        "editundo": "ботил",
        "diff-empty": "(бе тафовут)",
        "searchresults": "Натиҷаҳои ҷустуҷӯ",
+       "search-filter-title-prefix-reset": "Кофтани тамоми саҳифаҳо",
        "searchresults-title": "Натоиҷи ҷустуҷӯ барои \"$1\"",
        "titlematches": "Унвони саҳифа татбиқ мекунад",
        "textmatches": "Матни мақола татбиқ мекунад",
        "notextmatches": "Матни ҳеҷ мақолае рост намеояд",
        "prevn": "{{PLURAL:$1|$1-тои}} қаблӣ",
        "nextn": "{{PLURAL:$1|$1-тои}} навбатӣ",
+       "prev-page": "саҳифаи қаблӣ",
        "next-page": "саҳифаи навбатӣ",
        "prevn-title": "Қаблӣ $1 {{PLURAL:$1|натиҷа|натоиҷ}}",
        "nextn-title": "Баъдӣ $1 {{PLURAL:$1|натиҷа|натоиҷ}}",
        "search-interwiki-caption": "Лоиҳаҳои хоҳарӣ",
        "search-interwiki-default": "Натоиҷ аз $1:",
        "search-interwiki-more": "(бештар)",
+       "search-interwiki-more-results": "натиҷаи бештар",
        "search-relatedarticle": "Алоқаманд",
        "searchrelated": "алоқаманд",
        "searchall": "ҳама",
        "prefs-personal": "Додаҳои корбар",
        "prefs-rc": "Тағйироти охирин",
        "prefs-watchlist": "Феҳристи пайгириҳо",
+       "prefs-editwatchlist": "Вироиши феҳристи пайгириҳо",
        "prefs-watchlist-days": "Теъдоди рӯзҳое ки бояд дар феҳристи пайгириҳои намоиш дода шавад:",
        "prefs-watchlist-edits": "Теъдоди вироишҳои нишондода дар феҳристи пайгириҳои густаришёфта:",
        "prefs-misc": "Танзимоти ҳархела",
        "prefs-namespaces": "Фазоҳои ном",
        "default": "пешфарз",
        "prefs-files": "Файлҳо",
+       "prefs-custom-css": "CSS-и шахсӣ",
        "prefs-emailconfirm-label": "Тасдиқи почта:",
        "youremail": "Почтаи электронии Шумо:",
        "username": "{{GENDER:$1|Номи корбар}}:",
        "prefs-help-realname": "Номи ҳақиқӣ ихтиёрӣ ва агар шумо онро пешниҳод кунед онро ҳамчун муаллифи эҷодиётатон ёдоварӣ карда хоҳад шуд.",
        "prefs-help-email": "Нишонаи электронӣ ихтиёрист, аммо фиристодани гузарвожаи навро агар гузарвожаи худро фаромӯш кунед мумкин мегардад.",
        "prefs-help-email-required": "Нишони почтаи электрони лозим аст.",
+       "prefs-info": "Маълумоти асосӣ",
        "prefs-i18n": "Байналмиллаликунӣ",
        "prefs-signature": "Имзо",
+       "prefs-dateformat": "Намуди сана",
+       "prefs-timeoffset": "Замони ҷуброн",
+       "prefs-advancedediting": "Гузинаҳои умумӣ",
+       "prefs-developertools": "Абзорҳои барноманависӣ",
        "prefs-editor": "Вироишгар",
        "prefs-preview": "Пешнамоиш",
        "prefs-advancedrc": "Ихтиёроти пешрафта",
        "prefs-advancedwatchlist": "Ихтиёроти пешрафта",
        "prefs-displayrc": "Ихтиёроти намоиш",
        "prefs-displaywatchlist": "Ихтиёроти намоиш",
+       "prefs-changesrc": "Тағйирот нишон дода шудааст",
+       "prefs-changeswatchlist": "Тағйирот нишон дода шудааст",
+       "prefs-pageswatchlist": "Саҳифаҳои зери назар",
        "prefs-tokenwatchlist": "Рамз",
        "prefs-diffs": "Тафовут",
        "userrights": "Мудирияти ихтиёроти корбарӣ",
        "right-userrights": "Вироиши ҳамаи ихтиёроти корбарон",
        "right-userrights-interwiki": "Вироиши ихтиёроти корбарии корбарони дигар викиҳо",
        "right-siteadmin": "Бастн ва боз кардани пойгоҳи дода",
+       "grant-group-email": "фиристодани имайл",
+       "grant-createaccount": "Эҷоди ҳисобҳо",
+       "grant-createeditmovepage": "Эҷод, кучониш ва вироиши саҳифаҳо",
        "grant-rollback": "Вогардонидани тағйироти саҳифа",
+       "grant-basic": "Ҳуқуқҳот асосӣ",
        "newuserlogpage": "Гузориши эҷоди корбар",
        "newuserlogpagetext": "Ин гузориш аз номҳои корбарии тозасохташуда аст.",
        "rightslog": "Гузориши ихтиёроти корбар",
        "action-undelete": "барқарор кардани ин саҳифа",
        "action-rollback": "вогардонии зуди тағйирот",
        "action-sendemail": "фиристодани пайёмҳо",
+       "action-override-export-depth": "Нишон додан",
        "nchanges": "$1 {{PLURAL:$1|тағйир|тағйирот}}",
        "enhancedrc-history": "таърих",
        "recentchanges": "Тағйироти охирин",
        "recentchanges-label-unpatrolled": "Ин вироиш ҳанӯз гаштзанӣ нашудааст",
        "recentchanges-label-plusminus": "Ҳаҷми саҳифа ба андозаи ин миқдор байт тағйир ёфтааст",
        "recentchanges-legend-heading": "Ихтисораҳо:",
+       "recentchanges-submit": "Нишон додан",
+       "rcfilters-tag-remove": "'$1'ро ҳазф намудан",
+       "rcfilters-legend-heading": "<strong>Феҳристи ихтисорот:</strong>",
+       "rcfilters-other-review-tools": "Дигар асбобҳои сайр",
+       "rcfilters-activefilters-hide": "Пинҳон намудан",
+       "rcfilters-activefilters-show": "Нишон додан",
+       "rcfilters-days-title": "Рӯзҳои охир",
+       "rcfilters-hours-title": "Соатҳои охир",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|рӯз}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|соат }}",
+       "rcfilters-savedqueries-rename": "Тағйири ном",
+       "rcfilters-savedqueries-setdefault": "Ба таври пешфарз мондан",
+       "rcfilters-savedqueries-remove": "Ҳазф намудан",
+       "rcfilters-savedqueries-new-name-label": "Ном",
        "rcfilters-savedqueries-cancel-label": "Лағв",
+       "rcfilters-filter-editsbyself-label": "Тағйироти шумо",
+       "rcfilters-filter-editsbyself-description": "Вироишоти шумо.",
+       "rcfilters-filter-editsbyother-label": "Тағйироти дигарон",
+       "rcfilters-filter-editsbyother-description": "Тамоми тағйирот ба ғайри тағйироти шумо",
+       "rcfilters-filter-user-experience-level-registered-label": "Сабтиномшуда",
+       "rcfilters-filter-user-experience-level-registered-description": "Вироишгарони сабтиномшуда",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Сабтиномнашуда",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Вироишгароне, ки сабтином накардаанд.",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Навкорон",
+       "rcfilters-filter-user-experience-level-newcomer-description": "Вироишгарони сабтиномшудае, ки дар 4 рӯзи фаъолияташон 10 вироиш доранд.",
+       "rcfilters-filter-user-experience-level-learner-label": "Омӯзишгирандагон",
+       "rcfilters-filter-user-experience-level-learner-description": "Вироишгарони сабтиномшудае, ки дар байни Навкорон ва Корбарони Таҷрибадор қарор доранд.",
+       "rcfilters-filter-user-experience-level-experienced-label": "Корбарони таҷрибадор",
+       "rcfilters-filter-user-experience-level-experienced-description": "Вироишгарони сабтиномшудае, ки дар тӯли 30 рӯзи фаъолияташон беш аз 500 вироиш намудаанд.",
+       "rcfilters-filtergroup-automated": "Саҳмҳои автоматикӣ",
+       "rcfilters-filter-bots-label": "Бот",
+       "rcfilters-filter-bots-description": "Вироишоте, ки бо асбобҳои автоматикӣ карда шудаанд.",
+       "rcfilters-filter-humans-label": "Инсон (на бот)",
+       "rcfilters-filter-humans-description": "Вироишот аз тарафи вироишгар-инсон.",
+       "rcfilters-filtergroup-reviewstatus": "Вазъиятро баррасӣ намудан",
+       "rcfilters-filter-reviewstatus-unpatrolled-description": "Вироишот ба таври дасти ва ё худкор чун тафтишшуда ҳисоб шавад.",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "Баррасинашуда",
+       "rcfilters-filter-reviewstatus-manual-description": "Вироишоте, ки ба таври дастӣ баррасӣ шуданд.",
+       "rcfilters-filter-reviewstatus-manual-label": "Баррасӣ ба таври дастӣ",
+       "rcfilters-filter-reviewstatus-auto-description": "Вироишоти корбарони пешрафта, ки ба таври худкор чун баррасӣ шуда қайд мешавад.",
+       "rcfilters-filter-reviewstatus-auto-label": "Ба таври худкор баррасӣ шуда",
+       "rcfilters-filtergroup-significance": "Аҳамиятнокӣ",
+       "rcfilters-filter-minor-label": "Вироишоти начандон аҳамиятнок",
+       "rcfilters-filter-minor-description": "Нависандаро ба унвони ҷузъӣ ёдовар мекунад.",
+       "rcfilters-filter-major-label": "Вироишоти ғайриҷузъӣ",
+       "rcfilters-filter-major-description": "Вироишоте, ки ғайриҷузъиянд.",
+       "rcfilters-filtergroup-watchlist": "Феҳристи пайгириҳо",
+       "rcfilters-filter-watchlist-watched-label": "Дар феҳристи пайгириҳо",
+       "rcfilters-filter-watchlist-watched-description": "Тағйири саҳифаҳо дар феҳристи пайгириҳо.",
+       "rcfilters-filtergroup-changetype": "Намуди тағйирот",
+       "rcfilters-filter-pageedits-label": "Вироишоти саҳифа",
        "rcnotefrom": "Дар зер тағйиротҳои охирин аз <b>$2</b> (то <b>$1</b> нишон дода шудааст).",
        "rclistfrom": "Нишон додани тағйиротҳои нав сар карда аз $3 $2",
        "rcshowhideminor": "$1 вироишҳои хурд",
        "rcshowhidemine": "$1 вироишҳои ман",
        "rcshowhidemine-show": "Намоиш",
        "rcshowhidemine-hide": "Пинҳон кардани",
+       "rcshowhidecategorization-show": "Нишон додан",
+       "rcshowhidecategorization-hide": "Пинҳон намудан",
        "rclinks": "Нишон додани $1 тағйироти охирин дар $2 рӯзи охир",
        "diff": "фарқият",
        "hist": "таърих",
        "upload-file-error-text": "Ҳангоми талош барои эчоди як парвандаи муваққатӣ дар коргузор, як хатои дохилӣ рух дод. Лутфан бо мудири систем тамос бигиред.",
        "upload-misc-error": "Хатои номаълум дар боргузорӣ",
        "upload-misc-error-text": "Ҳангоми боргузорӣ, хатои номаълуме рух дод.  Лутфан итминнон ҳосил кунед, ки нишонаи URL мӯътабар ва қобили дастрасӣ аст, ва баъд дубора талош кунед. Агар мушкили пофишорӣ кунад, бо яке аз мудирони систем  тамос бигиред.",
+       "upload-dialog-title": "Фиристодани файл",
+       "upload-dialog-button-cancel": "Тамом кардан",
+       "upload-dialog-button-back": "Бозгашт",
+       "upload-dialog-button-done": "Карда шуд",
+       "upload-dialog-button-save": "Захира кардан",
+       "upload-dialog-button-upload": "Боркунӣ",
+       "upload-form-label-infoform-title": "Деталҳо",
+       "upload-form-label-infoform-name": "Ном",
+       "upload-form-label-infoform-description": "Тавзеҳот",
+       "upload-form-label-usage-title": "Истифодабарӣ",
+       "upload-form-label-usage-filename": "Номи файл",
+       "upload-form-label-own-work": "Ин кори ман аст",
        "upload-form-label-infoform-categories": "Гурӯҳҳо",
+       "upload-form-label-infoform-date": "Сана",
        "backend-fail-opentemp": "Парвандаи муваққатӣ боз нашуд.",
        "backend-fail-writetemp": "Ба парвандаи муваққатӣ сабт нашуд.",
        "backend-fail-closetemp": "Парвандаи муваққатиро пӯшида нашуд.",
        "license-nopreview": "(Пешнамоиш вуҷуд надорад)",
        "upload_source_url": "(як нишони интернетии мӯътабар ва оммавӣ)",
        "upload_source_file": " (парвандае дар компютери шумо)",
+       "listfiles-delete": "ҳазф",
        "listfiles-summary": "Ин саҳифаи вижа тамоми парвандаҳои боргузоришударо нишон медиҳад.\nБа таври пешфарз охирин парвандаҳои боргузоришуда дар болои феҳрист нишон дода шудаанд.\nЯк клик кардани рӯи унвони сутунҳо боиси тағйири тартиби намоиши парвандаҳо мешавад.",
        "listfiles_search_for": "Ҷустуҷӯи номи акс:",
        "imgfile": "парванда",
        "mostimages": "Аксҳое ки бештар аз ҳама бо онҳо пайванд шудааст",
        "mostrevisions": "Саҳифахое, ки аз ҳама бештар вироиш шудаанд",
        "prefixindex": "Ҳамаи саҳифаҳо бо пешванд",
+       "prefixindex-submit": "Намоиш",
        "shortpages": "Саҳифаҳои кӯтоҳ",
        "longpages": "Саҳифаҳои калон",
        "deadendpages": "Саҳифаҳои бемаъно",
        "deadendpagestext": "Саҳифаҳои зерин ба ҳеҷ дигар саҳифае дар {{SITENAME}} пайванд нестанд.",
        "protectedpages": "Саҳифаҳои ҳифзшуда",
+       "protectedpages-filters": "Филтрҳо:",
        "protectedpages-indef": "Фақат ҳифзшудаҳои номуайян",
        "protectedpages-noredirect": "Пинҳони саҳифаҳои равонакунӣ",
        "protectedpagesempty": "Дар ҳоли ҳозир ҳеҷ саҳифае муҳофизат нашудааст.",
        "listusers": "Рӯйхати корбарон",
        "usercreated": "{{GENDER:$3|Эҷодшуда}} дар таърихи $1 дар соати $2",
        "newpages": "Саҳифаҳои нав",
+       "newpages-submit": "Намоиш",
        "newpages-username": "Номи корбар:",
        "ancientpages": "Саҳифаҳои кӯҳнатарин",
        "move": "Кӯчонидан",
        "pager-newer-n": "{{PLURAL:$1|1-тои навтар|$1-тои навтар}}",
        "pager-older-n": "{{PLURAL:$1|1-тои кӯҳнатар|$1-тои кӯҳнатар}}",
        "suppress": "Назорат",
+       "apisandbox": "Регдони API",
+       "apisandbox-add-multi": "Илова кардан",
+       "apisandbox-results": "Натиҷаҳо",
        "booksources": "Манбаҳои китобҳо",
        "booksources-search-legend": "Ҷустуҷӯи сарчашмаҳои китоб",
        "booksources-search": "Ҷустуҷӯ",
        "specialloguserlabel": "Иҷрокунанда:",
        "speciallogtitlelabel": "Ҳадаф (унвон ё корбар):",
        "log": "Гузоришҳо",
+       "logeventslist-submit": "Намоиш",
        "all-logs-page": "Ҳамаи сабтҳои умумӣ",
        "alllogstext": "Намоиши ҳамаи гузоришҳои дастраси якҷояи дастраси {{SITENAME}}. Метавонед бо интихоби навъи гузориш, номи корбарӣ ва саҳифаҳои тағйирёфта, намоишро маҳдудтар созед.",
        "logempty": "Мавриди мутобиқ ба манзури шумо дар гузориш пайдо нашуд.",
        "log-title-wildcard": "Саҳифаҳоеро ҷустуҷӯ кунед, ки унвонашон бо ин матн оғоз мешаванд",
+       "checkbox-all": "Ҳама",
        "allpages": "Ҳамаи саҳифаҳо",
        "nextpage": "Саҳифаи навбатӣ ($1)",
        "prevpage": "Саҳифаи пешина ($1)",
        "unwatchthispage": "Тавқифи пайгирии ин саҳифа",
        "notanarticle": "Мақола нест",
        "notvisiblerev": "Нусха ҳазф шуд",
-       "watchlist-details": "{{PLURAL:$1|$1 саҳифа|$1 саҳифаҳо}} дар феҳристи пайгириҳои шумо, бидуни ҳисоби саҳифаҳои баҳс.",
+       "watchlist-details": "{{PLURAL:$1|$1 саҳифа}} дар феҳристи назароти шумо (бо саҳафоти баҳс).",
        "wlheader-enotif": "Иттилоорасонии тариқи почтаи электронӣ (E-mail) фаъол шудааст.",
        "wlheader-showupdated": "Саҳифаҳое, ки пас аз охирин сар заданатон ба онҳо тағйир кардаанд '''пурранг''' нишон дода шудаанд",
        "wlnote": "Дар зер {{PLURAL:$1|охирин тағйир|'''$1''' охирин тағйирот}} дар $2 соати охир {{PLURAL:омадааст|омадаанд}}.",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|нусха|нусха}} аз $2",
        "tooltip-pt-userpage": "Саҳифаи корбарии шумо",
        "tooltip-pt-anonuserpage": "Саҳифаи корбари IP, ки бо он шумо вироиш мекунед",
-       "tooltip-pt-mytalk": "Саҳифаи баҳси шумо",
+       "tooltip-pt-mytalk": "Саҳифаи баҳси {{GENDER:|Шумо}}",
        "tooltip-pt-anontalk": "Баҳси пиромуни вироишҳо аз ин нишонаи IP",
-       "tooltip-pt-preferences": "Тарҷиҳоти ман",
+       "tooltip-pt-preferences": "Тарҷиҳот {{GENDER:|Шумо}}",
        "tooltip-pt-watchlist": "Рӯйхати саҳифаҳое, ки тағйиротҳояшонро Шумо назорат мекунед",
-       "tooltip-pt-mycontris": "Феҳристи ҳиссагузориҳои шумо",
+       "tooltip-pt-mycontris": "Феҳристи ҳиссагузориҳои {{GENDER:|Шумо}}",
        "tooltip-pt-login": "Тавсия мешавад ки ба система ворид шавед, лекин маҷбурӣ нест.",
        "tooltip-pt-logout": "Хуруҷ аз систем",
        "tooltip-ca-talk": "Баҳси матни таркибии ин саҳифа",
-       "tooltip-ca-edit": "ШÑ\83мо Ð¸Ð½ Ñ\81аҳиÑ\84аÑ\80о Ð²Ð¸Ñ\80оиÑ\88 ÐºÐ°Ñ\80да Ð¼ÐµÑ\82авонед. Ð\9fеÑ\88 Ð°Ð· Ð·Ð°Ñ\85иÑ\80а ÐºÐ°Ñ\80дани Ñ\81аҳиÑ\84а Ð¿ÐµÑ\88намоиÑ\88Ñ\80о Ð¸Ñ\81Ñ\82иÑ\84ода Ð±Ð°Ñ\80ед.",
+       "tooltip-ca-edit": "Ð\92иÑ\80оиÑ\88и Ð¸Ð½ Ñ\81аҳиÑ\84а",
        "tooltip-ca-addsection": "Илова кардани бахши ҷадид",
        "tooltip-ca-viewsource": "Ин саҳифа ҳифз карда шудааст. Шумо танҳо таркиби онро дида метавонед.",
        "tooltip-ca-history": "Нусхаи охирини ин саҳифа.",
        "pageinfo-content-model": "Навъи таркибии саҳифа",
        "pageinfo-redirects-name": "Шумораи равонакуниҳо ба ин саҳифа",
        "pageinfo-redirects-value": "$1-то",
+       "pageinfo-hidden-categories": "Пинҳон {{PLURAL:$1|гурӯҳ|гурӯҳҳо}} ($1)",
        "pageinfo-toolboxlink": "Иттилооти саҳифа",
        "pageinfo-contentpage-yes": "Бале",
        "pageinfo-protect-cascading-yes": "Бале",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|саҳифа|саҳифаҳо}}",
        "file-info": "андозаи парванда: $1, навъи MIME: $2",
        "file-info-size": "$1 × $2 пиксел, ҳаҷми парванда: $3, навъи MIME: $4",
+       "file-info-size-pages": "$1 × $2 пиксел, андозаи файл: $3, навъи MIME: $4, $5 {{PLURAL:$5|саҳифа|саҳафот}}",
        "file-nohires": "Нусхаи ҳаҷман ва сифатан баландтар дастрас нест.",
        "svg-long-desc": "SVG парванда, исмӣ $1 × $2 пиксел, андозаи парванда: $3",
        "show-big-image": "Акси аслӣ",
        "watchlistedit-raw-done": "Феҳристи пайгириҳои шумо ба рӯз шуд.",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 унвон|$1 унвонҳо}} ба феҳристи пайгириҳо изофа шуд:",
        "watchlistedit-raw-removed": "Унвон ҳазф {{PLURAL:$1|шуд|шуданд}}:",
+       "watchlisttools-clear": "Тоза кардани феҳристи назарот",
        "watchlisttools-view": "Намоиши тағйироти алоқаманди феҳристи пайгириҳо",
        "watchlisttools-edit": "Мушоҳида ва вироиши феҳристи пайгириҳо",
        "watchlisttools-raw": "Вироиши феҳристи хоми пайгириҳо",
        "version-version": "($1)",
        "version-license": "Иҷозатномаи МедиаВики",
        "version-ext-colheader-license": "Иҷозатнома",
+       "version-ext-colheader-description": "Тавзеҳот",
        "version-ext-colheader-credits": "Муаллифон",
        "version-poweredby-others": "дигарон",
        "version-software": "Нусхаи насбшуда",
        "version-software-product": "Маҳсул",
        "version-software-version": "Нусха",
+       "version-libraries-description": "Тавзеҳот",
        "redirect-page": "Рамзи саҳифа",
        "fileduplicatesearch": "Ҷустуҷӯ барои парвандаҳои такрорӣ",
        "fileduplicatesearch-summary": "Ҷустуҷӯ барои парвандаҳои такрорӣ бар асоси миқдори дар ҳам шудаи онҳо сурат мегирад.",
        "specialpages-group-developer": "Абзорҳои тавсиядиҳандагон",
        "blankpage": "Саҳифаи холӣ",
        "tag-filter": "Филтри [[Special:Tags|барчасбҳо]]:",
+       "tags-description-header": "Тавзеҳоти пурраи маънияш",
        "tags-active-header": "Фаъол?",
        "tags-active-yes": "Бале",
        "tags-edit": "вироиш",
        "htmlform-selectorother-other": "Дигар",
        "htmlform-no": "На",
        "htmlform-yes": "Бале",
+       "logentry-delete-restore": "$1 саҳифаро $3 ($4) {{GENDER:$2|барқарор намуд}}",
        "revdelete-restricted": "маҳдудиятҳо ба мудирон амалӣ шуданд",
        "revdelete-unrestricted": "маҳдудиятҳо аз мудирон бардошта шуданд",
        "rightsnone": "(ҳеҷ)",
        "feedback-message": "Пайём:",
        "feedback-subject": "Мавзӯъ:",
        "feedback-submit": "Ирсол",
-       "searchsuggest-search": "Ҷустуҷӯ",
+       "searchsuggest-search": "Ҷустуҷӯ дар {{SITENAME}}",
        "expandtemplates": "Бастдодани шаблонҳо",
        "expand_templates_intro": "Ин саҳифаи вижа матнеро дарёфт карда ва тамоми шаблонҳои ба кор рафта дар онро ба таври бозгаште баст медиҳад. Ҳамчунин тобеҳои таҷзеҳ\n<nowiki>{{</nowiki>#language:...}}, ва мутағйирҳое чун\n<nowiki>{{</nowiki>CURRENTDAY}}&mdash;ро ҳам баст медиҳад – дар воқеъ тақрибан ҳар чиро ки дохили ду акулот бошад.\nИн кор бо садо задани марҳилаи таҷзеҳи марбут дар худи МедиаВики сурат мегирад.",
        "expand_templates_title": "Унвони мавзӯъ, барои {{FULLPAGENAME}} ва ғайра.:",
        "special-characters-group-cyrillic": "Сириллик",
        "randomrootpage": "Саҳифаи решавии тасодуфӣ",
        "changecredentials-submit": "Тағйири ҳисоби корбарӣ",
-       "removecredentials-submit": "Хориҷи эътиборнома"
+       "removecredentials-submit": "Хориҷи эътиборнома",
+       "specialmute-header": "Лутфан танзимоти хомӯши худро барои корбар <b>{{BIDI:[[Корбар:$1|$1]]}}</b> интихоб кунед."
 }
index 875bd82..1a93bad 100644 (file)
        "ipb-confirm": "ยืนยันการบล็อก",
        "ipb-sitewide": "ทั้งเว็บไซต์",
        "ipb-partial": "บางส่วน",
+       "ipb-partial-help": "ระบุหน้าหรือเนมสเปซ",
        "ipb-pages-label": "หน้า",
+       "ipb-namespaces-label": "เนมสเปซ",
        "badipaddress": "เลขที่อยู่ไอพีไม่ถูกต้อง",
        "blockipsuccesssub": "บล็อกสำเร็จ",
        "blockipsuccesstext": "บล็อก [[Special:Contributions/$1|$1]] แล้ว<br />\nดู[[Special:BlockList|รายการบล็อก]]เพื่อทบทวนการบล็อก",
        "blocklist-userblocks": "ซ่อนการบล็อกบัญชี",
        "blocklist-tempblocks": "ซ่อนการบล็อกชั่วคราว",
        "blocklist-addressblocks": "ซ่อนการบล็อกไอพีเดียว",
+       "blocklist-type": "ประเภท:",
+       "blocklist-type-opt-all": "ทั้งหมด",
+       "blocklist-type-opt-sitewide": "ทั้งเว็บไซต์",
+       "blocklist-type-opt-partial": "บางส่วน",
        "blocklist-rangeblocks": "ซ่อนการบล็อกช่วง",
        "blocklist-timestamp": "วัน-เวลา",
        "blocklist-target": "เป้าหมาย",
        "blocklist-editing-page": "หน้า",
        "blocklist-editing-ns": "เนมสเปซ",
        "ipblocklist-empty": "รายการบล็อกว่าง",
-       "ipblocklist-no-results": "à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีหรือà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88à¸\82อà¹\84มà¹\88à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81",
+       "ipblocklist-no-results": "à¹\84มà¹\88à¸\9eà¸\9aà¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีหรือà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88à¸\82อà¸\95รà¸\87",
        "blocklink": "บล็อก",
        "unblocklink": "ปลดบล็อก",
        "change-blocklink": "เปลี่ยนการบล็อก",
+       "empty-username": "(ไม่มีชื่อผู้ใช้)",
        "contribslink": "มีส่วนร่วม",
        "emaillink": "ส่งอีเมล",
        "autoblocker": "ถูกบล็อกอัตโนมัติเนื่องจาก \"[[User:$1|$1]]\" ใช้เลขที่อยู่ไอพีของคุณเมื่อเร็ว ๆ นี้\nเหตุผลที่ให้แก่การบล็อก $1 คือ: \"$2\"",
        "confirm-unwatch-top": "ลบหน้านี้ออกจากรายการเฝ้าดูของคุณ",
        "confirm-rollback-button": "ตกลง",
        "confirm-rollback-top": "ย้อนการแก้ไขหน้านี้หรือไม่",
+       "confirm-rollback-bottom": "ปฏิบัติการนี้จะย้อนการเปลี่ยนแปลงหน้านี้ที่เลือกรวดเดียวทันที",
        "confirm-mcrrestore-title": "กู้คืนรุ่นแก้ไข",
        "confirm-mcrundo-title": "ทำกลับการเปลี่ยนแปลง",
        "mcrundofailed": "ทำกลับล้มเหลว",
        "mediastatistics": "สถิติสื่อ",
        "mediastatistics-summary": "สถิติเกี่ยวกับประเภทไฟล์ที่อัปโหลด ซึ่งรวมเฉพาะรุ่นล่าสุดของไฟล์นั้น \nไม่รวมไฟล์รุ่นเก่าหรือที่ถูกลบแล้ว",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 ไบต์}} ($2; $3%)",
+       "mediastatistics-bytespertype": "ขนาดไฟล์ทั้งหมดสำหรับส่วนนี้: {{PLURAL:$1|$1 ไบต์}} ($2; $3%)",
+       "mediastatistics-allbytes": "ขนาดไฟล์ทั้งหมดของทุกไฟล์: {{PLURAL:$1|$1 ไบต์}} ($2)",
        "mediastatistics-table-count": "จำนวนไฟล์",
        "mediastatistics-table-totalbytes": "ขนาดรวม",
        "mediastatistics-header-unknown": "ไม่ทราบ",
        "mediastatistics-header-drawing": "ภาพวาดเส้น (ภาพเวกเตอร์)",
        "mediastatistics-header-audio": "เสียง",
        "mediastatistics-header-video": "วิดีทัศน์",
+       "mediastatistics-header-office": "สำนักงาน",
+       "mediastatistics-header-total": "ไฟล์ทั้งหมด",
        "json-error-depth": "ความลึกสแตกสูงสุดเกิน",
        "headline-anchor-title": "โยงมาส่วนนี้",
        "special-characters-group-latin": "ละติน",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "ห้ามรหัสผ่านตรงกับรหัสผ่านที่ขึ้นบัญชีดำโดยเจาะจง",
        "passwordpolicies-policy-maximalpasswordlength": "รหัสผ่านจะต้องมีความยาวน้อยกว่า $1 อักขระ",
        "passwordpolicies-policy-passwordcannotbepopular": "ห้ามรหัสผ่านเป็น{{PLURAL:$1|รหัสผ่านยอดนิยม|ติดรายการ $1 รหัสผ่านยอดนิยม}}",
-       "userlogout-continue": "หาà¸\81à¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\81ารออà¸\81à¸\88าà¸\81ระà¸\9aà¸\9a à¹\82à¸\9bรà¸\94[$1 à¸\94ำà¹\80à¸\99ิà¸\99à¸\81ารà¸\95à¹\88อà¹\84à¸\9bยัà¸\87หà¸\99à¹\89าออà¸\81à¸\88าà¸\81ระà¸\9aà¸\9a]"
+       "userlogout-continue": "à¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\81ารออà¸\81à¸\88าà¸\81ระà¸\9aà¸\9aหรือà¹\84มà¹\88"
 }
index d47c030..74c4512 100644 (file)
@@ -6,15 +6,17 @@
                        "Tuzkozbir",
                        "Гусейн",
                        "아라",
-                       "Baskervill"
+                       "Baskervill",
+                       "Eldarado",
+                       "Patriot Kur"
                ]
        },
-       "tog-underline": "Линки жинтоно ријә быкәш:",
+       "tog-underline": "Linki jintono rijə bıkəş:",
        "tog-hideminor": "Охоминә дәгишонәдә гәдә дәгишон нишо мәдә.",
        "tog-hidepatrolled": "Нујә дәгишон сијоһијәдә дәвинә кардә быә дәгишон нишо мәкә.",
        "tog-newpageshidepatrolled": "Нијони огәтеј ноғо доә быә сәһифон бә тожә сәһифон сијоһиәдә",
        "tog-usenewrc": "Охоминә дәгишон сәһифәдә ијән ноғо доә сијоһијәдә дәгишон бә дәстон ҹо кардеј (гәрәке JavaScript)",
-       "tog-numberheadings": "Ð\90вÑ\82омаÑ\82ик Ð±Ð°Ñ\88лÑ\8bÒ\93он Ð½Ñ\83мÑ\80Ó\99лÓ\99миÑ\88 Ð±Ñ\8bкÓ\99",
+       "tog-numberheadings": "Avtomatik baÅ\9flıÄ\9fon nümrÉ\99\99nmiÅ\9f bıkÉ\99",
        "tog-watchcreations": "Зијод кардеј чымы офәјә быә сәһифон ијән фајлон бә ноғо доә сијоһи",
        "tog-watchdefault": "Зијод кардеј демы дәгиш кардә быә сәһифон ијән фајлон бә ноғо доә сијоһи",
        "tog-watchmoves": "Зијод кардеј фајлон ијән ном дәгиш кардә быә сәһифон бә ноғо доә сијоһи",
        "tog-watchlisthideown": "Чымы дәгишон ноғо доә сијһиәдә нијо кардеј",
        "tog-watchlisthidebots": "Нијо кардеј ботон дәгишон ноғо доә сијоһиәдә",
        "tog-watchlisthideminor": "Нијо кардеј гәдә дәгишон ноғо доә сијоһиәдә",
-       "underline-always": "Һежо",
-       "sunday": "Ишамбә",
-       "monday": "Дышанбә",
-       "tuesday": "Сешанбә",
-       "wednesday": "Чошанбә",
+       "underline-always": "hejo",
+       "underline-never": "Hiç vaxt",
+       "sunday": "İşambə",
+       "monday": "Dışambə",
+       "tuesday": "Seşambə",
+       "wednesday": "Çoşambə",
        "thursday": "Ҹымә шәв",
        "friday": "Әjнә",
        "saturday": "Шанбә",
-       "sun": "Иша",
-       "mon": "Дыш",
-       "tue": "Сеш",
-       "wed": "Чош",
+       "sun": "İşa",
+       "mon": "Dış",
+       "tue": "Seş",
+       "wed": "Çoş",
        "thu": "Ҹым",
        "fri": "Әјн",
        "sat": "Шан",
        "october-gen": "Октјабрә манги",
        "november-gen": "Нојабрә манги",
        "december-gen": "Декабрә манги",
-       "jan": "Јан",
-       "feb": "Фев",
-       "mar": "Мар",
-       "apr": "Апр",
-       "may": "Мај",
-       "jun": "Ијун",
-       "jul": "Ијул",
-       "aug": "Авг",
-       "sep": "Сен",
-       "oct": "Окт",
-       "nov": "Ној",
-       "dec": "Дек",
-       "pagecategories": "{{PLURAL:$1|Категоријә|Категоријон}}",
+       "jan": "Yan",
+       "feb": "Fev",
+       "mar": "Mar",
+       "apr": "Apr",
+       "may": "May",
+       "jun": "İyo",
+       "jul": "İyol",
+       "aug": "Avğ",
+       "sep": "Sen",
+       "oct": "Okt",
+       "nov": "Noy",
+       "dec": "Dek",
+       "january-date": "Yanvar $1",
+       "february-date": "Fevral $1",
+       "march-date": "Mart $1",
+       "april-date": "Aprel $1",
+       "may-date": "May $1",
+       "june-date": "İyon $1",
+       "july-date": "İyol $1",
+       "august-date": "Avğost $1",
+       "september-date": "Sentyəbr $1",
+       "october-date": "Oktyəbr $1",
+       "november-date": "Noyəbr $1",
+       "december-date": "Dekabr $1",
+       "pagecategories": "{{PLURAL:$1|Kətiqoriyə|Kətiqoriyon}}",
        "category_header": "Сәһифон бы категоријәдә \"$1\"",
        "subcategories": "Категоријон жинтон",
        "category-media-header": "Медијә бы категоријәдә \"$1\"",
        "newwindow": "(нујә пенҹәдә окардеј)",
        "cancel": "Ләғв кардеј",
        "moredotdotdot": "Веј...",
-       "mypage": "СÓ\99һиÑ\84Ó\99",
-       "mytalk": "Мызокирон",
+       "mypage": "\99hifÉ\99",
+       "mytalk": "Müzokirə",
        "anontalk": "Бо ын IP-унвони мызокирә",
        "navigation": "Navigasiyə",
        "and": "&#32;ијән",
        "faq": "РАП",
-       "actions": "Һәрәкәтон",
+       "actions": "Hərəkəton",
        "namespaces": "Номон мәконон",
-       "variants": "Вариантон",
+       "variants": "Varianton",
        "navigation-heading": "Naviqasiyə menü",
-       "errorpagetitle": "Сәһв",
+       "errorpagetitle": "Səhv",
        "returnto": "Бә сәһифә огәрдеј $1.",
        "tagline": "Материал че {{SITENAME}}",
-       "help": "Арајиш",
+       "help": "Koməq",
        "search": "Nəve",
-       "searchbutton": "Нәве",
+       "searchbutton": "Nəve",
        "go": "Давардеј",
        "searcharticle": "Давардеј",
        "history": "Сәһифә тарых",
-       "history_short": "Тарых",
+       "history_short": "tarix",
+       "history_small": "tarix",
        "printableversion": "Чап кардејро рәвојәт",
        "permalink": "Еғрорә сәбон",
        "print": "Чап",
        "delete": "Рәдд кардеј",
        "undelete_short": "Бәрпо кардеј $1 {{PLURAL:$1|дәгиши|дәгишон|}}",
        "viewdeleted_short": "Дијә карде {{PLURAL:$1|иглә рәдд кардә быә дәгиши|$1 рәдд кардә быә дәгишон}}",
-       "protect": "Мыдофијә кардеј",
+       "protect": "Mıdofiə karde",
        "protect_change": "дәгиш кардеј",
        "unprotect": "Мыдофијә дәгиш кардеј",
        "newpage": "Тожә сәһифә",
        "disclaimers": "Çı məsuliyyətiku imtina",
        "disclaimerpage": "Project:Дејни бә гиј ныгәтеј",
        "edithelp": "Арајиш бо редактә кардеј",
+       "helppage-top-gethelp": "Kuməq",
        "mainpage": "Sərlohə",
-       "mainpage-description": "Ó\98Ñ\81оÑ\81Ó\99 Ñ\81Ó\99һиÑ\84Ó\99",
+       "mainpage-description": "Æ\8fsos sÉ\99hifÉ\99",
        "policy-url": "Project:Ғајдон",
        "portal": "Ҹәмјәт",
        "portal-url": "Project:Ҹәмјәти портал",
        "hidetoc": "нијо кардеј",
        "collapsible-collapse": "Бурмә кардеј",
        "collapsible-expand": "Һовуж кардеј",
+       "confirmable-yes": "Bəle",
+       "confirmable-no": "Ne",
        "thisisdeleted": "Дијә кардеј јаанки бәрпо кардеј $1?",
        "viewdeleted": "Дијә кардеј $1?",
        "restorelink": "{{PLURAL:$1|иглә рәдд кардә быә дәгиши|$1 рәдд кардә быә дәгишон}}",
        "nstab-media": "Медијә сәһифә",
        "nstab-special": "Хысусијә сәһифә",
        "nstab-project": "Нахшә бәрәдә",
-       "nstab-image": "Фајл",
+       "nstab-image": "Fayl",
+       "nstab-mediawiki": "Mesoj",
        "nstab-template": "Ғәлиб",
+       "nstab-help": "Koməqə səhifə",
        "nstab-category": "Тиспир",
        "mainpage-nstab": "Sərlohə",
        "error": "Сәһв",
+       "databaseerror-error": "Səhv: $1",
        "readonly": "Бә база нывыште блок быә.",
        "missing-article": "База мәлумотон дыләдә бә ахтар кардә быә саһифон «$1» $2 барәдә мәлумот пәјдо карде ныбе.\nЖыго вәзијјәт бе бәзне бә вахтики, ым сәһифә че рәдд кардә быә сәһифә канә рәвојәте.\nГирәм ым жыго ни, жәгәдә шымә програм тәминатијәдә сәһв пәјдо кардәјоне.\nХаһиш кардәмон че сәһифә URL-и бә [[Special:ListUsers/sysop|администратори]] бывғандәнән.",
        "missingarticle-rev": "(рәвојәт#: $1)",
        "exception-nologin": "Ыштәни едаштәнијоне",
        "yourname": "Иштирокәкә ном:",
        "yourpassword": "Парол:",
+       "userlogin-yourpassword": "Pərol",
        "yourpasswordagain": "Пароли сәнибәтон гырдә карде:",
+       "yourdomainname": "Iştı domen:",
        "login": "Ыштәни едаштеј",
        "nav-login-createaccount": "Ыштәни едаштеј / ыштәни ғејд кардовнијеј",
        "logout": "Системәдә кој орохнијеј",
        "userlogout": "Системәдә кој орохнијеј",
        "notloggedin": "Ыштәни едаштәнијоне",
        "createaccount": "Нујә иштирокәкә ғејд кардеј",
+       "createacct-emailrequired": "E-poşt unvan",
        "createaccountmail": "бә е-номә",
+       "createacct-realname": "Həğiği nüm",
+       "createacct-reason": "Səbəb",
        "mailmypassword": "Нујә парол вығандеј бә Е-номә.",
        "loginlanguagelabel": "Зывон: $1",
        "pt-login": "Dəşi",
        "resetpass_header": "Иштирокәкә пароли дәгиш карде",
        "oldpassword": "Канә парол:",
        "newpassword": "Нујә парол:",
+       "botpasswords-label-cancel": "Ləğv",
+       "botpasswords-label-delete": "Təmiz karde",
        "resetpass_forbidden": "Парол әзыни дәгиш бе",
        "resetpass-submit-loggedin": "Пароли дәгиш кардеј",
        "resetpass-submit-cancel": "Ләғв кардеј",
        "passwordreset-username": "Иштирокәкә ном:",
+       "passwordreset-domain": "Domen:",
        "passwordreset-email": "Е-номә унвон:",
        "changeemail": "Е-номә унвони дәгиш кардеј",
        "changeemail-newemail": "Е-номә тожә унвон:",
        "sig_tip": "Шымә ғол ијән вахт",
        "hr_tip": "Уфуғијә ријә (рә-рә истифодә мәкән)",
        "summary": "Дәгишон тәсвир:",
-       "subject": "Мывзу/сәрловһә:",
+       "subject": "Мıvzu:",
        "minoredit": "Ым гадә дәгишије",
        "watchthis": "Ым сәһифә тәмшо кардеј",
        "savearticle": "Сәһифә огәтеј",
        "history-feed-item-nocomment": "$1 бә $2-дә",
        "rev-delundel": "нишо дој/нијо кардеј",
        "rev-showdeleted": "нишо дој",
-       "revdelete-show-file-submit": "Бәле",
+       "revdelete-show-file-submit": "Bəle",
        "revdelete-radio-set": "Бәле",
        "revdelete-radio-unset": "Не",
-       "revdelete-log": "Сәбәб:",
+       "revdelete-log": "Səbəb",
        "revdel-restore": "Винде дәрәҹә дәгиш карде",
        "pagehist": "Сәһифә тарых",
-       "revdelete-reasonotherlist": "Ҹо сәбәб",
-       "mergehistory-reason": "Сәбәб:",
+       "revdelete-reasonotherlist": "Co səbəb",
+       "mergehistory-reason": "Səbəb",
        "revertmerge": "Бахш кардеј",
        "history-title": "$1: Дәгишон тарых",
        "lineno": "Сәтыр $1:",
        "tooltip-search-fulltext": "Səhifon pəydo kardey de ın mətni",
        "tooltip-p-logo": "Dəvardey bə əsosə səhifə",
        "tooltip-n-mainpage": "Дәвардеј бә әсосә сәһифә",
-       "tooltip-n-mainpage-description": "Ð\94Ó\99ваÑ\80деÑ\98 Ð±Ó\99 Ó\99Ñ\81оÑ\81Ó\99 Ñ\81Ó\99һиÑ\84Ó\99",
+       "tooltip-n-mainpage-description": "\99vardey bÉ\99 É\99sos sÉ\99hifÉ\99",
        "tooltip-n-portal": "Naxşə barədə, çiç şımə bəzneyon ıyo kardey, iyən konco çiç heste",
        "tooltip-n-currentevents": "Есәтнә һодисон сијоһи",
        "tooltip-n-recentchanges": "Oxonə dəqişon siyohi",
index 15071bc..423c7a8 100644 (file)
                        "Fitoschido"
                ]
        },
-       "tog-underline": "Сылтамаларны сызымлау:",
-       "tog-hideminor": "Соңгы үзгәртүләр исемлегендә кече үзгәртүләр яшерелсен",
-       "tog-hidepatrolled": "ТикÑ\88еÑ\80елгÓ\99н Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80 Ñ\8fңа Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80 Ð¸Ñ\81емлегеннÓ\99н яшерелсен",
-       "tog-newpageshidepatrolled": "ТикÑ\88еÑ\80елгÓ\99н Ð±Ð¸Ñ\82лÓ\99Ñ\80 Ñ\8fңа Ð±Ð¸Ñ\82лÓ\99Ñ\80 Ð¸Ñ\81емлегеннÓ\99н яшерелсен",
-       "tog-hidecategorization": "Битләрне төркемләшү яшерелсен",
-       "tog-extendwatchlist": "Соңгыларын гына түгел, ә барлык үзгәртүләрне эченә алган, киңәйтелгән күзәтү исемлеге",
+       "tog-underline": "Сылтамаларны ассызымлау:",
+       "tog-hideminor": "Соңгы үзгәрешләрдә кече төзәтмәләр яшерелсен",
+       "tog-hidepatrolled": "СоңгÑ\8b Ò¯Ð·Ð³Ó\99Ñ\80еÑ\88лÓ\99Ñ\80дÓ\99 Ñ\82икÑ\88еÑ\80елгÓ\99н Ñ\82өзÓ\99Ñ\82мÓ\99лÓ\99Ñ\80 яшерелсен",
+       "tog-newpageshidepatrolled": "Яңа Ð±Ð¸Ñ\82лÓ\99Ñ\80 Ð¸Ñ\81емлегендÓ\99 Ñ\82икÑ\88еÑ\80елгÓ\99н Ð±Ð¸Ñ\82лÓ\99Ñ\80 яшерелсен",
+       "tog-hidecategorization": "Битләрнең төркемләшүе яшерелсен",
+       "tog-extendwatchlist": "Соңгыларын гына түгел, ә барлык үзгәрешләрне эченә алган, киңәйтелгән күзәтү исемлеге",
        "tog-usenewrc": "Соңгы үзгәртүләрдә һәм күзәтү исемлегендә үзгәрешләрне төркемләргә",
        "tog-numberheadings": "Атамалар автомат рәвештә номерлансын",
        "tog-editondblclick": "Битләргә ике чирттерү белән үзгәртү бите ачылсын",
        "tog-watchdeletion": "Мин бетергән битләр һәм файлларны күзәтү исемлегемгә өстәлсен",
        "tog-watchuploads": "Минем тарафтан йөкләнелгән файлларны күзәтү исемлегемә кертелсен",
        "tog-watchrollback": "Мин үткәрмәгән битләрне күзәтү исемлегемә өстәргә",
-       "tog-minordefault": "Барлык үзгәртүләрне килешү буенча кече дип билгеләнсен",
+       "tog-minordefault": "Барлык төзәтмәләрне килешү буенча кече дип билгеләнсен",
        "tog-previewontop": "Үзгәртү тәрәзәсеннән өстәрәк битне алдан карау өлкәсен күрсәтелсен",
        "tog-previewonfirst": "Үзгәртү битенә күчкәндә башта алдан карау бите күрсәтелсен",
        "tog-enotifwatchlistpages": "Күзәтү исемлегемдәге бит яки файл үзгәртелү турында электрон почтага хәбәр җибәрелсен",
        "tog-enotifusertalkpages": "Бәхәс битем үзгәртелү турында электрон почтага хәбәр җибәрелсен",
-       "tog-enotifminoredits": "Кече үзгәртүләр турында да электрон почтага хәбәр җибәрелсен",
+       "tog-enotifminoredits": "Кече төзәтмәләр турында да электрон почтага хәбәр җибәрелсен",
        "tog-enotifrevealaddr": "Хәбәрнамәдә минем почта адресым күрсәтелсен",
        "tog-shownumberswatching": "Битне күзәтү исемлекләренә өстәгән кулланучылар санын күрсәтелсен",
        "tog-oldsig": "Хәзерге имзагыз:",
        "tog-fancysig": "Имзаның шәхси вики-билгеләмәсе (автоматик сылтамасыз)",
        "tog-uselivepreview": "Битне яңартмыйча тиз карап алуны куллану",
-       "tog-forceeditsummary": "Үзгәртүләрне тасвирлау юлы тутырылмаган булса, кисәтү",
-       "tog-watchlisthideown": "Ð\9cинем Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80ем ÐºÒ¯Ð·Ó\99Ñ\82Ò¯ Ð¸Ñ\81емлегеннÓ\99н яшерелсен",
-       "tog-watchlisthidebots": "Ð\91оÑ\82 Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80е ÐºÒ¯Ð·Ó\99Ñ\82Ò¯ Ð¸Ñ\81емлегеннÓ\99н яшерелсен",
-       "tog-watchlisthideminor": "Кече үзгәртүләр күзәтү исемлегеннән яшерелсен",
-       "tog-watchlisthideliu": "Ð\90вÑ\82оÑ\80изаÑ\86иÑ\8fне Ñ\83зган ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80нÑ\8bÒ£ Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80е ÐºÒ¯Ð·Ó\99Ñ\82Ò¯ Ð¸Ñ\81емлегеннÓ\99н яшерелсен",
+       "tog-forceeditsummary": "Төзәтмә аңлатмасы кыры буш булса, кисәтү",
+       "tog-watchlisthideown": "Ð\9aүзÓ\99Ñ\82Ò¯ Ð¸Ñ\81емлегемдÓ\99 Ð¼Ð¸Ð½ÐµÐ¼ Ñ\82өзÓ\99Ñ\82мÓ\99лÓ\99Ñ\80ем яшерелсен",
+       "tog-watchlisthidebots": "Ð\9aүзÓ\99Ñ\82Ò¯ Ð¸Ñ\81емлегемдÓ\99 Ð±Ð¾Ñ\82 Ñ\82өзÓ\99Ñ\82мÓ\99лÓ\99Ñ\80е яшерелсен",
+       "tog-watchlisthideminor": "Күзәтү исемлегемдә кече төзәтмәләр яшерелсен",
+       "tog-watchlisthideliu": "Ð\9aүзÓ\99Ñ\82Ò¯ Ð¸Ñ\81емлегемдÓ\99 ÐºÐµÑ\80гÓ\99н ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80нÑ\8bÒ£ Ñ\82өзÓ\99Ñ\82мÓ\99лÓ\99Ñ\80е яшерелсен",
        "tog-watchlistreloadautomatically": "Фильтр алмашкан очракта күзәтү исемлеген автоматик рәвештә яңартырга (JavaScript кирәк)",
-       "tog-watchlisthideanons": "Ð\90ноним ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80нÑ\8bÒ£ Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80е ÐºÒ¯Ð·Ó\99Ñ\82Ò¯ Ð¸Ñ\81емлегеннÓ\99н яшерелсен",
-       "tog-watchlisthidepatrolled": "ТикÑ\88еÑ\80елгÓ\99н Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80 ÐºÒ¯Ð·Ó\99Ñ\82Ò¯ Ð¸Ñ\81емлегеннÓ\99н яшерелсен",
+       "tog-watchlisthideanons": "Ð\9aүзÓ\99Ñ\82Ò¯ Ð¸Ñ\81емлегендÓ\99 Ð°Ð½Ð¾Ð½Ð¸Ð¼ ÐºÑ\83лланÑ\83Ñ\87Ñ\8bлаÑ\80нÑ\8bÒ£ Ñ\82өзÓ\99Ñ\82мÓ\99лÓ\99Ñ\80е яшерелсен",
+       "tog-watchlisthidepatrolled": "Ð\9aүзÓ\99Ñ\82Ò¯ Ð¸Ñ\81емлегемдÓ\99 Ñ\82икÑ\88еÑ\80елгÓ\99н Ñ\82өзÓ\99Ñ\82мÓ\99лÓ\99Ñ\80 яшерелсен",
        "tog-watchlisthidecategorization": "Битләрне төркемләшү яшерелсен",
        "tog-ccmeonemails": "Башка кулланучыларга җибәргән хатларымның копияләре миңа да җибәрелсен",
        "tog-diffonly": "Юрама чагыштыру астында бит эчтәлеге күрсәтелмәсен",
        "create-local": "Локаль тасвирлама өстәү",
        "delete": "Бетерү",
        "undelete_short": "$1 {{PLURAL:$1|төзәтмәне|$1 төзәтмә}} торгызу",
-       "viewdeleted_short": "{{PLURAL:$1|1=1 бетерелгән үзгәртүне|$1 бетерелгән үзгәртүне}} карау\n{{PLURAL:$1|бетерелгән төзәтмәне|$1 бетерелгән төзәтмәне}} карау",
+       "viewdeleted_short": "Бетерелгән {{PLURAL:$1|1=төзәтмәне|$1 төзәтмәне}} карау",
        "protect": "Яклау",
        "protect_change": "үзгәртү",
        "unprotect": "Яклауны үзгәртү",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Сезгә}} {{PLURAL:$3|$3 кулланучыдан}} $1 килде ($2).",
        "youhavenewmessagesmanyusers": "Сез бик күп кулланучыдан $1 алдыгыз ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|яңа хәбәр|999=яңа хәбәрләр}}",
-       "newmessagesdifflinkplural": "соңгы {{PLURAL:$1|үзгәртү|үзгәртүләр}}",
+       "newmessagesdifflinkplural": "соңгы {{PLURAL:$1|үзгәреш|999=үзгәрешләр}}",
        "youhavenewmessagesmulti": "$1 эчендә яңа хат бар",
        "editsection": "үзгәртү",
        "editold": "үзгәртү",
        "viewsource-title": "$1 битенең чыганагын карау",
        "actionthrottled": "Тизлек киметелгән",
        "actionthrottledtext": "Спамга каршы көрәш өчен, аз вакыт эчендә бу гамәлне еш куллану тыелган һәм СЕз бирелгән вакытны бетергәнсез инде. Зинһар, соңарак кабатлагыз.",
-       "protectedpagetext": "Ð\91Ñ\83 Ð±Ð¸Ñ\82 Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80дÓ\99н Ò»Ó\99м Ð±Ð°Ñ\88ка Ñ\82Ó©Ñ\80ле Ð³Ð°Ð¼Ó\99ллÓ\99Ñ\80дÓ\99н Ñ\8fкланган.",
+       "protectedpagetext": "Бу бит үзгәртүдән һәм башка төрле гамәлләрдән якланган.",
        "viewsourcetext": "Сез бу битнең башлангыч текстын карый һәм күчерә аласыз.",
        "viewyourtext": "Сез <strong>үз төзәтмәләрегезне</strong> бу сәхифәдә карый һәм чыгарылма текстны күчермәли аласыз.",
        "protectedinterface": "Бу биттә программа тәэминатының интерфейс хәбәрләре бар. Вандализмга каршы көрәш сәбәпле, бу битне үзгәртү тыела. Әлеге хәбәрнең тәрҗемәсен өстәү яки үзгәртү өчен, зинһар өчен, MediaWiki [https://translatewiki.net/ translatewiki.net] тәрҗемәләү сайтын кулланыгыз.",
        "editinginterface": "<strong>Игътибар:</strong> Сез программа тәэминатының интерфейс тексты булган битне үзгәртәсез. Бу башка кулланучыларга да тәэсир итәчәк.",
        "translateinterface": "Бу хәбәрнең текстын үзгәртү өчен яки өстәмәләр кертү өчен MediaWiki җирләштерү сайтын кулланыгыз [https://translatewiki.net/ translatewiki.net].",
-       "cascadeprotected": "Ð\91Ñ\83 Ð±Ð¸Ñ\82 Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80дÓ\99н Ñ\81акланган, Ñ\87өнки Ñ\83л ÐºÐ°Ñ\81кадлÑ\8b Ñ\81аклаÑ\83 ÐºÐ°Ð±Ñ\83л Ð¸Ñ\82елгÓ\99н {{PLURAL:$1|1=биÑ\82кÓ\99|биÑ\82лÓ\99Ñ\80гÓ\99}} Ó©Ñ\81Ñ\82Ó\99лгÓ\99н:\n$2",
+       "cascadeprotected": "Бу бит үзгәртүдән сакланган, чөнки ул каскадлы саклау кабул ителгән {{PLURAL:$1|1=биткә|битләргә}} өстәлгән:\n$2",
        "namespaceprotected": "'''$1''' исем киңлегендәге битләрне үзгәртү өчен сезнең рөхсәтегез юк.",
        "customcssprotected": "Сез бу CSS-сәхифәне үзгәртә алмыйсыз, чөнки монда башка кулланучының шәхси көйләнмәләре саклана",
        "customjsprotected": "Сез бу JavaScript-сәхифәне үзгәртә алмыйсыз, чөнк монда башка кулланучының шәхси көйләнмәләре саклана",
        "media_tip": "Файлга сылтама",
        "sig_tip": "Имзагыз вакыт белән",
        "hr_tip": "Горизонталь сызык (еш кулланмагыз)",
-       "summary": "Үзгәртүләр тасвирламасы:",
+       "summary": "Кыскача аңлатма:",
        "subject": "Тема:",
        "minoredit": "Бу кече төзәтмә",
        "watchthis": "Бу битне күзәтү",
        "savearticle": "Битне саклау",
-       "savechanges": "Үзгәртүләрне саклау",
+       "savechanges": "Үзгәрешләрне саклау",
        "publishpage": "Бит ясау",
        "publishchanges": "Битне бастыру",
        "savearticle-start": "Битне саклау...",
-       "savechanges-start": "Үзгәртүләрне саклау...",
+       "savechanges-start": "Үзгәрешләрне саклау…",
        "publishpage-start": "Битне бастыру...",
        "publishchanges-start": "Төзәтмәләрне бастыру...",
        "preview": "Алдан карау",
        "showpreview": "Алдан карау",
-       "showdiff": "Кертелгән үзгәртүләр",
+       "showdiff": "Кертелгән үзгәрешләр",
        "anoneditwarning": "<strong>Игътибар!</strong> Сез сайтта теркәлмәдегез. Әгәрдә сез нинди дә булсә төзәтмәләр яисә үзгәртүләр кертсәгез, сезнең IP-адрес башка кулланучыларга да билгеле булачак. Сайтка <strong>[$1 керсәгез]</strong> яисә <strong>[$2 кулланучы язмасын төзесәгез]</strong>, сез керткән үзгәртүләр сезнең кулланучы язмагызга бәйләнгән булачак, шулай ук башка мөмкинлекләр дә туачак.",
        "anonpreviewwarning": "''Сез системада теркәлмәдегез.Сезнең тарафтан эшләнгән барлык үзгәртүләр дә сезнең IP-юлламагызны саклауга китерә.''",
-       "missingsummary": "'''Искәртү.''' Сез үзгәртүгә кыскача тасвирлау язмадыгыз. Сез «Битне саклау» төймәсенә тагын бер тапкыр бассагыз, үзгәртүләр тасвирламасыз сакланачак.",
-       "missingcommenttext": "Коммент язуыгыз сорала.",
+       "missingsummary": "<strong>Искәртмә.</strong> Сез төзәтмәнең кыскача аңлатмасы бирмәдегез. \nӘгәр «$1» төймәсенә кабат бассагыз, төзәтмәгез аңлатмасыз сакланачак.",
+       "missingcommenttext": "Комментарий языгызчы.",
        "missingcommentheader": "<strong>Искәртү:</strong> Сез шәрехнең темасын күрсәтмәгәнсез.\n«$1» төймәсенә кабат бассагыз, үзгәртүләр темасыз язылачак.",
        "summary-preview": "Төзәтмәләрне карап чыгу:",
        "subject-preview": "Башисемне алдан карау:",
-       "blockedtitle": "Ð\9aÑ\83лланÑ\83Ñ\87Ñ\8b Ñ\82Ñ\8bелдÑ\8b",
+       "blockedtitle": "Ð\9aÑ\83лланÑ\83Ñ\87Ñ\8b Ñ\82Ñ\8bелган",
        "blockedtext": "<strong>Сезнең хисап язмагыз яки IP адресыгыз тыелган.</strong>\n\nТыючы идарәче: $1.\nКүрсәтелгән сәбәп: <em>$2</em>.\n\n* Тыю башланган вакыт: $8\n* Тыю ахыры: $6\n* Тыелулар саны: $7\n\nСез $1 яки башка [[{{MediaWiki:Grouppage-sysop}}|идарәчегә]] тыю буенча сорауларыгызны җибәрә аласыз.\nИсегездә тотыгыз: әгәр сез теркәлмәгән һәм электрон почта адресыгызны [[Special:Preferences|көйләнмәләрдә]] дәлилләмәгән булсагыз, сез бирелгән «{{int:emailuser}}» мөмкинчелекне куллана алмаячаксыз. Шулай ук тыю вакытында сезнең хат җибәрү мөмкинлегегезне чикләгән булырга да мөмкиннәр.\nСезнең IP адресыгыз — $3, тыю таныклыгы — $5.\nЗинһар, хатларда бу мәгълүматны күрсәтергә онытмагыз.",
        "autoblockedtext": "Сезнең IP адресыгыз, аның тыелган кулланучы тарафыннан кулланылуы сәбәпле, автомат рәвештә тыелды.\nУл кулланучыны тыючы идарәче: $1. Күрсәтелгән сәбәп:\n\n:<em>$2</em>\n\n* Тыю башланган вакыт: $8\n* Тыю ахыры: $6\n* Тыелулар саны: $7\n\nСез $1 яки башка [[{{MediaWiki:Grouppage-sysop}}|идарәчегә]] тыю буенча сорауларыгызны җибәрә аласыз.\n\nИсегездә тотыгыз: әгәр сез [[Special:Preferences|көйләнмәләрдә]] электрон почта адресыгызны  күрсәтмәгән яки дәлилләмәгән булсагыз, шулай ук  сез блокта булсагыз хат җибәреп булмаячак һәм  сез \"{{int:emailuser}}\" мөмкинлеген куллана алмаячаксыз.\n\nСезнең IP адрес — $3, тыю идентификаторы — #$5.\nХатларда бу мәгълүматны күрсәтергә онытмагыз.",
        "blockednoreason": "сәбәп күрсәтелмәгән",
        "accmailtext": "[[User talk:$1|$1]] кулланучысы өчен төзелгән серсүз $2 адресына җибәрелде.\n\nАвторизация узгач, үз хисап язмагызда сез ''[[Special:ChangePassword|серсүзегезне үзгәртә аласыз]]''.",
        "newarticle": "(Яңа)",
        "newarticletext": "Сез әлегә язылмаган биткә кердегез.\nЯңа бит ясау өчен астагы тәрәзәдә мәкалә текстын җыегыз ([$1 ярдәм битен] карый аласыз).\nӘгәр сез бу биткә ялгышлык белән эләккән булсагыз, браузерыгызның '''артка''' төймәсенә басыгыз.",
-       "anontalkpagetext": "----\n<em>Бу бәхәс бите системада теркәлмәгән яисә үз исеме белән кермәгән кулланучыныкы.</em>\nАны тану өчен без санлы IP адресын файдаланырга мәҗбүрбез.\nӘлеге адрес башка аноним кулланучылар тарафыннан да кулланылырга мөмкин.\nӘгәр сез аноним кулланучы һәм сезгә юлланмаган хәбәрләр алдым дип саныйсыз икән (бер IP адресы күп кулланучы өчен булырга мөмкин), башка мондый аңлашылмаучанлыклар килеп чыкмасын өчен [[Special:UserLogin|системага керегез]] яисә [[Special:CreateAccount|теркәлегез]].",
+       "anontalkpagetext": "----\n<em>Бу системада теркәлмәгән яки үз исеме белән кермәгән кулланучы өчен бәхәс бите.</em>\nШуңа күрә аны тану өчен безгә санлы IP адресын файдаланырга туры килә.\nШундый ук IP адресын берничә кулланучы бер-бере белән уртаклашырга мөмкин.\nӘгәр сез бер аноним кулланучы һәм сезгә юлланмаган хәбәрләрне алдым дип тоясез икән, башка мондый аңлашылмаучылык килеп чыкмасын өчен  [[Special:CreateAccount|теркәлегез]] яки [[Special:UserLogin|системага керегез]] әле.",
        "noarticletext": "Хәзерге вакытта бу биттә текст юк.\nСез [[Special:Search/{{PAGENAME}}|бу исем кергән башка мәкаләләрне]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} көндәлекләрдәге язмаларны] таба\nяки '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} шушындый исемле яңа бит төзи]'''</span> аласыз.",
        "noarticletext-nopermission": "Хәзерге вакытта бу биттә текст юк.\nСез [[Special:Search/{{PAGENAME}}|бу исем кергән башка мәкаләләрне]] башка битләрдә,\nяисә <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} көндәлекләрдәге язмаларны] таба аласыз.</span> Сезнең бу битне ясарга хакыгыз юк.",
        "userpage-userdoesnotexist": "«<nowiki>$1</nowiki>» исемле хисап язмасы юк. Сез чынлап та бу битне ясарга яисә үзгәртергә телисезме?",
        "log-fulllog": "Көндәлекне тулысынча карау",
        "edit-hook-aborted": "Үзгәртү махсус процедура тарафыннан кире кагыла.\nСәбәпләре китерелми.",
        "edit-gone-missing": "Битне яңартып булмый.\nУл бетерелгән булырга мөмкин.",
-       "edit-conflict": "Үзгәртүләр конфликты.",
+       "edit-conflict": "Үзгәртү конфликты.",
        "edit-no-change": "Текстта үзгәешләр ясалмау сәбәпле, сезнең үзгәртү кире кагыла.",
        "postedit-confirmation-created": "Бит төзелде",
        "postedit-confirmation-saved": "Төзәтмәгез сакланды.",
        "edit-already-exists": "Яңа бит төзеп булмый.\nУл инде бар.",
        "editwarning-warning": "Башка биткә күчү вакытында бу мәкаләгә керткән үзгәрешләр югалырга мөмкин.\nӘгәрдә сез теркәлгән булсагыз, бу искәрмәне сез көйләнмәләрегезнең «{{int:prefs-editing}}» бүлегендә үзгәртә аласыз.",
+       "slot-name-main": "Төп",
        "content-model-wikitext": "викитекст",
        "content-model-text": "гади текст",
        "content-model-javascript": "JavaScript",
        "expansion-depth-exceeded-category": "Ачыклык тирәнлеге зур булган битләр",
        "expansion-depth-exceeded-warning": "Биттә кертем чиге артып киткән",
        "undo-success": "Үзгәртүдән баш тартып була.\nЮрамалараны чагыштыруны карагыз һәм, үзгәртүләр Сез теләгәнчә булса, битне саклагыз.",
-       "undo-failure": "Аралыктагы үзгәртүләр туры килмәү сәбәпле, үзгәртүдән баш тартып булмый.",
-       "undo-norev": "Үзгәртү юк яисә ул бетерелгән, шуңа аннан баш тартып булмый.",
+       "undo-failure": "Аралыктагы үзгәрешләр туры килмәү сәбәпле, төзәтмәне кире кагып булмый.",
+       "undo-norev": "Төзәтмәне кире кагып булмый, чөнки аны барлыкта юк яки ул бетерелгән.",
        "undo-summary": "[[Special:Contributions/$2|$2]] кулланучысының ([[User talk:$2|бәхәс]]) $1 үзгәртүеннән баш тарту",
        "cantcreateaccount-text": "Бу IP адресыннан (<b>$1</b>) хисап язмалары төзү тыела. Тыючы: [[User:$3|$3]].\n\n$3 күрсәткән сәбәп: ''$2''",
        "viewpagelogs": "Бу битнең көндәлекләрен карау",
-       "nohistory": "Ð\91Ñ\83 Ð±Ð¸Ñ\82нең Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үлÓ\99Ñ\80 тарихы юк.",
+       "nohistory": "Ð\91Ñ\83 Ð±Ð¸Ñ\82нең Ò¯Ð·Ð³Ó\99Ñ\80Ñ\82үе тарихы юк.",
        "currentrev": "Хәзерге юрама",
        "currentrev-asof": "Хәзерге юрама, $1",
        "revisionasof": "$1 юрамасы",
        "revision-info": "$1 юрамасы; {{GENDER:$6|$2}}$7",
        "previousrevision": "← Алдагы юрама",
-       "nextrevision": "ЧиÑ\80аÑ\82Ñ\82агÑ\8b юрама →",
+       "nextrevision": "Ð\9aилÓ\99Ñ\81е юрама →",
        "currentrevisionlink": "Хәзерге юрама",
        "cur": "хәзерге",
        "next": "киләсе",
        "page_first": "беренче",
        "page_last": "соңгы",
        "histlegend": "Аңлатмалар: '''({{int:cur}})''' = хәзерге юрамадан аерымлыклар, '''({{int:last}})''' = баягы юрамадан аерымлыклар, '''{{int:minoreditletter}}''' = кече үзгәртүләр.",
-       "history-fieldset-title": "Үзгәртмәләрне сөзү",
+       "history-fieldset-title": "Төзәтмәләрне сөзү",
        "history-show-deleted": "Бары тик бетерелгән төзәтмәләр",
        "histfirst": "иң иске",
        "histlast": "иң яңа",
        "historysize": "($1 {{PLURAL:$1|байт}})",
-       "historyempty": "(буш)",
+       "historyempty": "буш",
        "history-feed-title": "Үзгәртү тарихы",
        "history-feed-description": "Бу битнең викидагы үзгәртү тарихы",
        "history-feed-item-nocomment": "$1, $2",
        "history-feed-empty": "Соратылган бит юк.\nУл бетерелгән яисә бүтән урынга күчерелгән (башка исем алган) булырга мөмкин.\n[[Special:Search|Эзләтеп]] карагыз.",
-       "rev-deleted-comment": "(үзгәртүләрнең тасвиры бетерелгән)",
+       "rev-deleted-comment": "(төзәтмә аңлатмасы бетерелгән)",
        "rev-deleted-user": "(автор исеме бетерелгән)",
        "rev-deleted-event": "(язма бетерелгән)",
        "rev-deleted-user-contribs": "[кулланучының исеме яки  IP-юлламасы бетерелгән  — үзгәртү кертем битеннән яшерелгән]",
        "rev-deleted-text-view": "Битнең бу юрамасы '''бетерелгән'''.\nСез аны карый аласыз. [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Бетерүләр көндәлегендә] аңлатмалар бирелгән булырга мөмкин.",
        "rev-suppressed-text-view": "Битнең бу юрамасы '''яшерелгән'''.\nСез аны карый аласыз. [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} Яшерүләр көндәлегендә] аңлатмалар бирелгән булырга мөмкин.",
        "rev-deleted-no-diff": "Сез юрамалар арасындагы аермаларны карый алмыйсыз. Сәбәбе: кайсыдыр юрама '''бетерелгән'''.\n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Бетерүләр көндәлегендә] тулырак мәгълүмат табып була.",
-       "rev-suppressed-no-diff": "Сез юрамалар  арасындагы үзгәртүләрне карый алмыйсыз, чөнки аларның берсе '''бетерелгән'''.",
+       "rev-suppressed-no-diff": "Сез юрамалар аермасын карый алмыйсыз, чөнки аларның берсе <strong>бетерелгән</strong>.",
        "rev-deleted-unhide-diff": "Битнең кайсыдыр юрамасы '''бетерелгән'''.\n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Бетерүләр көндәлегендә] тулырак мәгълүмат табып була.\nТеләгегез булса сез  [$1 бирелгән юраманы карый аласыз]",
        "rev-suppressed-unhide-diff": "Битнең кайсыдыр юрамасы '''яшерелгән'''.\n[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} Яшерүләр көндәлегендә] тулырак мәгълүмат табып була.\nТеләгегез булса сез  [$1 яшерелгән юраманы карый аласыз]",
        "rev-deleted-diff-view": "Бу юрамалар чагыштыруының бер юрамасы '''бетерелгән'''.\nСез  чагыштыруны карый аласыз, [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} бетерүләр көндәлегендә] тулырак мәгълүмат бирелгән булырга мөмкин.",
        "revdelete-hide-text": "Үзгәртү тексты",
        "revdelete-hide-image": "Файл эчендәгеләрне качыр",
        "revdelete-hide-name": "Гамәлне һәм көйләүне яшерү",
-       "revdelete-hide-comment": "Үзгәртүләр тасвирламасы",
+       "revdelete-hide-comment": "Үзгәрешләр аңлатмасы",
        "revdelete-hide-user": "Кулланучы исеме/IP-адрес",
        "revdelete-hide-restricted": "Мәгълүматлар идарәчеләрдән дә яшерелсен",
        "revdelete-radio-same": "(үзгәртмәү)",
        "revdelete-edit-reasonlist": "Сәбәпләр исемлеген үзгәртү",
        "revdelete-offender": "Әлеге юрамалы битнең авторы:",
        "suppressionlog": "Яшерү көндәлеге",
-       "mergehistory": "Үзгәртүләр тарихын берләштерү",
+       "mergehistory": "Үзгәрешләр тарихын берләштерү",
        "mergehistory-box": "Ике битнең үзгәртүләр тарихын берләштерү:",
        "mergehistory-from": "Чыганак:",
        "mergehistory-into": "Төп бит:",
        "prefs-labs": "Сынаулы мөмкинчелекләр",
        "prefs-user-pages": "Кулланучы битләре",
        "prefs-personal": "Шәхси мәгълүмат",
-       "prefs-rc": "Соңгы төзәтмәләр",
+       "prefs-rc": "Соңгы үзгәрешләр",
        "prefs-watchlist": "Күзәтү исемлеге",
        "prefs-editwatchlist": "Күзәтү исемлеген үзгәртү",
        "prefs-editwatchlist-label": "Күзәтү исемлеге язмаларын үзгәртү:",
        "prefs-editwatchlist-clear": "Күзәтү исемлеген чистарту",
        "prefs-watchlist-days": "Күзәтү исемлегендә күрсәтелгән көннәр саны:",
        "prefs-watchlist-days-max": "Иң күбе $1 {{PLURAL:$1|1=көн|көн}}",
-       "prefs-watchlist-edits": "Күзәтү исемлегендә күрсәтелүче төзәтмәләрнең максималь саны:",
+       "prefs-watchlist-edits": "Күзәтү исемлегендә күрсәтү өчен үзгәрешләрнең иң зур саны:",
        "prefs-watchlist-edits-max": "Иң күбе: 1000",
        "prefs-watchlist-token": "Күзәтү исемлеге токены:",
        "prefs-watchlist-managetokens": "Токеннар беләр идарә итү",
        "action-sendemail": "электрон хат җибәрү",
        "nchanges": "$1 {{PLURAL:$1|үзгәртү}}",
        "enhancedrc-history": "тарих",
-       "recentchanges": "Соңгы үзгәртүләр",
+       "recentchanges": "Соңгы үзгәрешләр",
        "recentchanges-legend": "Соңгы үзгәртүләр көйләүләре",
        "recentchanges-summary": "Төрле битләрдә эшләнгән соңгы үзгәртүләр исемлеге.",
        "recentchanges-noresult": "Сайланган чорда күрсәтелгән шартларга туры килүче төзәтмәләр юк.",
        "rcfilters-savedqueries-cancel-label": "Баш тарту",
        "rcfilters-savedqueries-add-new-title": "Хәзерге фильтр көйләнмәләрен саклау",
        "rcfilters-clear-all-filters": "Барлык филтерләрне чистарту",
-       "rcfilters-search-placeholder": "Фильтрланы соңгы үзгәртү (карау яисә кертүне башлау)",
+       "rcfilters-search-placeholder": "Үзгәрешләрне сөзү (меню кулланыгыз яки сөзгеч аты буенча эзлигез)",
        "rcfilters-invalid-filter": "Яраксыз фильтр",
        "rcfilters-filterlist-title": "Фильтрлар",
        "rcfilters-filterlist-feedbacklink": "Әлеге фильтрлау кораллары турында турында фикер калдырыгыз",
        "rcfilters-watchlist-markseen-button": "Бар үзгәртүләрне каралган дип билгеләргә",
        "rcfilters-watchlist-edit-watchlist-button": "Күзәтү исемлегегезне үзгәртү",
        "rcfilters-watchlist-showupdated": "Сезнең соңгы төзәтмәләрдән соң үзгәргән битләр <strong>калын</strong> һәм тулы маркер белән күрсәтелгән",
-       "rcfilters-preference-label": "«Соңгы үзгәртүләр» битенең яңа юрамасын яшерү",
+       "rcfilters-preference-label": "JavaScript тан башка интерфейсын куллану",
        "rcnotefrom": "Астарак <strong>$3, $4</strong> өчен {{PLURAL:$5|үзгәртүләр күрсәтелгән}} (<strong>$1</strong> артык түгел).",
        "rclistfrom": "$3 $2 башлап яңа үзгәртүләрне күрсәт",
        "rcshowhideminor": "кече төзәтмәләрне $1",
        "delete-confirm": "«$1» бетерү",
        "delete-legend": "Бетерү",
        "historywarning": "<strong>Игътибар:</strong> Сез бетерергә теләгән биттә үзгәртү тарихы бар, ул $1 {{PLURAL:$1|юрамадан тора}}:",
-       "historyaction-submit": "Ð\9aÒ¯Ñ\80Ñ\81Ó\99Ñ\82",
+       "historyaction-submit": "ЮÑ\80амалаÑ\80 ÐºÒ¯Ñ\80Ñ\81Ó\99Ñ\82Ò¯",
        "confirmdeletetext": "Сез бу битнең (яки рәсемнең) тулысынча бетерелүен сорадыгыз.\nЗинһар, моны чыннан да эшләргә теләгәнегезне, моның нәтиҗәләрен аңлаганыгызны һәм [[{{MediaWiki:Policy-url}}]] бүлегендәге кагыйдәләр буенча эшләгәнегезне раслагыз.",
        "actioncomplete": "Гамәл башкарган",
        "actionfailed": "Эш башкарылмаган",
        "deletereasonotherlist": "Башка сәбәп",
        "deletereason-dropdown": "* Бетерүнең сәбәпләре\n** спам\n** вандаллык\n** автор хокукларын бозу\n** автор соравы буенча\n** эшсез күчермә",
        "delete-edit-reasonlist": "Сәбәпләр исемлеген үзгәртү",
+       "rollback-confirmation-no": "Кире алу",
        "rollbacklink": "кире кайтару",
        "rollbacklinkcount": "$1 {{PLURAL:$1|төзәтмәне}} кире кагу",
        "editcomment": "Үзгәртүләр тасвирламасы: <em>$1</em>.",
        "ipbother": "Башка вакыт:",
        "ipboptions": "2 сәгать:2 hours,1 көн:1 day,3 көн:3 days,1 атна:1 week,2 атна:2 weeks,1 ай:1 month,3ай:3 months,6 ай:6 months,1 ел:1 year,чикләүсез:infinite",
        "ipb-confirm": "Тыюны раслау",
+       "ipb-pages-label": "Битләр",
        "badipaddress": "Ялгыш IP адресы",
        "blockipsuccesssub": "Тыю башкарылган",
        "ipb-unblock-addr": "$1 кулланучысын тыюдан азат итү",
        "ipb-unblock": "Кулланучы яки IP адресы тыюдан азат итү",
        "ipb-blocklist-duration-left": "$1 калды",
        "block-expiry": "Бетә:",
+       "block-prevent-edit": "Үзгәртү",
+       "block-reason": "Сәбәп:",
+       "block-target": "IP адресы яки кулланучы исеме",
        "unblockip": "Кулланучыны тыюдан азат итү",
        "ipusubmit": "Бу тыюны туктату",
        "blocklist": "Тыелган кулланучылар",
+       "autoblocklist-submit": "Эзләү",
+       "autoblocklist-legend": "Автотыелу исемлеге",
        "ipblocklist": "Тыелган кулланучылар",
        "blocklist-timestamp": "Дата/вакыт",
        "blocklist-target": "Максат",
        "noautoblockblock": "автотыю ябык",
        "createaccountblock": "хисап язмасы теркәү тыелган",
        "emailblock": "хат җибәрү тыелган",
+       "blocklist-editing": "үзгәртү",
        "blocklink": "тыю",
        "unblocklink": "тыюдан азат итү",
        "change-blocklink": "тыюны үзгәртү",
        "tooltip-n-mainpage-description": "Баш биткә күчү",
        "tooltip-n-portal": "Бу проект турында, монда нәрсә итә аласыз һәм кайда нәрсәдер таба аласыз",
        "tooltip-n-currentevents": "Хәзерге вакыйгалар турында мәгълүматны табарга",
-       "tooltip-n-recentchanges": "Соңгы үзгәртүләр исемлеге",
+       "tooltip-n-recentchanges": "Соңгы үзгәрешләр исемлеге",
        "tooltip-n-randompage": "Очраклы битне карау",
        "tooltip-n-help": "Белешмә алу өчен урын",
        "tooltip-t-whatlinkshere": "Бирегә сылтаган барлык битләрнең исемлеге",
        "special-characters-group-khmer": "Кһмер",
        "special-characters-group-canadianaboriginal": "Канада иҗек язуы",
        "mw-widgets-abandonedit": "Сез чыннан да үзгәртүләрне сакламыйча карау режимына чыгарга телисезме?",
-       "mw-widgets-abandonedit-discard": "Үзгәртүләрне кире кагу",
+       "mw-widgets-abandonedit-discard": "Үзгәрешне кире кагу",
        "mw-widgets-abandonedit-keep": "Үзгәртүне дәвам итү",
        "mw-widgets-abandonedit-title": "Сез ризамы?",
        "mw-widgets-dateinput-no-date": "Дата сайланмаган",
index 9c6550d..75d6b2e 100644 (file)
        "changepassword": "Чажыт сөстү өскертири",
        "resetpass_text": "<!-- Маңаа сөзүглелди немерелээри -->",
        "resetpass_header": "Чажыт сөстү катап чогаадып кылыры",
-       "oldpassword": "Эгри чажыт сөзүңер:",
+       "oldpassword": "Эрги уруң (чажыт сөс):",
        "newpassword": "Чаа чажыт сөзүңер:",
        "retypenew": "Чажыт сөзүңерни катап бижиңер:",
        "resetpass_submit": "Чажыт сөстү чоогадып кылыр база кирер.",
        "page_first": "бирги",
        "page_last": "сөөлгү",
        "histlegend": "Версиялар шилиири: деңнээр дээн арыныңар версияларын имнеңеш, бээр базыптыңар '''{{int:compare-submit}}'''.<br />\nТайылбыр: '''({{int:cur}})''' — амгы версиядан ылгавыр; '''({{int:last}})''' — эрткен версиядан ылгавыр;  '''{{int:minoreditletter}}''' — биче өскерилгелер.",
-       "history-fieldset-title": "Ð\9aаÑ\80алааÑ\80Ñ\8b Ñ\82өөгүзү",
+       "history-fieldset-title": "ЭдилгелеÑ\80ни Ñ\88Ò¯Ò¯Ñ\80",
        "history-show-deleted": "Чүгле казыттынган",
        "histfirst": "Эң эрги",
        "histlast": "Эң чаа",
        "unusedcategories": "Ажыглаваан бөлүктер",
        "unusedimages": "Ажыглаваан файлдар",
        "wantedcategories": "Күзээринге бөлүктер",
-       "wantedpages": "Күзээрүнге арыннар",
+       "wantedpages": "Күзээн арыннар",
        "mostlinked": "Эң холбаалар арыннар",
        "mostlinkedcategories": "Эң холбаалар бөлүктер",
        "mostlinkedtemplates": "Эң холбаалар майыктар",
        "duration-years": "$1 {{PLURAL:$1|чыл|чыл}}",
        "duration-decades": "$1 {{PLURAL:$1|1=он хонук|он хонук}}",
        "duration-centuries": "$1 {{PLURAL:$1|1=чүс чыл|чүс чыл}}",
-       "mw-widgets-abandonedit-title": "Бүзүрелдиг-дир бе?"
+       "mw-widgets-abandonedit-title": "Бүзүрелдиг-дир бе?",
+       "mw-widgets-dateinput-no-date": "Ай-хүн шилитинмээн",
+       "date-range-to": "Ай-хүнге чедир:"
 }
index cb80d47..c4ffa03 100644 (file)
        "privacypage": "Project:اصولِ اخفائے راز",
        "badaccess": "نقص اجازت",
        "badaccess-group0": "آپ متمنی عمل کا اجراء کرنے کے مُجاز نہیں۔",
-       "badaccess-groups": "آپ کا درخواست‌کردہ عمل {{PLURAL:$2|گروہ|گروہوں میں سے ایک}}: $1 کے صارفین تک محدود ہے.",
+       "badaccess-groups": "آپ کا درخواست کردہ اقدام {{PLURAL:$2|اس حلقۂ صارف|ان حلقۂ ہائے صارف میں سے کسی ایک}} تک محدود ہے: $1۔",
        "versionrequired": "میڈیا ویکی کا $1 نسخہ لازمی چاہئیے.",
        "versionrequiredtext": "اِس صفحہ کو استعمال کرنے کیلئے میڈیاویکی کا $1 نسخہ چاہئیے.\n\n\nدیکھئے [[خاص:نسخہ|صفحۂ نسخہ]]",
        "ok": "ٹھیک ہے",
index 1b0da39..f98efd4 100644 (file)
        "createacct-benefit-heading": "{{SITENAME}}係由你同其他人貢獻。",
        "createacct-benefit-body1": "{{PLURAL:$1|次編輯|次編輯}}",
        "createacct-benefit-body2": "{{PLURAL:$1|版|版}}",
-       "createacct-benefit-body3": "最近{{PLURAL:$1|貢獻者|貢獻者}}",
+       "createacct-benefit-body3": "位最近{{PLURAL:$1|貢獻者}}",
        "badretype": "你入嘅密碼前後不一。",
        "usernameinprogress": "呢個名嘅戶口已經開緊。\n請等等。",
        "userexists": "你入嘅用戶名已經有人用咗。\n唔該揀過個名啦。",
index 604a253..257c0b9 100644 (file)
        "specialmute-submit": "确认",
        "specialmute-label-mute-email": "屏蔽该用户的邮件",
        "specialmute-error-invalid-user": "未找到您请求的用户名。",
-       "specialmute-error-email-blacklist-disabled": "沉默向你发电子邮件的用户的功能没启用。",
-       "specialmute-error-email-preferences": "你需要去确认你的电子邮件地址才能沉默用户提醒。你可能需要去[[Special:Preferences|参数设置]]进行设置。",
        "specialmute-login-required": "请登录以更改您的沉默用户提醒设置。",
        "revid": "修订版本$1",
        "pageid": "页面ID$1",
index 032973c..90e6bac 100644 (file)
                        "Luuva",
                        "Davidzdh",
                        "WQL",
-                       "Tang891228"
+                       "Tang891228",
+                       "Winston Sung"
                ]
        },
        "tog-underline": "底線標示連結:",
        "accmailtitle": "密碼已寄出",
        "accmailtext": "[[User talk:$1|$1]] 的隨機密碼已經寄送至 $2,可登入後至 <em>[[Special:ChangePassword|變更密碼]] 頁面更改</em>。",
        "newarticle": "(新)",
-       "newarticletext": "您正連結至一頁不存在頁面。要建立該頁面,請在下方的編輯方塊中輸入內容(詳情請參考[$1 使用說明頁面])。如果您是不小心來到此頁面,請點選瀏覽器的<strong>返回</strong>按鈕。",
+       "newarticletext": "您正連結至一頁不存在頁面。要建立該頁面,請在下方的編輯方塊中輸入內容(詳情請參考[$1 說明頁面])。如果您是不小心來到此頁面,請點選瀏覽器的<strong>返回</strong>按鈕。",
        "anontalkpagetext": "----\n<em>此討論頁面是給尚未建立帳號的匿名使用者使用</em>\n因此我們必須使用 IP 位址來辨識對方,但相同的 IP 位址可能是由許多不同的使用者所共用。\n如果您是匿名使用者並且覺得評論的內容與您無關,請[[Special:CreateAccount|建立新帳號]]或[[Special:UserLogin|登入]]避免與其他匿名使用者混淆。",
        "noarticletext": "此頁面目前沒有內容,您可以在其它頁面中[[Special:Search/{{PAGENAME}}|搜尋此頁面標題]]、<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜尋相關日誌]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 建立此頁面]</span>。",
        "noarticletext-nopermission": "此頁面目前沒有內容,\n您可以在其它頁面中 [[Special:Search/{{PAGENAME}}|搜尋此頁面標題]],或 <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜尋相關日誌]</span>,但您沒有權限建立此頁面。",
        "revdelete-hide-comment": "編輯摘要",
        "revdelete-hide-user": "編輯者的使用者名稱/IP 位址",
        "revdelete-hide-restricted": "禁止顯示資料給管理者及其他使用者",
-       "revdelete-radio-same": "(不變更)",
+       "revdelete-radio-same": "(不變更)",
        "revdelete-radio-set": "隱藏",
        "revdelete-radio-unset": "顯示",
        "revdelete-suppress": "禁止向管理者及其他使用者顯示資料",
        "listgrouprights-key": "說明:\n* <span class=\"listgrouprights-granted\">已授予的權限</span>\n* <span class=\"listgrouprights-revoked\">已撤銷的權限</span>",
        "listgrouprights-group": "群組",
        "listgrouprights-rights": "權限",
-       "listgrouprights-helppage": "Help:Group rights",
+       "listgrouprights-helppage": "Help:使用者群組權限",
        "listgrouprights-members": "(成員清單)",
        "listgrouprights-addgroup": "加入{{PLURAL:$2|群組}}:$1",
        "listgrouprights-removegroup": "移除{{PLURAL:$2|群組|群組}}:$1",
        "specialmute-success": "您的遮蓋偏好設定已更新。可在[[Special:Preferences|您的偏好設定]]查看所有遮蓋掉的使用者。",
        "specialmute-submit": "確認",
        "specialmute-label-mute-email": "遮蓋來自此使用者的郵件",
-       "specialmute-header": "請選擇您對於{{BIDI:[[User:$1]]}}的遮蓋偏好設定。",
+       "specialmute-header": "請選擇您對於<b>{{BIDI:[[User:$1]]}}</b>的遮蓋偏好設定。",
        "specialmute-error-invalid-user": "無法找到請求的使用者名稱。",
-       "specialmute-error-email-blacklist-disabled": "未啟用遮蓋掉使用者發送電子郵件給您的功能。",
-       "specialmute-error-email-preferences": "在您遮蓋使用者之前,您必須確認您的電子郵件地址。您可以在[[Special:Preferences|偏好設定]]進行。",
        "specialmute-email-footer": "要管理{{BIDI:$2}}的電子郵件偏好設定,請查看<$1>。",
        "specialmute-login-required": "請登入以變更您的遮蓋偏好設定。",
        "revid": "修訂 $1",
index e1ea247..4cc52a4 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 require_once __DIR__ . '/Maintenance.php';
 
 /**
@@ -67,9 +69,9 @@ class CleanupSpam extends Maintenance {
                        // Clean up spam on all wikis
                        $this->output( "Finding spam on " . count( $wgLocalDatabases ) . " wikis\n" );
                        $found = false;
-                       foreach ( $wgLocalDatabases as $wikiID ) {
+                       foreach ( $wgLocalDatabases as $wikiId ) {
                                /** @var Database $dbr */
-                               $dbr = $this->getDB( DB_REPLICA, [], $wikiID );
+                               $dbr = $this->getDB( DB_REPLICA, [], $wikiId );
 
                                foreach ( $protConds as $conds ) {
                                        $count = $dbr->selectField(
@@ -82,9 +84,9 @@ class CleanupSpam extends Maintenance {
                                                $found = true;
                                                $cmd = wfShellWikiCmd(
                                                        "$IP/maintenance/cleanupSpam.php",
-                                                       [ '--wiki', $wikiID, $spec ]
+                                                       [ '--wiki', $wikiId, $spec ]
                                                );
-                                               passthru( "$cmd | sed 's/^/$wikiID:  /'" );
+                                               passthru( "$cmd | sed 's/^/$wikiId:  /'" );
                                        }
                                }
                        }
@@ -136,8 +138,8 @@ class CleanupSpam extends Maintenance {
                $rev = Revision::newFromTitle( $title );
                $currentRevId = $rev->getId();
 
-               while ( $rev && ( $rev->isDeleted( Revision::DELETED_TEXT )
-                       || LinkFilter::matchEntry( $rev->getContent( Revision::RAW ), $domain, $protocol ) )
+               while ( $rev && ( $rev->isDeleted( RevisionRecord::DELETED_TEXT )
+                       || LinkFilter::matchEntry( $rev->getContent( RevisionRecord::RAW ), $domain, $protocol ) )
                ) {
                        $rev = $rev->getPrevious();
                }
@@ -152,7 +154,7 @@ class CleanupSpam extends Maintenance {
                        $page = WikiPage::factory( $title );
                        if ( $rev ) {
                                // Revert to this revision
-                               $content = $rev->getContent( Revision::RAW );
+                               $content = $rev->getContent( RevisionRecord::RAW );
 
                                $this->output( "reverting\n" );
                                $page->doEditContent(
index 8579f0f..45c66ae 100644 (file)
@@ -44,10 +44,10 @@ class ClearInterwikiCache extends Maintenance {
                        $prefixes[] = $row->iw_prefix;
                }
 
-               foreach ( $wgLocalDatabases as $db ) {
-                       $this->output( "$db..." );
+               foreach ( $wgLocalDatabases as $wikiId ) {
+                       $this->output( "$wikiId..." );
                        foreach ( $prefixes as $prefix ) {
-                               $wgMemc->delete( "$db:interwiki:$prefix" );
+                               $wgMemc->delete( "$wikiId:interwiki:$prefix" );
                        }
                        $this->output( "done\n" );
                }
index dc70e9c..0e96142 100644 (file)
@@ -57,8 +57,9 @@ class CopyJobQueue extends Maintenance {
                        ? JobQueueGroup::singleton()->getQueueTypes()
                        : [ $this->getOption( 'type' ) ];
 
+               $dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
                foreach ( $types as $type ) {
-                       $baseConfig = [ 'type' => $type, 'wiki' => wfWikiID() ];
+                       $baseConfig = [ 'type' => $type, 'domain' => $dbDomain ];
                        $src = JobQueue::factory( $baseConfig + $wgJobQueueMigrationConfig[$srcKey] );
                        $dst = JobQueue::factory( $baseConfig + $wgJobQueueMigrationConfig[$dstKey] );
 
index aa9cb2e..71a15bc 100644 (file)
@@ -2843,7 +2843,6 @@ notvisiblerev
 notwatched
 notwikitext
 notype
-noudp
 noupdates
 nouploadmodule
 nouser
index cb4eddf..d3d76ac 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\Revision\RevisionRecord;
+
 require_once __DIR__ . '/Maintenance.php';
 
 /**
@@ -79,7 +81,7 @@ class FixDefaultJsonContentPages extends LoggedUpdateMaintenance {
                $title = Title::makeTitle( $row->page_namespace, $row->page_title );
                $this->output( "Processing {$title} ({$row->page_id})...\n" );
                $rev = Revision::newFromTitle( $title );
-               $content = $rev->getContent( Revision::RAW );
+               $content = $rev->getContent( RevisionRecord::RAW );
                $dbw = $this->getDB( DB_MASTER );
                if ( $content instanceof JsonContent ) {
                        if ( $content->isValid() ) {
index 05dd0d0..aef45bf 100644 (file)
@@ -188,18 +188,20 @@ class GenerateSitemap extends Maintenance {
                        $this->fatalError( "Can not create directory $fspath." );
                }
 
+               $dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
                $this->fspath = realpath( $fspath ) . DIRECTORY_SEPARATOR;
                $this->urlpath = $this->getOption( 'urlpath', "" );
                if ( $this->urlpath !== "" && substr( $this->urlpath, -1 ) !== '/' ) {
                        $this->urlpath .= '/';
                }
-               $this->identifier = $this->getOption( 'identifier', wfWikiID() );
+               $this->identifier = $this->getOption( 'identifier', $dbDomain );
                $this->compress = $this->getOption( 'compress', 'yes' ) !== 'no';
                $this->skipRedirects = $this->hasOption( 'skip-redirects' );
                $this->dbr = $this->getDB( DB_REPLICA );
                $this->generateNamespaces();
                $this->timestamp = wfTimestamp( TS_ISO_8601, wfTimestampNow() );
-               $this->findex = fopen( "{$this->fspath}sitemap-index-{$this->identifier}.xml", 'wb' );
+               $encIdentifier = rawurlencode( $this->identifier );
+               $this->findex = fopen( "{$this->fspath}sitemap-index-{$encIdentifier}.xml", 'wb' );
                $this->main();
        }
 
index 2e8cf77..ca67c83 100644 (file)
@@ -23,6 +23,8 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\Storage\RevisionRecord;
+
 require_once __DIR__ . '/Maintenance.php';
 
 /**
@@ -51,8 +53,8 @@ class GetTextMaint extends Maintenance {
                        $this->fatalError( "Page $titleText does not exist.\n" );
                }
                $content = $rev->getContent( $this->hasOption( 'show-private' )
-                       ? Revision::RAW
-                       : Revision::FOR_PUBLIC );
+                       ? RevisionRecord::RAW
+                       : RevisionRecord::FOR_PUBLIC );
 
                if ( $content === false ) {
                        $titleText = $title->getPrefixedText();
index c6738bc..f9b3951 100644 (file)
@@ -759,6 +759,7 @@ TEXT
        function openSpawn() {
                global $IP;
 
+               $wiki = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
                if ( count( $this->php ) == 2 ) {
                        $mwscriptpath = $this->php[1];
                } else {
@@ -771,14 +772,14 @@ TEXT
                                                $this->php[0],
                                                $mwscriptpath,
                                                "fetchText.php",
-                                               '--wiki', wfWikiID() ] ) );
+                                               '--wiki', $wiki ] ) );
                } else {
                        $cmd = implode( " ",
                                array_map( [ Shell::class, 'escape' ],
                                        [
                                                $this->php[0],
                                                "$IP/maintenance/fetchText.php",
-                                               '--wiki', wfWikiID() ] ) );
+                                               '--wiki', $wiki ] ) );
                }
                $spec = [
                        0 => [ "pipe", "r" ],
index 333b8b9..5024395 100644 (file)
@@ -28,6 +28,7 @@ require_once __DIR__ . '/Maintenance.php';
 
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IResultWrapper;
 use Wikimedia\Rdbms\IMaintainableDatabase;
 
@@ -558,8 +559,12 @@ class NamespaceDupes extends Maintenance {
         * @return bool
         */
        private function canMerge( $id, LinkTarget $linkTarget, &$logStatus ) {
-               $latestDest = Revision::newFromTitle( $linkTarget, 0, Revision::READ_LATEST );
-               $latestSource = Revision::newFromPageId( $id, 0, Revision::READ_LATEST );
+               $latestDest = Revision::newFromTitle(
+                       $linkTarget, 0, RevisionRecord::READ_LATEST
+               );
+               $latestSource = Revision::newFromPageId(
+                       $id, 0, RevisionRecord::READ_LATEST
+               );
                if ( $latestSource->getTimestamp() > $latestDest->getTimestamp() ) {
                        $logStatus = 'cannot merge since source is later';
                        return false;
index dcb89d1..e48b6ab 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IDatabase;
 
 require_once __DIR__ . '/Maintenance.php';
@@ -144,7 +145,7 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance {
                        ? Revision::newFromArchiveRow( $row )
                        : new Revision( $row );
 
-               $content = $rev->getContent( Revision::RAW );
+               $content = $rev->getContent( RevisionRecord::RAW );
                if ( !$content ) {
                        # This should not happen, but sometimes does (T22757)
                        $id = $row->$idCol;
index a62e019..b9e084e 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 
 require_once __DIR__ . '/dumpIterator.php';
 
@@ -81,7 +82,7 @@ class PreprocessDump extends DumpIterator {
         * @param Revision $rev
         */
        public function processRevision( $rev ) {
-               $content = $rev->getContent( Revision::RAW );
+               $content = $rev->getContent( RevisionRecord::RAW );
 
                if ( $content->getModel() !== CONTENT_MODEL_WIKITEXT ) {
                        return;
index 8306243..3f48abb 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\RevisionRecord;
 use Wikimedia\Rdbms\IDatabase;
 
 require_once __DIR__ . '/Maintenance.php';
@@ -231,7 +232,7 @@ class RefreshLinks extends Maintenance {
                }
 
                $rt = null;
-               $content = $page->getContent( Revision::RAW );
+               $content = $page->getContent( RevisionRecord::RAW );
                if ( $content !== null ) {
                        $rt = $content->getUltimateRedirectTarget();
                }
index c2fa687..d8a8808 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\RevisionRecord;
 use MediaWiki\Shell\Shell;
 
 if ( !defined( 'MEDIAWIKI' ) ) {
@@ -523,7 +524,7 @@ class CheckStorage {
 
        function importRevision( &$revision, &$importer ) {
                $id = $revision->getID();
-               $content = $revision->getContent( Revision::RAW );
+               $content = $revision->getContent( RevisionRecord::RAW );
                $id = $id ?: '';
 
                if ( $content === null ) {
index 8a8f4d8..6fd53cc 100644 (file)
@@ -218,6 +218,8 @@ class RecompressTracked {
         * writing are all slow.
         */
        function startReplicaProcs() {
+               $wiki = WikiMap::getWikiIdFromDbDomain( WikiMap::getCurrentWikiDbDomain() );
+
                $cmd = 'php ' . Shell::escape( __FILE__ );
                foreach ( self::$cmdLineOptionMap as $cmdOption => $classOption ) {
                        if ( $cmdOption == 'replica-id' ) {
@@ -229,7 +231,7 @@ class RecompressTracked {
                        }
                }
                $cmd .= ' --child' .
-                       ' --wiki ' . Shell::escape( wfWikiID() ) .
+                       ' --wiki ' . Shell::escape( $wiki ) .
                        ' ' . Shell::escape( ...$this->destClusters );
 
                $this->replicaPipes = $this->replicaProcs = [];
index f759c13..5f7f9d5 100644 (file)
@@ -45,7 +45,6 @@ class UserDupes {
        private $outputCallback;
 
        /**
-        * UserDupes constructor.
         * @param IMaintainableDatabase &$database
         * @param callback $outputCallback
         */
index 4c9dcb4..98f1c24 100644 (file)
@@ -107,16 +107,14 @@ The new option is NOT validated.' );
 
                                $userValue = $user->getOption( $option );
                                if ( $userValue <> $defaultOptions[$option] ) {
-                                       // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
-                                       @$ret[$option][$userValue]++;
+                                       $ret[$option][$userValue] = ( $ret[$option][$userValue] ?? 0 ) + 1;
                                }
                        } else {
 
                                foreach ( $defaultOptions as $name => $defaultValue ) {
                                        $userValue = $user->getOption( $name );
                                        if ( $userValue != $defaultValue ) {
-                                               // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
-                                               @$ret[$name][$userValue]++;
+                                               $ret[$option][$userValue] = ( $ret[$option][$userValue] ?? 0 ) + 1;
                                        }
                                }
                        }
index 671369a..8683eed 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Maintenance
  */
 
+use MediaWiki\Revision\RevisionRecord;
+
 require_once __DIR__ . '/Maintenance.php';
 
 /**
@@ -43,7 +45,7 @@ class ViewCLI extends Maintenance {
 
                $page = WikiPage::factory( $title );
 
-               $content = $page->getContent( Revision::RAW );
+               $content = $page->getContent( RevisionRecord::RAW );
                if ( !$content ) {
                        $this->fatalError( "Page has no content" );
                }
index 9455994..0c2df6b 100644 (file)
@@ -1968,6 +1968,8 @@ return [
                'lessMessages' => [
                        'parentheses-start',
                        'parentheses-end',
+                       'brackets-start',
+                       'brackets-end',
                        'pipe-separator'
                ],
                'skinStyles' => [
index 5d18fdf..09998da 100644 (file)
@@ -249,8 +249,8 @@ oojs-router:
 
 ooui:
   type: tar
-  src: https://registry.npmjs.org/oojs-ui/-/oojs-ui-0.33.3.tgz
-  integrity: sha384-eM78ktDU9DG7WIjxnAHWUsPa9VHCaltqLya4afg0C10gd+c5c5q9NJSnNdFgy76J
+  src: https://registry.npmjs.org/oojs-ui/-/oojs-ui-0.33.4.tgz
+  integrity: sha384-ZqQ9VxkRqt444Xthv89HNZB1PyM1SmNz+7gnC2HfaXUtBh+coJdXv7JxlaBjAouq
 
   dest:
     # Main stuff
index 60ef70c..c913a1d 100644 (file)
@@ -1,4 +1,11 @@
 # OOUI Release History
+## v0.33.4 / 2019-07-22
+### Styles
+* Frameless buttons should feature hover and active states (Volker E.)
+* Revert "WikimediaUI theme: Apply primary flag to ButtonWidget (frameless)" (Volker E.)
+* icons: Add 'bellOutline' and 'userAvatarOutline' and amend 'search' (Volker E.)
+
+
 ## v0.33.3 / 2019-07-16
 ### Styles
 * MessageWidget: Apply `bold` only to inline message types (Volker E.)
index b7f3f10..2a1984d 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:36Z
+ * Date: 2019-07-23T03:23:32Z
  */
 ( function ( OO ) {
 
index 5fe630e..e664153 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:43Z
+ * Date: 2019-07-23T03:23:40Z
  */
 .oo-ui-element-hidden {
   display: none !important;
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
   color: #000;
 }
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover {
+  background-color: #fafafa;
+  color: #000;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:active {
+  background-color: #ddd;
+  color: #000;
+}
 .oo-ui-buttonElement-frameless.oo-ui-labelElement:first-child,
 .oo-ui-buttonElement-frameless.oo-ui-iconElement:first-child {
   margin-left: -0.3125em;
index ccbda55..2b45f4e 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:43Z
+ * Date: 2019-07-23T03:23:40Z
  */
 .oo-ui-element-hidden {
   display: none !important;
   color: #222;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button:hover {
+  background-color: #f8f9fa;
+  color: #000;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active {
+  background-color: #eaecf0;
   color: #444;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-iconElement > .oo-ui-buttonElement-button:focus,
   color: #b32424;
   box-shadow: none;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
-  color: #fff;
-  background-color: #36c;
-  border-color: #36c;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
-  background-color: #447ff5;
-  border-color: #447ff5;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active:focus,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-popupToolGroup-active > .oo-ui-buttonElement-button {
-  color: #fff;
-  background-color: #2a4b8d;
-  border-color: #2a4b8d;
-  box-shadow: none;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:focus {
-  border-color: #36c;
-  box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
-  color: #fff;
-  background-color: #d33;
-  border-color: #d33;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
-  background-color: #ff4242;
-  border-color: #ff4242;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active:focus,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-popupToolGroup-active > .oo-ui-buttonElement-button {
-  color: #fff;
-  background-color: #b32424;
-  border-color: #b32424;
-  box-shadow: none;
-}
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:focus {
-  border-color: #d33;
-  box-shadow: inset 0 0 0 1px #d33, inset 0 0 0 2px #fff;
-}
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled[class*='oo-ui-flaggedElement'] > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
   opacity: 1;
   padding-top: 1.42857143em;
   padding-right: 0;
 }
+.oo-ui-fieldLayout .oo-ui-fieldLayout-help .oo-ui-buttonElement-button:hover,
+.oo-ui-fieldLayout .oo-ui-fieldLayout-help .oo-ui-buttonElement-button:active {
+  background-color: transparent;
+}
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > .oo-ui-inline-help {
   margin-top: 0.28571429em;
 }
@@ -788,6 +751,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   padding-top: 1.42857143em;
   padding-right: 0;
 }
+.oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-help .oo-ui-buttonElement-button:hover,
+.oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-help .oo-ui-buttonElement-button:active {
+  background-color: transparent;
+}
 
 .oo-ui-formLayout + .oo-ui-fieldsetLayout,
 .oo-ui-formLayout + .oo-ui-formLayout {
index 213540f..a0bc401 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:36Z
+ * Date: 2019-07-23T03:23:32Z
  */
 ( function ( OO ) {
 
index d1db776..7b84493 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:43Z
+ * Date: 2019-07-23T03:23:40Z
  */
 .oo-ui-tool > .oo-ui-tool-link > .oo-ui-tool-checkIcon {
   display: none;
index cf0245d..63a3784 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:43Z
+ * Date: 2019-07-23T03:23:40Z
  */
 .oo-ui-tool {
   -webkit-box-sizing: border-box;
index d2a22ff..02b796d 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:36Z
+ * Date: 2019-07-23T03:23:32Z
  */
 ( function ( OO ) {
 
index e9845f3..eefee7b 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:43Z
+ * Date: 2019-07-23T03:23:40Z
  */
 .oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
   cursor: move;
index 8305107..fb59c44 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:43Z
+ * Date: 2019-07-23T03:23:40Z
  */
 .oo-ui-draggableElement-handle:not( .oo-ui-draggableElement-undraggable ).oo-ui-widget {
   cursor: move;
index 722f6dd..1f5ca65 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:36Z
+ * Date: 2019-07-23T03:23:32Z
  */
 ( function ( OO ) {
 
index 56f7ea4..7a67cce 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:36Z
+ * Date: 2019-07-23T03:23:32Z
  */
 ( function ( OO ) {
 
index b54b053..f0c4b64 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:43Z
+ * Date: 2019-07-23T03:23:40Z
  */
 
 .oo-ui-window {
index a80f293..617599d 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:43Z
+ * Date: 2019-07-23T03:23:40Z
  */
 
 .oo-ui-window {
index de7e45d..d6f9989 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOUI v0.33.3
+ * OOUI v0.33.4
  * https://www.mediawiki.org/wiki/OOUI
  *
  * Copyright 2011–2019 OOUI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2019-07-16T21:33:36Z
+ * Date: 2019-07-23T03:23:32Z
  */
 ( function ( OO ) {
 
index 8e440cb..c8111a2 100644 (file)
@@ -8,6 +8,9 @@
                "bell": {
                        "file": "../wikimediaui/images/icons/bell.svg"
                },
+               "bellOutline": {
+                       "file": "../wikimediaui/images/icons/bellOutline.svg"
+               },
                "error": {
                        "file": "../wikimediaui/images/icons/error.svg"
                },
index 89b38b5..e13bb1d 100644 (file)
@@ -8,6 +8,9 @@
                "userAvatar": {
                        "file": "../wikimediaui/images/icons/userAvatar.svg"
                },
+               "userAvatarOutline": {
+                       "file": "../wikimediaui/images/icons/userAvatarOutline.svg"
+               },
                "userTalk": {
                        "file": {
                                "ltr": "../wikimediaui/images/icons/userTalk-ltr.svg",
index 2b315c8..627c6ef 100644 (file)
@@ -34,6 +34,9 @@
                "bell": {
                        "file": "images/icons/bell.svg"
                },
+               "bellOutline": {
+                       "file": "images/icons/bellOutline.svg"
+               },
                "error": {
                        "file": "images/icons/error.svg",
                        "variants": [
index 0e4fe16..7266d34 100644 (file)
@@ -31,6 +31,9 @@
                "userAvatar": {
                        "file": "images/icons/userAvatar.svg"
                },
+               "userAvatarOutline": {
+                       "file": "images/icons/userAvatarOutline.svg"
+               },
                "userTalk": {
                        "file": {
                                "ltr": "images/icons/userTalk-ltr.svg",
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-invert.png
new file mode 100644 (file)
index 0000000..65a31fb
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-invert.svg
new file mode 100644 (file)
index 0000000..b1b7c8a
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bell</title><path fill="#fff" fill-rule="evenodd" d="M11.5 2.19C14.09 2.86 16 5.2 16 8v6l2 2v1H2v-1l2-2V8c0-2.8 1.91-5.14 4.5-5.81V1.5C8.5.67 9.17 0 10 0s1.5.67 1.5 1.5v.69zM10 4C7.79 4 6 5.79 6 8v7h8V8c0-2.21-1.79-4-4-4zM8 18h4c0 1.1-.9 2-2 2s-2-.9-2-2z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-progressive.png
new file mode 100644 (file)
index 0000000..984c582
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline-progressive.svg
new file mode 100644 (file)
index 0000000..4525006
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bell</title><path fill="#36c" fill-rule="evenodd" d="M11.5 2.19C14.09 2.86 16 5.2 16 8v6l2 2v1H2v-1l2-2V8c0-2.8 1.91-5.14 4.5-5.81V1.5C8.5.67 9.17 0 10 0s1.5.67 1.5 1.5v.69zM10 4C7.79 4 6 5.79 6 8v7h8V8c0-2.21-1.79-4-4-4zM8 18h4c0 1.1-.9 2-2 2s-2-.9-2-2z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline.png b/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline.png
new file mode 100644 (file)
index 0000000..c5ac8fb
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/bellOutline.svg
new file mode 100644 (file)
index 0000000..3d6a721
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bell</title><path fill-rule="evenodd" d="M11.5 2.19C14.09 2.86 16 5.2 16 8v6l2 2v1H2v-1l2-2V8c0-2.8 1.91-5.14 4.5-5.81V1.5C8.5.67 9.17 0 10 0s1.5.67 1.5 1.5v.69zM10 4C7.79 4 6 5.79 6 8v7h8V8c0-2.21-1.79-4-4-4zM8 18h4c0 1.1-.9 2-2 2s-2-.9-2-2z"/></svg>
\ No newline at end of file
index 91dc0c4..75a663c 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/search-invert.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/search-invert.png differ
index 16c3438..f736c95 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search</title><path fill="#fff" d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.5 4.5 0 0 1 3.5 8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search</title><path fill="#fff" d="M7.5 13c3.04 0 5.5-2.46 5.5-5.5S10.54 2 7.5 2 2 4.46 2 7.5 4.46 13 7.5 13zm4.55.46A7.432 7.432 0 0 1 7.5 15C3.36 15 0 11.64 0 7.5S3.36 0 7.5 0C11.64 0 15 3.36 15 7.5c0 1.71-.57 3.29-1.54 4.55l6.49 6.49-1.41 1.41-6.49-6.49z"/></svg>
\ No newline at end of file
index e410eca..5644489 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/search-progressive.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/search-progressive.png differ
index 789999d..4c5ed6f 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search</title><path fill="#36c" d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.5 4.5 0 0 1 3.5 8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search</title><path fill="#36c" d="M7.5 13c3.04 0 5.5-2.46 5.5-5.5S10.54 2 7.5 2 2 4.46 2 7.5 4.46 13 7.5 13zm4.55.46A7.432 7.432 0 0 1 7.5 15C3.36 15 0 11.64 0 7.5S3.36 0 7.5 0C11.64 0 15 3.36 15 7.5c0 1.71-.57 3.29-1.54 4.55l6.49 6.49-1.41 1.41-6.49-6.49z"/></svg>
\ No newline at end of file
index fe88ca2..e633273 100644 (file)
Binary files a/resources/lib/ooui/themes/wikimediaui/images/icons/search.png and b/resources/lib/ooui/themes/wikimediaui/images/icons/search.png differ
index 293f53f..b304da6 100644 (file)
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search</title><path d="M19 17l-5.15-5.15a7 7 0 1 0-2 2L17 19zM3.5 8A4.5 4.5 0 1 1 8 12.5 4.5 4.5 0 0 1 3.5 8z"/></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>search</title><path d="M7.5 13c3.04 0 5.5-2.46 5.5-5.5S10.54 2 7.5 2 2 4.46 2 7.5 4.46 13 7.5 13zm4.55.46A7.432 7.432 0 0 1 7.5 15C3.36 15 0 11.64 0 7.5S3.36 0 7.5 0C11.64 0 15 3.36 15 7.5c0 1.71-.57 3.29-1.54 4.55l6.49 6.49-1.41 1.41-6.49-6.49z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.png b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.png
new file mode 100644 (file)
index 0000000..b5689de
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-invert.svg
new file mode 100644 (file)
index 0000000..3db6aca
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>user avatar</title><path fill="#fff" d="M10 8c1.7 0 3.06-1.35 3.06-3S11.7 2 10 2 6.94 3.35 6.94 5 8.3 8 10 8zm0 2c-2.8 0-5.06-2.24-5.06-5S7.2 0 10 0s5.06 2.24 5.06 5-2.26 5-5.06 5zm-7 8h14v-1.33c0-1.75-2.31-3.56-7-3.56s-7 1.81-7 3.56V18zm7-6.89c6.66 0 9 3.33 9 5.56V20H1v-3.33c0-2.23 2.34-5.56 9-5.56z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.png b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.png
new file mode 100644 (file)
index 0000000..5bb95db
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline-progressive.svg
new file mode 100644 (file)
index 0000000..c14e3e7
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>user avatar</title><path fill="#36c" d="M10 8c1.7 0 3.06-1.35 3.06-3S11.7 2 10 2 6.94 3.35 6.94 5 8.3 8 10 8zm0 2c-2.8 0-5.06-2.24-5.06-5S7.2 0 10 0s5.06 2.24 5.06 5-2.26 5-5.06 5zm-7 8h14v-1.33c0-1.75-2.31-3.56-7-3.56s-7 1.81-7 3.56V18zm7-6.89c6.66 0 9 3.33 9 5.56V20H1v-3.33c0-2.23 2.34-5.56 9-5.56z"/></svg>
\ No newline at end of file
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.png b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.png
new file mode 100644 (file)
index 0000000..cd9b4fe
Binary files /dev/null and b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.png differ
diff --git a/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.svg b/resources/lib/ooui/themes/wikimediaui/images/icons/userAvatarOutline.svg
new file mode 100644 (file)
index 0000000..1f0d41d
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>user avatar</title><path d="M10 8c1.7 0 3.06-1.35 3.06-3S11.7 2 10 2 6.94 3.35 6.94 5 8.3 8 10 8zm0 2c-2.8 0-5.06-2.24-5.06-5S7.2 0 10 0s5.06 2.24 5.06 5-2.26 5-5.06 5zm-7 8h14v-1.33c0-1.75-2.31-3.56-7-3.56s-7 1.81-7 3.56V18zm7-6.89c6.66 0 9 3.33 9 5.56V20H1v-3.33c0-2.23 2.34-5.56 9-5.56z"/></svg>
\ No newline at end of file
index a0e9f15..59eca6b 100644 (file)
@@ -8,6 +8,16 @@
        content: '. .';
 }
 
+.mw-rollback-link {
+       &:before {
+               content: '@{msg-brackets-start}';
+       }
+
+       &:after {
+               content: '@{msg-brackets-end}';
+       }
+}
+
 /* stylelint-disable-next-line selector-class-pattern */
 .comment--without-parentheses,
 .mw-changeslist-links,
        > span:not( :first-child ):before {
                content: '@{msg-pipe-separator}';
        }
+
+       // In pages like history, do not add additional brackets where not needed
+       .mw-rollback-link:before,
+       .mw-rollback-link:after {
+               content: '';
+       }
 }
index 2d141e6..83e8d85 100644 (file)
@@ -1468,7 +1468,7 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                        $rev->getPage(),
                        $rev->getId()
                );
-               $cache->delete( $key, WANObjectCache::HOLDOFF_NONE );
+               $cache->delete( $key, WANObjectCache::HOLDOFF_TTL_NONE );
                $this->assertFalse( $cache->get( $key ) );
 
                ++$now;
diff --git a/tests/phpunit/includes/api/ApiCSPReportTest.php b/tests/phpunit/includes/api/ApiCSPReportTest.php
new file mode 100644 (file)
index 0000000..b3e0543
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+
+/**
+ * @group API
+ * @group medium
+ * @covers ApiCSPReport
+ */
+class ApiCSPReportTest extends MediaWikiIntegrationTestCase {
+
+       public function setUp() {
+               parent::setUp();
+               $this->setMwGlobals( [
+                       'CSPFalsePositiveUrls' => [],
+               ] );
+       }
+
+       public function testInternalReportonly() {
+               $params = [
+                       'reportonly' => '1',
+                       'source' => 'internal',
+               ];
+               $cspReport = [
+                       'document-uri' => 'https://doc.test/path',
+                       'referrer' => 'https://referrer.test/path',
+                       'violated-directive' => 'connet-src',
+                       'disposition' => 'report',
+                       'blocked-uri' => 'https://blocked.test/path?query',
+                       'line-number' => 4,
+                       'column-number' => 2,
+                       'source-file' => 'https://source.test/path?query',
+               ];
+
+               $log = $this->doExecute( $params, $cspReport );
+
+               $this->assertEquals(
+                       [
+                               [
+                                       '[report-only] Received CSP report: ' .
+                                               '<https://blocked.test> blocked from being loaded on <https://doc.test/path>:4',
+                                       [
+                                               'method' => 'ApiCSPReport::execute',
+                                               'user_id' => 'logged-out',
+                                               'user-agent' => 'Test/0.0',
+                                               'source' => 'internal'
+                                       ]
+                               ],
+                       ],
+                       $log,
+                       'logged messages'
+               );
+       }
+
+       public function testFalsePositiveOriginMatch() {
+               $params = [
+                       'reportonly' => '1',
+                       'source' => 'internal',
+               ];
+               $cspReport = [
+                       'document-uri' => 'https://doc.test/path',
+                       'referrer' => 'https://referrer.test/path',
+                       'violated-directive' => 'connet-src',
+                       'disposition' => 'report',
+                       'blocked-uri' => 'https://blocked.test/path/file?query',
+                       'line-number' => 4,
+                       'column-number' => 2,
+                       'source-file' => 'https://source.test/path/file?query',
+               ];
+
+               $this->setMwGlobals( [
+                       'wgCSPFalsePositiveUrls' => [
+                               'https://blocked.test/path/' => true,
+                       ],
+               ] );
+               $log = $this->doExecute( $params, $cspReport );
+
+               $this->assertSame(
+                       [],
+                       $log,
+                       'logged messages'
+               );
+       }
+
+       private function doExecute( array $params, array $cspReport ) {
+               $log = [];
+               $logger = $this->createMock( Psr\Log\AbstractLogger::class );
+               $logger->method( 'warning' )->will( $this->returnCallback(
+                       function ( $msg, $ctx ) use ( &$log ) {
+                               unset( $ctx['csp-report'] );
+                               $log[] = [ $msg, $ctx ];
+                       }
+               ) );
+               $this->setLogger( 'csp-report-only', $logger );
+
+               $postBody = json_encode( [ 'csp-report' => $cspReport ] );
+               $req = $this->getMockBuilder( FauxRequest::class )
+                       ->setMethods( [ 'getRawInput' ] )
+                       ->setConstructorArgs( [ $params, /* $wasPosted */ true ] )
+                       ->getMock();
+               $req->method( 'getRawInput' )->willReturn( $postBody );
+               $req->setHeaders( [
+                       'Content-Type' => 'application/csp-report',
+                       'User-Agent' => 'Test/0.0'
+               ] );
+
+               $api = $this->getMockBuilder( ApiCSPReport::class )
+                       ->disableOriginalConstructor()
+                       ->setMethods( [ 'getParameter', 'getRequest', 'getResult' ] )
+                       ->getMock();
+               $api->method( 'getParameter' )->will( $this->returnCallback(
+                       function ( $key ) use ( $req ) {
+                               return $req->getRawVal( $key );
+                       }
+               ) );
+               $api->method( 'getRequest' )->willReturn( $req );
+               $api->method( 'getResult' )->willReturn( new ApiResult( false ) );
+
+               $api->execute();
+               return $log;
+       }
+}
index 708ebc5..93c5345 100644 (file)
@@ -54,7 +54,7 @@ class ApiQuerySearchTest extends ApiTestCase {
                        'one wiki response' => [
                                [ 'utwiki' => [ 'Qwerty' ] ],
                                [
-                                       SearchResultSet::SECONDARY_RESULTS => [
+                                       ISearchResultSet::SECONDARY_RESULTS => [
                                                'utwiki' => new MockSearchResultSet( [
                                                        $this->mockResultClosure(
                                                                'Qwerty',
index fe3bb88..b8f60c4 100644 (file)
@@ -2,9 +2,11 @@
 
 use MediaWiki\Block\BlockManager;
 use MediaWiki\Block\DatabaseBlock;
+use MediaWiki\Block\CompositeBlock;
 use MediaWiki\Block\SystemBlock;
 use MediaWiki\Config\ServiceOptions;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\TestingAccessWrapper;
 
 /**
  * @group Blocking
@@ -63,26 +65,23 @@ class BlockManagerTest extends MediaWikiTestCase {
         * @covers ::shouldApplyCookieBlock
         */
        public function testGetBlockFromCookieValue( $options, $expected ) {
-               $blockManager = $this->getBlockManager( [
-                       'wgCookieSetOnAutoblock' => true,
-                       'wgCookieSetOnIpBlock' => true,
-               ] );
+               $blockManager = TestingAccessWrapper::newFromObject(
+                       $this->getBlockManager( [
+                               'wgCookieSetOnAutoblock' => true,
+                               'wgCookieSetOnIpBlock' => true,
+                       ] )
+               );
 
                $block = new DatabaseBlock( array_merge( [
-                       'address' => $options[ 'target' ] ?: $this->user,
+                       'address' => $options['target'] ?: $this->user,
                        'by' => $this->sysopId,
-               ], $options[ 'blockOptions' ] ) );
+               ], $options['blockOptions'] ) );
                $block->insert();
 
-               $class = new ReflectionClass( BlockManager::class );
-               $method = $class->getMethod( 'getBlockFromCookieValue' );
-               $method->setAccessible( true );
-
-               $user = $options[ 'loggedIn' ] ? $this->user : new User();
+               $user = $options['loggedIn'] ? $this->user : new User();
                $user->getRequest()->setCookie( 'BlockID', $block->getCookieValue() );
 
-               $this->assertSame( $expected, (bool)$method->invoke(
-                       $blockManager,
+               $this->assertSame( $expected, (bool)$blockManager->getBlockFromCookieValue(
                        $user,
                        $user->getRequest()
                ) );
@@ -142,16 +141,14 @@ class BlockManagerTest extends MediaWikiTestCase {
         * @covers ::isLocallyBlockedProxy
         */
        public function testIsLocallyBlockedProxy( $proxyList, $expected ) {
-               $class = new ReflectionClass( BlockManager::class );
-               $method = $class->getMethod( 'isLocallyBlockedProxy' );
-               $method->setAccessible( true );
-
-               $blockManager = $this->getBlockManager( [
-                       'wgProxyList' => $proxyList
-               ] );
+               $blockManager = TestingAccessWrapper::newFromObject(
+                       $this->getBlockManager( [
+                               'wgProxyList' => $proxyList
+                       ] )
+               );
 
                $ip = '1.2.3.4';
-               $this->assertSame( $expected, $method->invoke( $blockManager, $ip ) );
+               $this->assertSame( $expected, $blockManager->isLocallyBlockedProxy( $ip ) );
        }
 
        public static function provideIsLocallyBlockedProxy() {
@@ -174,16 +171,14 @@ class BlockManagerTest extends MediaWikiTestCase {
                        'addresses in keys: ' . $proxy . ', please move them to values)'
                );
 
-               $class = new ReflectionClass( BlockManager::class );
-               $method = $class->getMethod( 'isLocallyBlockedProxy' );
-               $method->setAccessible( true );
-
-               $blockManager = $this->getBlockManager( [
-                       'wgProxyList' => [ $proxy => 'test' ]
-               ] );
+               $blockManager = TestingAccessWrapper::newFromObject(
+                       $this->getBlockManager( [
+                               'wgProxyList' => [ $proxy => 'test' ]
+                       ] )
+               );
 
                $ip = '1.2.3.4';
-               $this->assertSame( true, $method->invoke( $blockManager, $ip ) );
+               $this->assertTrue( $blockManager->isLocallyBlockedProxy( $ip ) );
        }
 
        /**
@@ -202,9 +197,7 @@ class BlockManagerTest extends MediaWikiTestCase {
                        ->setConstructorArgs( $this->getBlockManagerConstructorArgs( $blockManagerConfig ) )
                        ->setMethods( [ 'checkHost' ] )
                        ->getMock();
-
-               $blockManager->expects( $this->any() )
-                       ->method( 'checkHost' )
+               $blockManager->method( 'checkHost' )
                        ->will( $this->returnValueMap( [ [
                                $options['dnsblQuery'],
                                $options['dnsblResponse'],
@@ -306,89 +299,406 @@ class BlockManagerTest extends MediaWikiTestCase {
        public function testGetUniqueBlocks() {
                $blockId = 100;
 
-               $class = new ReflectionClass( BlockManager::class );
-               $method = $class->getMethod( 'getUniqueBlocks' );
-               $method->setAccessible( true );
-
-               $blockManager = $this->getBlockManager( [] );
+               $blockManager = TestingAccessWrapper::newFromObject( $this->getBlockManager( [] ) );
 
                $block = $this->getMockBuilder( DatabaseBlock::class )
                        ->setMethods( [ 'getId' ] )
                        ->getMock();
-               $block->expects( $this->any() )
-                       ->method( 'getId' )
+               $block->method( 'getId' )
                        ->willReturn( $blockId );
 
                $autoblock = $this->getMockBuilder( DatabaseBlock::class )
                        ->setMethods( [ 'getParentBlockId', 'getType' ] )
                        ->getMock();
-               $autoblock->expects( $this->any() )
-                       ->method( 'getParentBlockId' )
+               $autoblock->method( 'getParentBlockId' )
                        ->willReturn( $blockId );
-               $autoblock->expects( $this->any() )
-                       ->method( 'getType' )
+               $autoblock->method( 'getType' )
                        ->willReturn( DatabaseBlock::TYPE_AUTO );
 
                $blocks = [ $block, $block, $autoblock, new SystemBlock() ];
 
-               $this->assertSame( 2, count( $method->invoke( $blockManager, $blocks ) ) );
+               $this->assertSame( 2, count( $blockManager->getUniqueBlocks( $blocks ) ) );
        }
 
        /**
-        * @covers ::trackBlockWithCookie
         * @dataProvider provideTrackBlockWithCookie
-        * @param bool $expectCookieSet
-        * @param bool $hasCookie
-        * @param bool $isBlocked
+        * @covers ::trackBlockWithCookie
         */
-       public function testTrackBlockWithCookie( $expectCookieSet, $hasCookie, $isBlocked ) {
-               $blockID = 123;
+       public function testTrackBlockWithCookie( $options, $expectedVal ) {
                $this->setMwGlobals( 'wgCookiePrefix', '' );
 
                $request = new FauxRequest();
-               if ( $hasCookie ) {
+               if ( $options['cookieSet'] ) {
                        $request->setCookie( 'BlockID', 'the value does not matter' );
                }
 
-               if ( $isBlocked ) {
-                       $block = $this->getMockBuilder( DatabaseBlock::class )
-                               ->setMethods( [ 'getType', 'getId' ] )
-                               ->getMock();
-                       $block->method( 'getType' )
-                               ->willReturn( DatabaseBlock::TYPE_IP );
-                       $block->method( 'getId' )
-                               ->willReturn( $blockID );
-               } else {
-                       $block = null;
-               }
-
                $user = $this->getMockBuilder( User::class )
                        ->setMethods( [ 'getBlock', 'getRequest' ] )
                        ->getMock();
                $user->method( 'getBlock' )
-                       ->willReturn( $block );
+                       ->willReturn( $options['block'] );
                $user->method( 'getRequest' )
                        ->willReturn( $request );
-               /** @var User $user */
 
                // Although the block cookie is set via DeferredUpdates, in command line mode updates are
                // processed immediately
-               $blockManager = $this->getBlockManager( [] );
+               $blockManager = $this->getBlockManager( [
+                       'wgSecretKey' => '',
+                       'wgCookieSetOnIpBlock' => true,
+               ] );
                $blockManager->trackBlockWithCookie( $user );
 
                /** @var FauxResponse $response */
                $response = $request->response();
-               $this->assertCount( $expectCookieSet ? 1 : 0, $response->getCookies() );
-               $this->assertEquals( $expectCookieSet ? $blockID : null, $response->getCookie( 'BlockID' ) );
+               $this->assertCount( $expectedVal ? 1 : 0, $response->getCookies() );
+               $this->assertEquals( $expectedVal ?: null, $response->getCookie( 'BlockID' ) );
        }
 
        public function provideTrackBlockWithCookie() {
+               $blockId = 123;
+               return [
+                       'Block cookie is already set; there is a trackable block' => [
+                               [
+                                       'cookieSet' => true,
+                                       'block' => $this->getTrackableBlock( $blockId ),
+                               ],
+                               null,
+                       ],
+                       'Block cookie is already set; there is no block' => [
+                               [
+                                       'cookieSet' => true,
+                                       'block' => null,
+                               ],
+                               null,
+                       ],
+                       'Block cookie is not yet set; there is no block' => [
+                               [
+                                       'cookieSet' => false,
+                                       'block' => null,
+                               ],
+                               null,
+                       ],
+                       'Block cookie is not yet set; there is a trackable block' => [
+                               [
+                                       'cookieSet' => false,
+                                       'block' => $this->getTrackableBlock( $blockId ),
+                               ],
+                               $blockId,
+                       ],
+                       'Block cookie is not yet set; there is a composite block with a trackable block' => [
+                               [
+                                       'cookieSet' => false,
+                                       'block' => new CompositeBlock( [
+                                               'originalBlocks' => [
+                                                       new SystemBlock(),
+                                                       $this->getTrackableBlock( $blockId ),
+                                               ]
+                                       ] ),
+                               ],
+                               $blockId,
+                       ],
+                       'Block cookie is not yet set; there is a composite block but no trackable block' => [
+                               [
+                                       'cookieSet' => false,
+                                       'block' => new CompositeBlock( [
+                                               'originalBlocks' => [
+                                                       new SystemBlock(),
+                                                       new SystemBlock(),
+                                               ]
+                                       ] ),
+                               ],
+                               null,
+                       ],
+               ];
+       }
+
+       private function getTrackableBlock( $blockId ) {
+               $block = $this->getMockBuilder( DatabaseBlock::class )
+                       ->setMethods( [ 'getType', 'getId' ] )
+                       ->getMock();
+               $block->method( 'getType' )
+                       ->willReturn( DatabaseBlock::TYPE_IP );
+               $block->method( 'getId' )
+                       ->willReturn( $blockId );
+               return $block;
+       }
+
+       /**
+        * @dataProvider provideSetBlockCookie
+        * @covers ::setBlockCookie
+        */
+       public function testSetBlockCookie( $expiryDelta, $expectedExpiryDelta ) {
+               $this->setMwGlobals( [
+                       'wgCookiePrefix' => '',
+               ] );
+
+               $request = new FauxRequest();
+               $response = $request->response();
+
+               $blockManager = $this->getBlockManager( [
+                       'wgSecretKey' => '',
+                       'wgCookieSetOnIpBlock' => true,
+               ] );
+
+               $now = wfTimestamp();
+
+               $block = new DatabaseBlock( [
+                       'expiry' => $expiryDelta === '' ? '' : $now + $expiryDelta
+               ] );
+               $blockManager->setBlockCookie( $block, $response );
+               $cookies = $response->getCookies();
+
+               $this->assertEquals(
+                       $now + $expectedExpiryDelta,
+                       $cookies['BlockID']['expire'],
+                       '',
+                       60 // Allow actual to be up to 60 seconds later than expected
+               );
+       }
+
+       public static function provideSetBlockCookie() {
+               // Maximum length of a block cookie, defined in BlockManager::setBlockCookie
+               $maxExpiryDelta = ( 24 * 60 * 60 );
+
+               $longExpiryDelta = ( 48 * 60 * 60 );
+               $shortExpiryDelta = ( 12 * 60 * 60 );
+
+               return [
+                       'Block has indefinite expiry' => [
+                               '',
+                               $maxExpiryDelta,
+                       ],
+                       'Block expiry is later than maximum cookie block expiry' => [
+                               $longExpiryDelta,
+                               $maxExpiryDelta,
+                       ],
+                       'Block expiry is sooner than maximum cookie block expiry' => [
+                               $shortExpiryDelta,
+                               $shortExpiryDelta,
+                       ],
+               ];
+       }
+
+       /**
+        * @covers ::shouldTrackBlockWithCookie
+        */
+       public function testShouldTrackBlockWithCookieSystemBlock() {
+               $blockManager = TestingAccessWrapper::newFromObject( $this->getBlockManager( [] ) );
+               $this->assertFalse( $blockManager->shouldTrackBlockWithCookie(
+                       new SystemBlock(),
+                       true
+               ) );
+       }
+
+       /**
+        * @dataProvider provideShouldTrackBlockWithCookie
+        * @covers ::shouldTrackBlockWithCookie
+        */
+       public function testShouldTrackBlockWithCookie( $options, $expected ) {
+               $block = $this->getMockBuilder( DatabaseBlock::class )
+                       ->setMethods( [ 'getType', 'isAutoblocking' ] )
+                       ->getMock();
+               $block->method( 'getType' )
+                       ->willReturn( $options['type'] );
+               if ( isset( $options['autoblocking'] ) ) {
+                       $block->method( 'isAutoblocking' )
+                               ->willReturn( $options['autoblocking'] );
+               }
+
+               $blockManager = TestingAccessWrapper::newFromObject(
+                       $this->getBlockManager( $options['blockManagerConfig'] )
+               );
+
+               $this->assertSame(
+                       $expected,
+                       $blockManager->shouldTrackBlockWithCookie( $block, $options['isAnon'] )
+               );
+       }
+
+       public static function provideShouldTrackBlockWithCookie() {
                return [
-                       // $expectCookieSet, $hasCookie, $isBlocked
-                       [ false, false, false ],
-                       [ false, true, false ],
-                       [ true, false, true ],
-                       [ false, true, true ],
+                       'IP block, anonymous user, IP block cookies enabled' => [
+                               [
+                                       'type' => DatabaseBlock::TYPE_IP,
+                                       'isAnon' => true,
+                                       'blockManagerConfig' => [ 'wgCookieSetOnIpBlock' => true ],
+                               ],
+                               true
+                       ],
+                       'IP range block, anonymous user, IP block cookies enabled' => [
+                               [
+                                       'type' => DatabaseBlock::TYPE_RANGE,
+                                       'isAnon' => true,
+                                       'blockManagerConfig' => [ 'wgCookieSetOnIpBlock' => true ],
+                               ],
+                               true
+                       ],
+                       'IP block, anonymous user, IP block cookies disabled' => [
+                               [
+                                       'type' => DatabaseBlock::TYPE_IP,
+                                       'isAnon' => true,
+                                       'blockManagerConfig' => [ 'wgCookieSetOnIpBlock' => false ],
+                               ],
+                               false
+                       ],
+                       'IP block, logged in user, IP block cookies enabled' => [
+                               [
+                                       'type' => DatabaseBlock::TYPE_IP,
+                                       'isAnon' => false,
+                                       'blockManagerConfig' => [ 'wgCookieSetOnIpBlock' => true ],
+                               ],
+                               false
+                       ],
+                       'User block, anonymous, autoblock cookies enabled, block is autoblocking' => [
+                               [
+                                       'type' => DatabaseBlock::TYPE_USER,
+                                       'isAnon' => true,
+                                       'blockManagerConfig' => [ 'wgCookieSetOnAutoblock' => true ],
+                                       'autoblocking' => true,
+                               ],
+                               false
+                       ],
+                       'User block, logged in, autoblock cookies enabled, block is autoblocking' => [
+                               [
+                                       'type' => DatabaseBlock::TYPE_USER,
+                                       'isAnon' => false,
+                                       'blockManagerConfig' => [ 'wgCookieSetOnAutoblock' => true ],
+                                       'autoblocking' => true,
+                               ],
+                               true
+                       ],
+                       'User block, logged in, autoblock cookies disabled, block is autoblocking' => [
+                               [
+                                       'type' => DatabaseBlock::TYPE_USER,
+                                       'isAnon' => false,
+                                       'blockManagerConfig' => [ 'wgCookieSetOnAutoblock' => false ],
+                                       'autoblocking' => true,
+                               ],
+                               false
+                       ],
+                       'User block, logged in, autoblock cookies enabled, block is not autoblocking' => [
+                               [
+                                       'type' => DatabaseBlock::TYPE_USER,
+                                       'isAnon' => false,
+                                       'blockManagerConfig' => [ 'wgCookieSetOnAutoblock' => true ],
+                                       'autoblocking' => false,
+                               ],
+                               false
+                       ],
+                       'Block type is autoblock' => [
+                               [
+                                       'type' => DatabaseBlock::TYPE_AUTO,
+                                       'isAnon' => true,
+                                       'blockManagerConfig' => [],
+                               ],
+                               false
+                       ]
                ];
        }
+
+       /**
+        * @covers ::clearBlockCookie
+        */
+       public function testClearBlockCookie() {
+               $this->setMwGlobals( [
+                       'wgCookiePrefix' => '',
+               ] );
+
+               $request = new FauxRequest();
+               $response = $request->response();
+               $response->setCookie( 'BlockID', '100' );
+               $this->assertSame( '100', $response->getCookie( 'BlockID' ) );
+
+               BlockManager::clearBlockCookie( $response );
+               $this->assertSame( '', $response->getCookie( 'BlockID' ) );
+       }
+
+       /**
+        * @dataProvider provideGetIdFromCookieValue
+        * @covers ::getIdFromCookieValue
+        */
+       public function testGetIdFromCookieValue( $options, $expected ) {
+               $blockManager = $this->getBlockManager( [
+                       'wgSecretKey' => $options['secretKey']
+               ] );
+               $this->assertEquals(
+                       $expected,
+                       $blockManager->getIdFromCookieValue( $options['cookieValue'] )
+               );
+       }
+
+       public static function provideGetIdFromCookieValue() {
+               $blockId = 100;
+               $secretKey = '123';
+               $hmac = MWCryptHash::hmac( $blockId, $secretKey, false );
+               return [
+                       'No secret key is set' => [
+                               [
+                                       'secretKey' => '',
+                                       'cookieValue' => $blockId,
+                                       'calculatedHmac' => MWCryptHash::hmac( $blockId, '', false ),
+                               ],
+                               $blockId,
+                       ],
+                       'Secret key is set and stored hmac is correct' => [
+                               [
+                                       'secretKey' => $secretKey,
+                                       'cookieValue' => $blockId . '!' . $hmac,
+                                       'calculatedHmac' => $hmac,
+                               ],
+                               $blockId,
+                       ],
+                       'Secret key is set and stored hmac is incorrect' => [
+                               [
+                                       'secretKey' => $secretKey,
+                                       'cookieValue' => $blockId . '!xyz',
+                                       'calculatedHmac' => $hmac,
+                               ],
+                               null,
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetCookieValue
+        * @covers ::getCookieValue
+        */
+       public function testGetCookieValue( $options, $expected ) {
+               $blockManager = $this->getBlockManager( [
+                       'wgSecretKey' => $options['secretKey']
+               ] );
+
+               $block = $this->getMockBuilder( DatabaseBlock::class )
+                       ->setMethods( [ 'getId' ] )
+                       ->getMock();
+               $block->method( 'getId' )
+                       ->willReturn( $options['blockId'] );
+
+               $this->assertEquals(
+                       $expected,
+                       $blockManager->getCookieValue( $block )
+               );
+       }
+
+       public static function provideGetCookieValue() {
+               $blockId = 100;
+               return [
+                       'Secret key not set' => [
+                               [
+                                       'secretKey' => '',
+                                       'blockId' => $blockId,
+                                       'hmac' => MWCryptHash::hmac( $blockId, '', false ),
+                               ],
+                               $blockId,
+                       ],
+                       'Secret key set' => [
+                               [
+                                       'secretKey' => '123',
+                                       'blockId' => $blockId,
+                                       'hmac' => MWCryptHash::hmac( $blockId, '123', false ),
+                               ],
+                               $blockId . '!' . MWCryptHash::hmac( $blockId, '123', false ) ],
+               ];
+       }
+
 }
index 2fa662b..35dacac 100644 (file)
@@ -204,7 +204,7 @@ class MessageCacheTest extends MediaWikiLangTestCase {
                ];
        }
 
-       public function testNoDBAccess() {
+       public function testNoDBAccessContentLanguage() {
                global $wgContLanguageCode;
 
                $dbr = wfGetDB( DB_REPLICA );
@@ -218,7 +218,22 @@ class MessageCacheTest extends MediaWikiLangTestCase {
 
                $dbr->restoreFlags();
 
-               $this->assertEquals( 0, $dbr->trxLevel(), "No DB read queries" );
+               $this->assertEquals( 0, $dbr->trxLevel(), "No DB read queries (content language)" );
+       }
+
+       public function testNoDBAccessNonContentLanguage() {
+               $dbr = wfGetDB( DB_REPLICA );
+
+               MessageCache::singleton()->getMsgFromNamespace( 'allpages/nl', 'nl' );
+
+               $this->assertEquals( 0, $dbr->trxLevel() );
+               $dbr->setFlag( DBO_TRX, $dbr::REMEMBER_PRIOR ); // make queries trigger TRX
+
+               MessageCache::singleton()->getMsgFromNamespace( 'go/nl', 'nl' );
+
+               $dbr->restoreFlags();
+
+               $this->assertEquals( 0, $dbr->trxLevel(), "No DB read queries (non-content language)" );
        }
 
        /**
index f953319..8c53873 100644 (file)
@@ -125,6 +125,12 @@ class CachedBagOStuffTest extends PHPUnit\Framework\TestCase {
         * @covers CachedBagOStuff::makeKey
         */
        public function testMakeKey() {
+               if ( defined( 'HHVM_VERSION' ) ) {
+                       // This works fine on HHVM (and verified by integration tests), but due to
+                       // a bug in HHVM's Reflection, PHPUnit 4 fails to create a mock (T228563)
+                       $this->markTestSkipped( 'HHVM Reflection buggy' );
+               }
+
                $backend = $this->getMockBuilder( HashBagOStuff::class )
                        ->setMethods( [ 'makeKey' ] )
                        ->getMock();
@@ -145,6 +151,10 @@ class CachedBagOStuffTest extends PHPUnit\Framework\TestCase {
         * @covers CachedBagOStuff::makeGlobalKey
         */
        public function testMakeGlobalKey() {
+               if ( defined( 'HHVM_VERSION' ) ) {
+                       $this->markTestSkipped( 'HHVM Reflection buggy' );
+               }
+
                $backend = $this->getMockBuilder( HashBagOStuff::class )
                        ->setMethods( [ 'makeGlobalKey' ] )
                        ->getMock();
index 9f88474..dc49a13 100644 (file)
@@ -107,6 +107,10 @@ class MultiWriteBagOStuffTest extends MediaWikiTestCase {
         * @covers MultiWriteBagOStuff::makeKey
         */
        public function testMakeKey() {
+               if ( defined( 'HHVM_VERSION' ) ) {
+                       $this->markTestSkipped( 'HHVM Reflection buggy' );
+               }
+
                $cache1 = $this->getMockBuilder( HashBagOStuff::class )
                        ->setMethods( [ 'makeKey' ] )->getMock();
                $cache1->expects( $this->once() )->method( 'makeKey' )
@@ -124,6 +128,10 @@ class MultiWriteBagOStuffTest extends MediaWikiTestCase {
         * @covers MultiWriteBagOStuff::makeGlobalKey
         */
        public function testMakeGlobalKey() {
+               if ( defined( 'HHVM_VERSION' ) ) {
+                       $this->markTestSkipped( 'HHVM Reflection buggy' );
+               }
+
                $cache1 = $this->getMockBuilder( HashBagOStuff::class )
                        ->setMethods( [ 'makeGlobalKey' ] )->getMock();
                $cache1->expects( $this->once() )->method( 'makeGlobalKey' )
index 890218c..9e4a5d7 100644 (file)
@@ -767,8 +767,8 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $localBag = $this->getMockBuilder( HashBagOStuff::class )
                        ->setMethods( [ 'getMulti' ] )->getMock();
                $localBag->expects( $this->exactly( 1 ) )->method( 'getMulti' )->willReturn( [
-                       WANObjectCache::VALUE_KEY_PREFIX . 'k1' => 'val-id1',
-                       WANObjectCache::VALUE_KEY_PREFIX . 'k2' => 'val-id2'
+                       'WANCache:v:' . 'k1' => 'val-id1',
+                       'WANCache:v:' . 'k2' => 'val-id2'
                ] );
                $wanCache = new WANObjectCache( [ 'cache' => $localBag ] );
 
@@ -964,7 +964,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 1, $calls, 'Value was populated' );
 
                // Acquire the mutex to verify that getWithSetCallback uses lockTSE properly
-               $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
+               $this->internalCache->add( 'WANCache:m:' . $key, 1, 0 );
 
                $checkKeys = [ wfRandomString() ]; // new check keys => force misses
                $ret = $cache->getWithSetCallback( $key, 30, $func,
@@ -1026,7 +1026,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
 
                $mockWallClock += 2; // low logical TTL expired
                // Acquire a lock to verify that getWithSetCallback uses lockTSE properly
-               $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
+               $this->internalCache->add( 'WANCache:m:' . $key, 1, 0 );
 
                $ret = $cache->getWithSetCallback( $key, 300, $func, [ 'lockTSE' => 5 ] );
                $this->assertEquals( $value, $ret );
@@ -1034,7 +1034,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
 
                $mockWallClock += 301; // physical TTL expired
                // Acquire a lock to verify that getWithSetCallback uses lockTSE properly
-               $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
+               $this->internalCache->add( 'WANCache:m:' . $key, 1, 0 );
 
                $ret = $cache->getWithSetCallback( $key, 300, $func, [ 'lockTSE' => 5 ] );
                $this->assertEquals( $value, $ret );
@@ -1092,7 +1092,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $mockWallClock += 0.2; // interim keys not brand new
 
                // Acquire a lock to verify that getWithSetCallback uses busyValue properly
-               $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
+               $this->internalCache->add( 'WANCache:m:' . $key, 1, 0 );
 
                $checkKeys = [ wfRandomString() ]; // new check keys => force misses
                $ret = $cache->getWithSetCallback( $key, 30, $func,
@@ -1111,14 +1111,14 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( $busyValue, $ret, 'Callback was not used; used busy value' );
                $this->assertEquals( 2, $calls, 'Callback was not used; used busy value' );
 
-               $this->internalCache->delete( $cache::MUTEX_KEY_PREFIX . $key );
+               $this->internalCache->delete( 'WANCache:m:' . $key );
                $mockWallClock += 0.001; // cached values will be newer than tombstone
                $ret = $cache->getWithSetCallback( $key, 30, $func,
                        [ 'lockTSE' => 30, 'busyValue' => $busyValue, 'checkKeys' => $checkKeys ] );
                $this->assertEquals( $value, $ret, 'Callback was used; saved interim' );
                $this->assertEquals( 3, $calls, 'Callback was used; saved interim' );
 
-               $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
+               $this->internalCache->add( 'WANCache:m:' . $key, 1, 0 );
                $ret = $cache->getWithSetCallback( $key, 30, $func,
                        [ 'busyValue' => $busyValue, 'checkKeys' => $checkKeys ] );
                $this->assertEquals( $value, $ret, 'Callback was not used; used interim' );
@@ -1208,7 +1208,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                // Fake initial check key to be set in the past. Otherwise we'd have to sleep for
                // several seconds during the test to assert the behaviour.
                foreach ( [ $checkAll, $check1, $check2 ] as $checkKey ) {
-                       $cache->touchCheckKey( $checkKey, WANObjectCache::HOLDOFF_NONE );
+                       $cache->touchCheckKey( $checkKey, WANObjectCache::HOLDOFF_TTL_NONE );
                }
 
                $mockWallClock += 0.100;
@@ -1330,7 +1330,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertLessThan( 0, $curTTL, "Deleted key is tombstoned and has current TTL < 0" );
 
                $this->cache->set( $key, $value );
-               $this->cache->delete( $key, WANObjectCache::HOLDOFF_NONE );
+               $this->cache->delete( $key, WANObjectCache::HOLDOFF_TTL_NONE );
 
                $curTTL = null;
                $v = $this->cache->get( $key, $curTTL );
@@ -1462,10 +1462,10 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $v = $cache->getWithSetCallback( $key, 60, $func );
                $this->assertEquals( 3, $wasCalled, 'Value regenerated (got mutex)' ); // sets interim
                // Lock up the mutex so interim cache is used
-               $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
+               $this->internalCache->add( 'WANCache:m:' . $key, 1, 0 );
                $v = $cache->getWithSetCallback( $key, 60, $func );
                $this->assertEquals( 3, $wasCalled, 'Value interim cached (failed mutex)' );
-               $this->internalCache->delete( $cache::MUTEX_KEY_PREFIX . $key );
+               $this->internalCache->delete( 'WANCache:m:' . $key );
 
                $cache->useInterimHoldOffCaching( false );
 
@@ -1482,7 +1482,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $v = $cache->getWithSetCallback( $key, 60, $func );
                $this->assertEquals( 4, $wasCalled, 'Value still regenerated (got mutex)' );
                // Lock up the mutex so interim cache is used
-               $this->internalCache->add( $cache::MUTEX_KEY_PREFIX . $key, 1, 0 );
+               $this->internalCache->add( 'WANCache:m:' . $key, 1, 0 );
                $v = $cache->getWithSetCallback( $key, 60, $func );
                $this->assertEquals( 5, $wasCalled, 'Value still regenerated (failed mutex)' );
        }
@@ -1548,16 +1548,16 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
 
                // Two check keys are newer (given hold-off) than $key, another is older
                $this->internalCache->set(
-                       WANObjectCache::TIME_KEY_PREFIX . $tKey2,
-                       WANObjectCache::PURGE_VAL_PREFIX . ( $priorTime - 3 )
+                       'WANCache:t:' . $tKey2,
+                       'PURGED:' . ( $priorTime - 3 )
                );
                $this->internalCache->set(
-                       WANObjectCache::TIME_KEY_PREFIX . $tKey2,
-                       WANObjectCache::PURGE_VAL_PREFIX . ( $priorTime - 5 )
+                       'WANCache:t:' . $tKey2,
+                       'PURGED:' . ( $priorTime - 5 )
                );
                $this->internalCache->set(
-                       WANObjectCache::TIME_KEY_PREFIX . $tKey1,
-                       WANObjectCache::PURGE_VAL_PREFIX . ( $priorTime - 30 )
+                       'WANCache:t:' . $tKey1,
+                       'PURGED:' . ( $priorTime - 30 )
                );
                $this->cache->set( $key, $value, 30 );
 
@@ -1584,30 +1584,30 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $badTime = microtime( true ) - 300;
 
                $this->internalCache->set(
-                       WANObjectCache::VALUE_KEY_PREFIX . $vKey1,
+                       'WANCache:v:' . $vKey1,
                        [
-                               WANObjectCache::FLD_FORMAT_VERSION => WANObjectCache::VERSION,
-                               WANObjectCache::FLD_VALUE => $value,
-                               WANObjectCache::FLD_TTL => 3600,
-                               WANObjectCache::FLD_TIME => $goodTime
+                               0 => 1,
+                               1 => $value,
+                               2 => 3600,
+                               3 => $goodTime
                        ]
                );
                $this->internalCache->set(
-                       WANObjectCache::VALUE_KEY_PREFIX . $vKey2,
+                       'WANCache:v:' . $vKey2,
                        [
-                               WANObjectCache::FLD_FORMAT_VERSION => WANObjectCache::VERSION,
-                               WANObjectCache::FLD_VALUE => $value,
-                               WANObjectCache::FLD_TTL => 3600,
-                               WANObjectCache::FLD_TIME => $badTime
+                               0 => 1,
+                               1 => $value,
+                               2 => 3600,
+                               3 => $badTime
                        ]
                );
                $this->internalCache->set(
-                       WANObjectCache::TIME_KEY_PREFIX . $tKey1,
-                       WANObjectCache::PURGE_VAL_PREFIX . $goodTime
+                       'WANCache:t:' . $tKey1,
+                       'PURGED:' . $goodTime
                );
                $this->internalCache->set(
-                       WANObjectCache::TIME_KEY_PREFIX . $tKey2,
-                       WANObjectCache::PURGE_VAL_PREFIX . $badTime
+                       'WANCache:t:' . $tKey2,
+                       'PURGED:' . $badTime
                );
 
                $this->assertEquals( $value, $this->cache->get( $vKey1 ) );
@@ -1632,10 +1632,10 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                        ->setMethods( [ 'get', 'changeTTL' ] )->getMock();
                $backend->expects( $this->once() )->method( 'get' )
                        ->willReturn( [
-                               WANObjectCache::FLD_FORMAT_VERSION => WANObjectCache::VERSION,
-                               WANObjectCache::FLD_VALUE => 'value',
-                               WANObjectCache::FLD_TTL => 3600,
-                               WANObjectCache::FLD_TIME => 300,
+                               0 => 1,
+                               1 => 'value',
+                               2 => 3600,
+                               3 => 300,
                        ] );
                $backend->expects( $this->once() )->method( 'changeTTL' )
                        ->willReturn( false );
@@ -1721,7 +1721,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                ] );
 
                $localBag->expects( $this->once() )->method( 'set' )
-                       ->with( "/*/mw-wan/" . $wanCache::VALUE_KEY_PREFIX . "test" );
+                       ->with( "/*/mw-wan/" . 'WANCache:v:' . "test" );
 
                $wanCache->delete( 'test' );
        }
@@ -1737,7 +1737,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                ] );
 
                $localBag->expects( $this->once() )->method( 'set' )
-                       ->with( "/*/mw-wan/" . $wanCache::TIME_KEY_PREFIX . "test" );
+                       ->with( "/*/mw-wan/" . 'WANCache:t:' . "test" );
 
                $wanCache->touchCheckKey( 'test' );
        }
@@ -1753,7 +1753,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                ] );
 
                $localBag->expects( $this->once() )->method( 'delete' )
-                       ->with( "/*/mw-wan/" . $wanCache::TIME_KEY_PREFIX . "test" );
+                       ->with( "/*/mw-wan/" . 'WANCache:t:' . "test" );
 
                $wanCache->resetCheckKey( 'test' );
        }
@@ -1865,6 +1865,10 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
         * @covers WANObjectCache::makeKey
         */
        public function testMakeKey() {
+               if ( defined( 'HHVM_VERSION' ) ) {
+                       $this->markTestSkipped( 'HHVM Reflection buggy' );
+               }
+
                $backend = $this->getMockBuilder( HashBagOStuff::class )
                        ->setMethods( [ 'makeKey' ] )->getMock();
                $backend->expects( $this->once() )->method( 'makeKey' )
@@ -1881,6 +1885,10 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
         * @covers WANObjectCache::makeGlobalKey
         */
        public function testMakeGlobalKey() {
+               if ( defined( 'HHVM_VERSION' ) ) {
+                       $this->markTestSkipped( 'HHVM Reflection buggy' );
+               }
+
                $backend = $this->getMockBuilder( HashBagOStuff::class )
                        ->setMethods( [ 'makeGlobalKey' ] )->getMock();
                $backend->expects( $this->once() )->method( 'makeGlobalKey' )
diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderFilePathTest.php b/tests/phpunit/includes/resourceloader/ResourceLoaderFilePathTest.php
deleted file mode 100644 (file)
index 292340b..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-class ResourceLoaderFilePathTest extends PHPUnit\Framework\TestCase {
-       /**
-        * @covers ResourceLoaderFilePath::__construct
-        */
-       public function testConstructor() {
-               $resourceLoaderFilePath = new ResourceLoaderFilePath(
-                       'dummy/path', 'localBasePath', 'remoteBasePath'
-               );
-
-               $this->assertInstanceOf( ResourceLoaderFilePath::class, $resourceLoaderFilePath );
-       }
-
-       /**
-        * @covers ResourceLoaderFilePath::getLocalPath
-        */
-       public function testGetLocalPath() {
-               $resourceLoaderFilePath = new ResourceLoaderFilePath(
-                       'dummy/path', 'localBasePath', 'remoteBasePath'
-               );
-
-               $this->assertSame(
-                       'localBasePath/dummy/path', $resourceLoaderFilePath->getLocalPath()
-               );
-       }
-
-       /**
-        * @covers ResourceLoaderFilePath::getRemotePath
-        */
-       public function testGetRemotePath() {
-               $resourceLoaderFilePath = new ResourceLoaderFilePath(
-                       'dummy/path', 'localBasePath', 'remoteBasePath'
-               );
-
-               $this->assertSame(
-                       'remoteBasePath/dummy/path', $resourceLoaderFilePath->getRemotePath()
-               );
-       }
-
-       /**
-        * @covers ResourceLoaderFilePath::getPath
-        */
-       public function testGetPath() {
-               $resourceLoaderFilePath = new ResourceLoaderFilePath(
-                       'dummy/path', 'localBasePath', 'remoteBasePath'
-               );
-
-               $this->assertSame(
-                       'dummy/path', $resourceLoaderFilePath->getPath()
-               );
-       }
-}
index 2772b0d..d66e480 100644 (file)
@@ -38,7 +38,7 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                        'wgCapitalLinks' => true,
                        'wgCapitalLinkOverrides' => [
                                NS_CATEGORY => false // for testCompletionSearchMustRespectCapitalLinkOverrides
-                       ]
+                       ],
                ] );
 
                $lb = LoadBalancerSingle::newFromConnection( $this->db );
@@ -64,7 +64,7 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                        'wgCapitalLinks' => true,
                        'wgCapitalLinkOverrides' => [
                                NS_CATEGORY => false // for testCompletionSearchMustRespectCapitalLinkOverrides
-                       ]
+                       ],
                ] );
 
                $this->insertPage( 'Not_Main_Page', 'This is not a main page' );
@@ -283,7 +283,7 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                        $mockField =
                                $this->getMockBuilder( SearchIndexFieldDefinition::class )->setConstructorArgs( [
                                        $name,
-                                       $type
+                                       $type,
                                ] )->getMock();
 
                        $mockField->expects( $this->any() )->method( 'getMapping' )->willReturn( [
@@ -346,8 +346,9 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                $setAugmentor = $this->createMock( ResultSetAugmentor::class );
                $setAugmentor->expects( $this->once() )
                        ->method( 'augmentAll' )
-                       ->willReturnCallback( function ( SearchResultSet $resultSet ) {
+                       ->willReturnCallback( function ( ISearchResultSet $resultSet ) {
                                $data = [];
+                               /** @var SearchResult $result */
                                foreach ( $resultSet as $result ) {
                                        $id = $result->getTitle()->getArticleID();
                                        $data[$id] = "Result:$id:" . $result->getTitle()->getText();
@@ -405,7 +406,7 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                                [
                                        'query' => 'foo',
                                ],
-                               false
+                               false,
                        ],
                        'empty' => [
                                [
@@ -445,34 +446,34 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                                        'query' => 'all:test',
                                        'withAll' => false,
                                ],
-                               false
+                               false,
                        ],
                        'ns only' => [
                                [
                                        'query' => 'help:',
                                ],
-                               [ '', [ NS_HELP ] ]
+                               [ '', [ NS_HELP ] ],
                        ],
                        'all only' => [
                                [
                                        'query' => 'all:',
                                        'withAll' => true,
                                ],
-                               [ '', null ]
+                               [ '', null ],
                        ],
                        'all wins over namespace when first' => [
                                [
                                        'query' => 'all:help:test',
                                        'withAll' => true,
                                ],
-                               [ 'help:test', null ]
+                               [ 'help:test', null ],
                        ],
                        'ns wins over all when first' => [
                                [
                                        'query' => 'help:all:test',
                                        'withAll' => true,
                                ],
-                               [ 'all:test', [ NS_HELP ] ]
+                               [ 'all:test', [ NS_HELP ] ],
                        ],
                ];
        }
index 72db766..9616672 100644 (file)
@@ -86,6 +86,10 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
         * @return PHPUnit_Framework_MockObject_MockObject|HashBagOStuff
         */
        private function getMockCache() {
+               if ( defined( 'HHVM_VERSION' ) ) {
+                       $this->markTestSkipped( 'HHVM Reflection buggy' );
+               }
+
                $mock = $this->getMockBuilder( HashBagOStuff::class )
                        ->disableOriginalConstructor()
                        ->setMethods( [ 'get', 'set', 'delete', 'makeKey' ] )
index 7a78e52..54a362e 100644 (file)
@@ -6,6 +6,7 @@ use DumpBackup;
 use Exception;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Revision\RevisionRecord;
+use MediaWiki\Revision\SlotRecord;
 use MediaWikiTestCase;
 use MWException;
 use RequestContext;
@@ -28,13 +29,14 @@ class BackupDumperPageTest extends DumpTestCase {
 
        // We'll add several pages, revision and texts. The following variables hold the
        // corresponding ids.
-       private $pageId1, $pageId2, $pageId3, $pageId4;
-       private $pageTitle1, $pageTitle2, $pageTitle3, $pageTitle4;
+       private $pageId1, $pageId2, $pageId3, $pageId4, $pageId5;
+       private $pageTitle1, $pageTitle2, $pageTitle3, $pageTitle4, $pageTitle5;
        private $revId1_1, $textId1_1;
        private $revId2_1, $textId2_1, $revId2_2, $textId2_2;
        private $revId2_3, $textId2_3, $revId2_4, $textId2_4;
        private $revId3_1, $textId3_1, $revId3_2, $textId3_2;
        private $revId4_1, $textId4_1;
+       private $revId5_1, $textId5_1;
        private $namespace, $talk_namespace;
 
        /**
@@ -106,6 +108,15 @@ class BackupDumperPageTest extends DumpTestCase {
                                "Talk about BackupDumperTestP1 Text1",
                                "Talk BackupDumperTestP1 Summary1" );
                        $this->pageId4 = $page->getId();
+
+                       $this->pageTitle5 = Title::newFromText( 'BackupDumperTestP5' );
+                       $page = WikiPage::factory( $this->pageTitle5 );
+                       list( $this->revId5_1, $this->textId5_1 ) = $this->addRevision( $page,
+                               "BackupDumperTestP5 Text1",
+                               "BackupDumperTestP5 Summary1" );
+                       $this->pageId5 = $page->getId();
+
+                       $this->corruptRevisionData( $page->getRevision()->getRevisionRecord() );
                } catch ( Exception $e ) {
                        // We'd love to pass $e directly. However, ... see
                        // documentation of exceptionFromAddDBData in
@@ -114,6 +125,39 @@ class BackupDumperPageTest extends DumpTestCase {
                }
        }
 
+       /**
+        * Corrupt the information about the given revision in the database.
+        *
+        * @param RevisionRecord $revision
+        */
+       private function corruptRevisionData( RevisionRecord $revision ) {
+               global $wgMultiContentRevisionSchemaMigrationStage;
+
+               if ( ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
+                       $this->db->update(
+                               'revision',
+                               [
+                                       'rev_text_id' => 0,
+                                       'rev_sha1' => '',
+                                       'rev_len' => '0',
+                               ],
+                               [ 'rev_id' => $revision->getId() ]
+                       );
+               }
+
+               if ( ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) ) {
+                       $this->db->update(
+                               'content',
+                               [
+                                       'content_address' => 'tt:0',
+                                       'content_sha1' => '',
+                                       'content_size' => '0',
+                               ],
+                               [ 'content_id' => $revision->getSlot( SlotRecord::MAIN )->getContentId() ]
+                       );
+               }
+       }
+
        protected function setUp() {
                parent::setUp();
 
@@ -201,11 +245,14 @@ class BackupDumperPageTest extends DumpTestCase {
                $dumper = $this->newDumpBackup(
                        [ '--full', '--quiet', '--output', 'file:' . $fname, '--schema-version', $schemaVersion ],
                        $this->pageId1,
-                       $this->pageId4 + 1
+                       $this->pageId5 + 1
                );
 
-               // Performing the dump
+               // Performing the dump. Suppress warnings, since we want to test
+               // accessing broken revision data (page 5).
+               $this->setMwGlobals( 'wgDevelopmentWarnings', false );
                $dumper->execute();
+               $this->setMwGlobals( 'wgDevelopmentWarnings', true );
 
                // Checking the dumped data
                $this->assertDumpSchema( $fname, $this->getXmlSchemaPath( $schemaVersion ) );
@@ -295,6 +342,26 @@ class BackupDumperPageTest extends DumpTestCase {
                );
                $asserter->assertPageEnd();
 
+               // Page 5 (broken revision data)
+               $asserter->assertPageStart(
+                       $this->pageId5,
+                       $this->namespace,
+                       $this->pageTitle5->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId5_1,
+                       "BackupDumperTestP5 Summary1",
+                       null,
+                       0,
+                       "",
+                       false,
+                       false,
+                       CONTENT_MODEL_WIKITEXT,
+                       CONTENT_FORMAT_WIKITEXT,
+                       $schemaVersion
+               );
+               $asserter->assertPageEnd();
+
                $asserter->assertDumpEnd();
 
                // FIXME: add multi-slot test case!
@@ -317,11 +384,14 @@ class BackupDumperPageTest extends DumpTestCase {
                                '--schema-version', $schemaVersion,
                        ],
                        $this->pageId1,
-                       $this->pageId4 + 1
+                       $this->pageId5 + 1
                );
 
-               // Performing the dump
+               // Performing the dump. Suppress warnings, since we want to test
+               // accessing broken revision data (page 5).
+               $this->setMwGlobals( 'wgDevelopmentWarnings', false );
                $dumper->execute();
+               $this->setMwGlobals( 'wgDevelopmentWarnings', true );
 
                // Checking the dumped data
                $this->assertDumpSchema( $fname, $this->getXmlSchemaPath( $schemaVersion ) );
@@ -404,6 +474,21 @@ class BackupDumperPageTest extends DumpTestCase {
                );
                $asserter->assertPageEnd();
 
+               // Page 5 (broken revision data)
+               $asserter->assertPageStart(
+                       $this->pageId5,
+                       $this->namespace,
+                       $this->pageTitle5->getPrefixedText()
+               );
+               $asserter->assertRevision(
+                       $this->revId5_1,
+                       "BackupDumperTestP5 Summary1",
+                       null,
+                       0,
+                       ""
+               );
+               $asserter->assertPageEnd();
+
                $asserter->assertDumpEnd();
        }
 
index 207ac28..6b31972 100644 (file)
@@ -5,7 +5,7 @@ use MediaWiki\MediaWikiServices;
 class MockSearchEngine extends SearchEngine {
        /** @var SearchResult[][] */
        private static $results = [];
-       /** @var SearchResultSet[][] */
+       /** @var ISearchResultSet[][] */
        private static $interwikiResults = [];
 
        public static function clearMockResults() {
@@ -33,7 +33,7 @@ class MockSearchEngine extends SearchEngine {
        }
 
        /**
-        * @param SearchResultSet[][] $interwikiResults
+        * @param ISearchResultSet[][] $interwikiResults
         */
        public static function setMockInterwikiResults( array $interwikiResults ) {
                self::$interwikiResults = $interwikiResults;
index 38f6731..e6ee016 100644 (file)
@@ -9,7 +9,7 @@ class MockSearchResultSet extends SearchResultSet {
 
        /**
         * @param SearchResult[]|callable[] $results
-        * @param SearchResultSet[][]|callable[][] $interwikiResults Map from result type
+        * @param ISearchResultSet[][]|callable[][] $interwikiResults Map from result type
         *  to list of results for that type.
         */
        public function __construct( array $results, array $interwikiResults = [] ) {
index e35e373..7233b86 100644 (file)
@@ -12,6 +12,11 @@ class RedisBagOStuffTest extends MediaWikiUnitTestCase {
 
        protected function setUp() {
                parent::setUp();
+
+               if ( defined( 'HHVM_VERSION' ) ) {
+                       $this->markTestSkipped( 'HHVM Reflection buggy' );
+               }
+
                $cache = $this->getMockBuilder( RedisBagOStuff::class )
                        ->disableOriginalConstructor()
                        ->getMock();
diff --git a/tests/phpunit/unit/includes/resourceloader/ResourceLoaderFilePathTest.php b/tests/phpunit/unit/includes/resourceloader/ResourceLoaderFilePathTest.php
new file mode 100644 (file)
index 0000000..b1db383
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @covers ResourceLoaderFilePath
+ */
+class ResourceLoaderFilePathTest extends MediaWikiUnitTestCase {
+
+       public function testConstructor() {
+               $path = new ResourceLoaderFilePath( 'dummy/path', '/local', '/remote' );
+
+               $this->assertInstanceOf( ResourceLoaderFilePath::class, $path );
+       }
+
+       public function testGetters() {
+               $path = new ResourceLoaderFilePath( 'dummy/path', '/local', '/remote' );
+
+               $this->assertSame( '/local/dummy/path', $path->getLocalPath() );
+               $this->assertSame( '/remote/dummy/path', $path->getRemotePath() );
+               $this->assertSame( '/local', $path->getLocalBasePath() );
+               $this->assertSame( '/remote', $path->getRemoteBasePath() );
+               $this->assertSame( 'dummy/path', $path->getPath() );
+       }
+}
index daf7112..22c05f4 100644 (file)
@@ -35,7 +35,7 @@ describe( 'Rollback with confirmation', function () {
        it.skip( 'should offer rollback options for admin users', function () {
                assert.strictEqual( HistoryPage.rollback.getText(), 'rollback 1 edit' );
 
-               HistoryPage.rollback.click();
+               HistoryPage.rollbackLink.click();
 
                assert.strictEqual( HistoryPage.rollbackConfirmable.getText(), 'Please confirm:' );
                assert.strictEqual( HistoryPage.rollbackConfirmableYes.getText(), 'Rollback' );