Merge "RFC T157418: Trim whitespace in table cells, list items, headings"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 20 Mar 2018 15:26:06 +0000 (15:26 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 20 Mar 2018 15:26:06 +0000 (15:26 +0000)
152 files changed:
.phpcs.xml
composer.json
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/ServiceWiring.php
includes/Storage/RevisionStore.php
includes/Storage/SlotRecord.php
includes/WebRequest.php
includes/actions/MarkpatrolledAction.php
includes/api/ApiBase.php
includes/api/ApiFormatBase.php
includes/api/ApiQuerySiteinfo.php
includes/api/i18n/cs.json
includes/api/i18n/ja.json
includes/content/ContentHandler.php
includes/content/WikiTextStructure.php
includes/db/MWLBFactory.php
includes/debug/MWDebug.php
includes/diff/TableDiffFormatter.php
includes/export/DumpNamespaceFilter.php
includes/externalstore/ExternalStoreDB.php
includes/externalstore/ExternalStoreHttp.php
includes/externalstore/ExternalStoreMwstore.php
includes/filerepo/file/LocalFile.php
includes/htmlform/HTMLForm.php
includes/installer/MssqlUpdater.php
includes/installer/MysqlUpdater.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/installer/WebInstaller.php
includes/installer/i18n/ast.json
includes/installer/i18n/pl.json
includes/installer/i18n/sr-ec.json
includes/jobqueue/JobQueueFederated.php
includes/libs/HashRing.php
includes/libs/HtmlArmor.php
includes/libs/Timing.php
includes/libs/http/HttpAcceptNegotiator.php
includes/libs/http/HttpAcceptParser.php
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseMssql.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/libs/virtualrest/SwiftVirtualRESTService.php
includes/libs/xmp/XMP.php
includes/libs/xmp/XMPValidate.php
includes/page/WikiPage.php
includes/parser/StripState.php
includes/profiler/ProfileSection.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderModule.php
includes/specials/pagers/NewFilesPager.php
includes/user/User.php
languages/data/grammarTransformations/ru.json
languages/i18n/ast.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/bs.json
languages/i18n/ckb.json
languages/i18n/da.json
languages/i18n/en.json
languages/i18n/es.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/gor.json
languages/i18n/he.json
languages/i18n/hu.json
languages/i18n/io.json
languages/i18n/ko.json
languages/i18n/ku-latn.json
languages/i18n/lij.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/nds-nl.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/pl.json
languages/i18n/ru.json
languages/i18n/scn.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/th.json
languages/i18n/udm.json
languages/i18n/zgh.json
languages/i18n/zh-hant.json
maintenance/Maintenance.php
maintenance/archives/patch-rev_text_id-default.sql [new file with mode: 0644]
maintenance/archives/patch-slot-origin.sql [new file with mode: 0644]
maintenance/archives/patch-slots.sql
maintenance/dev/README
maintenance/mssql/archives/patch-rev_text_id-default.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-slot-origin.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-slots.sql
maintenance/mssql/tables.sql
maintenance/oracle/archives/patch-slot-origin.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-slots.sql
maintenance/oracle/tables.sql
maintenance/postgres/archives/patch-slots-table.sql
maintenance/postgres/tables.sql
maintenance/rebuildFileCache.php
maintenance/sqlite/archives/patch-rev_text_id-default.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-slot-origin.sql [new file with mode: 0644]
maintenance/tables.sql
resources/src/mediawiki.action/mediawiki.action.history.styles.css
resources/src/mediawiki.legacy/commonPrint.css
resources/src/mediawiki.legacy/oldshared.css
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.skinning/content.css
resources/src/mediawiki.skinning/interface.css
resources/src/mediawiki/mediawiki.js
resources/src/mediawiki/mediawiki.toc.print.css
resources/src/mediawiki/mediawiki.util.js
tests/common/TestsAutoLoader.php
tests/parser/ParserTestRunner.php
tests/phpunit/data/composer/composer.json
tests/phpunit/data/composer/composer.lock
tests/phpunit/data/composer/installed.json
tests/phpunit/data/composer/new-composer.json
tests/phpunit/includes/Storage/MutableRevisionRecordTest.php
tests/phpunit/includes/Storage/RevisionStoreDbTest.php
tests/phpunit/includes/Storage/SlotRecordTest.php
tests/phpunit/includes/WebRequestTest.php
tests/phpunit/includes/api/ApiTestCaseUpload.php
tests/phpunit/includes/api/ApiUploadTest.php
tests/phpunit/includes/api/ApiUploadTestCase.php [new file with mode: 0644]
tests/phpunit/includes/changes/ChangesListStringOptionsFilterGroupTest.php
tests/phpunit/includes/libs/GenericArrayObjectTest.php
tests/phpunit/includes/libs/IPTest.php
tests/phpunit/includes/libs/composer/ComposerInstalledTest.php
tests/phpunit/includes/libs/composer/ComposerLockTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseMysqlBaseTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php
tests/phpunit/includes/page/WikiPageDbTestBase.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/phpunit/languages/classes/LanguageRuTest.php
tests/phpunit/tests/MediaWikiTestCaseSchemaTest.sql
tests/qunit/data/load.mock.php
tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js

index cd55428..d77d398 100644 (file)
@@ -22,8 +22,6 @@
                <exclude name="MediaWiki.Files.ClassMatchesFilename.NotMatch" />
                <exclude name="Generic.Files.OneObjectStructurePerFile.MultipleFound" />
                <exclude name="MediaWiki.VariableAnalysis.ForbiddenGlobalVariables.ForbiddenGlobal$wgTitle" />
-               <exclude name="MediaWiki.Usage.DeprecatedConstantUsage.NS_IMAGE" />
-               <exclude name="MediaWiki.Usage.DeprecatedConstantUsage.NS_IMAGE_TALK" />
                <exclude name="MediaWiki.Commenting.FunctionComment.SpacingDocStar" />
                <exclude name="MediaWiki.Commenting.FunctionComment.SpacingDocTag" />
                <exclude name="Squiz.Scope.MethodScope.Missing" />
index 178c280..0569b03 100644 (file)
@@ -9,7 +9,7 @@
                        "homepage": "https://www.mediawiki.org/wiki/Special:Version/Credits"
                }
        ],
-       "license": "GPL-2.0+",
+       "license": "GPL-2.0-or-later",
        "support": {
                "issues": "https://bugs.mediawiki.org/",
                "irc": "irc://irc.freenode.net/mediawiki",
index fad49e4..538c1b2 100644 (file)
@@ -7335,7 +7335,7 @@ $wgAutoloadAttemptLowercase = true;
  *     'version' => '1.9.0',
  *     'url' => 'https://example.org/example-extension/',
  *     'descriptionmsg' => 'exampleextension-desc',
- *     'license-name' => 'GPL-2.0+',
+ *     'license-name' => 'GPL-2.0-or-later',
  * ];
  * @endcode
  *
@@ -7369,7 +7369,7 @@ $wgAutoloadAttemptLowercase = true;
  *    localizable message (omit in favour of 'descriptionmsg').
  *
  * - license-name: Short name of the license (used as label for the link), such
- *   as "GPL-2.0+" or "MIT" (https://spdx.org/licenses/ for a list of identifiers).
+ *   as "GPL-2.0-or-later" or "MIT" (https://spdx.org/licenses/ for a list of identifiers).
  */
 $wgExtensionCredits = [];
 
index 1d61996..7a5a5d8 100644 (file)
@@ -1050,7 +1050,7 @@ function wfMatchesDomainList( $url, $domains ) {
  */
 function wfDebug( $text, $dest = 'all', array $context = [] ) {
        global $wgDebugRawPage, $wgDebugLogPrefix;
-       global $wgDebugTimestamps, $wgRequestTime;
+       global $wgDebugTimestamps;
 
        if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
                return;
@@ -1061,7 +1061,7 @@ function wfDebug( $text, $dest = 'all', array $context = [] ) {
        if ( $wgDebugTimestamps ) {
                $context['seconds_elapsed'] = sprintf(
                        '%6.4f',
-                       microtime( true ) - $wgRequestTime
+                       microtime( true ) - $_SERVER['REQUEST_TIME_FLOAT']
                );
                $context['memory_used'] = sprintf(
                        '%5.1fM',
@@ -1514,9 +1514,11 @@ function wfHostname() {
  * @return string
  */
 function wfReportTime() {
-       global $wgRequestTime, $wgShowHostnames;
+       global $wgShowHostnames;
 
-       $responseTime = round( ( microtime( true ) - $wgRequestTime ) * 1000 );
+       $elapsed = ( microtime( true ) - $_SERVER['REQUEST_TIME_FLOAT'] );
+       // seconds to milliseconds
+       $responseTime = round( $elapsed * 1000 );
        $reportVars = [ 'wgBackendResponseTime' => $responseTime ];
        if ( $wgShowHostnames ) {
                $reportVars['wgHostname'] = wfHostname();
index 08d343b..5131917 100644 (file)
@@ -61,7 +61,10 @@ return [
                );
                $class = MWLBFactory::getLBFactoryClass( $lbConf );
 
-               return new $class( $lbConf );
+               $instance = new $class( $lbConf );
+               MWLBFactory::setSchemaAliases( $instance );
+
+               return $instance;
        },
 
        'DBLoadBalancer' => function ( MediaWikiServices $services ) {
index e00deef..584142b 100644 (file)
@@ -455,7 +455,7 @@ class RevisionStore
                        $dbw->insert( 'ip_changes', $ipcRow, __METHOD__ );
                }
 
-               $newSlot = SlotRecord::newSaved( $row['rev_id'], $blobAddress, $slot );
+               $newSlot = SlotRecord::newSaved( $row['rev_id'], $textId, $blobAddress, $slot );
                $slots = new RevisionSlots( [ 'main' => $newSlot ] );
 
                $rev = new RevisionStoreRecord(
@@ -594,16 +594,17 @@ class RevisionStore
 
                if ( $current ) {
                        $fields = [
-                               'page'       => $title->getArticleID(),
-                               'user_text'  => $user->getName(),
-                               'user'       => $user->getId(),
-                               'actor'      => $user->getActorId(),
-                               'comment'    => $comment,
-                               'minor_edit' => $minor,
-                               'text_id'    => $current->rev_text_id,
-                               'parent_id'  => $current->page_latest,
-                               'len'        => $current->rev_len,
-                               'sha1'       => $current->rev_sha1
+                               'page'        => $title->getArticleID(),
+                               'user_text'   => $user->getName(),
+                               'user'        => $user->getId(),
+                               'actor'       => $user->getActorId(),
+                               'comment'     => $comment,
+                               'minor_edit'  => $minor,
+                               'text_id'     => $current->rev_text_id,
+                               'parent_id'   => $current->page_latest,
+                               'slot_origin' => $current->page_latest,
+                               'len'         => $current->rev_len,
+                               'sha1'        => $current->rev_sha1
                        ];
 
                        if ( $this->contentHandlerUseDB ) {
@@ -751,6 +752,10 @@ class RevisionStore
        private function emulateMainSlot_1_29( $row, $queryFlags, Title $title ) {
                $mainSlotRow = new stdClass();
                $mainSlotRow->role_name = 'main';
+               $mainSlotRow->model_name = null;
+               $mainSlotRow->slot_revision_id = null;
+               $mainSlotRow->content_address = null;
+               $mainSlotRow->slot_content_id = null;
 
                $content = null;
                $blobData = null;
@@ -763,9 +768,15 @@ class RevisionStore
                        }
 
                        if ( isset( $row->rev_text_id ) && $row->rev_text_id > 0 ) {
-                               $mainSlotRow->cont_address = 'tt:' . $row->rev_text_id;
+                               $mainSlotRow->slot_content_id = $row->rev_text_id;
+                               $mainSlotRow->content_address = 'tt:' . $row->rev_text_id;
                        }
 
+                       // This is used by null-revisions
+                       $mainSlotRow->slot_origin = isset( $row->slot_origin )
+                               ? intval( $row->slot_origin )
+                               : null;
+
                        if ( isset( $row->old_text ) ) {
                                // this happens when the text-table gets joined directly, in the pre-1.30 schema
                                $blobData = isset( $row->old_text ) ? strval( $row->old_text ) : null;
@@ -776,10 +787,10 @@ class RevisionStore
                                $blobFlags = ( $row->old_flags === null ) ? '' : $row->old_flags;
                        }
 
-                       $mainSlotRow->slot_revision = intval( $row->rev_id );
+                       $mainSlotRow->slot_revision_id = intval( $row->rev_id );
 
-                       $mainSlotRow->cont_size = isset( $row->rev_len ) ? intval( $row->rev_len ) : null;
-                       $mainSlotRow->cont_sha1 = isset( $row->rev_sha1 ) ? strval( $row->rev_sha1 ) : null;
+                       $mainSlotRow->content_size = isset( $row->rev_len ) ? intval( $row->rev_len ) : null;
+                       $mainSlotRow->content_sha1 = isset( $row->rev_sha1 ) ? strval( $row->rev_sha1 ) : null;
                        $mainSlotRow->model_name = isset( $row->rev_content_model )
                                ? strval( $row->rev_content_model )
                                : null;
@@ -788,13 +799,19 @@ class RevisionStore
                                ? strval( $row->rev_content_format )
                                : null;
                } elseif ( is_array( $row ) ) {
-                       $mainSlotRow->slot_revision = isset( $row['id'] ) ? intval( $row['id'] ) : null;
+                       $mainSlotRow->slot_revision_id = isset( $row['id'] ) ? intval( $row['id'] ) : null;
 
-                       $mainSlotRow->cont_address = isset( $row['text_id'] )
+                       $mainSlotRow->slot_content_id = isset( $row['text_id'] )
+                               ? intval( $row['text_id'] )
+                               : null;
+                       $mainSlotRow->slot_origin = isset( $row['slot_origin'] )
+                               ? intval( $row['slot_origin'] )
+                               : null;
+                       $mainSlotRow->content_address = isset( $row['text_id'] )
                                ? 'tt:' . intval( $row['text_id'] )
                                : null;
-                       $mainSlotRow->cont_size = isset( $row['len'] ) ? intval( $row['len'] ) : null;
-                       $mainSlotRow->cont_sha1 = isset( $row['sha1'] ) ? strval( $row['sha1'] ) : null;
+                       $mainSlotRow->content_size = isset( $row['len'] ) ? intval( $row['len'] ) : null;
+                       $mainSlotRow->content_sha1 = isset( $row['sha1'] ) ? strval( $row['sha1'] ) : null;
 
                        $mainSlotRow->model_name = isset( $row['content_model'] )
                                ? strval( $row['content_model'] ) : null;  // XXX: must be a string!
@@ -827,9 +844,11 @@ class RevisionStore
                        throw new MWException( 'Revision constructor passed invalid row format.' );
                }
 
-               // With the old schema, the content changes with every revision.
-               // ...except for null-revisions. Would be nice if we could detect them.
-               $mainSlotRow->slot_inherited = 0;
+               // With the old schema, the content changes with every revision,
+               // except for null-revisions.
+               if ( !isset( $mainSlotRow->slot_origin ) ) {
+                       $mainSlotRow->slot_origin = $mainSlotRow->slot_revision_id;
+               }
 
                if ( $mainSlotRow->model_name === null ) {
                        $mainSlotRow->model_name = function ( SlotRecord $slot ) use ( $title ) {
@@ -853,6 +872,7 @@ class RevisionStore
                        };
                }
 
+               $mainSlotRow->slot_id = $mainSlotRow->slot_revision_id;
                return new SlotRecord( $mainSlotRow, $content );
        }
 
@@ -1035,9 +1055,10 @@ class RevisionStore
         * @return RevisionRecord|null
         */
        public function getRevisionByTimestamp( $title, $timestamp ) {
+               $db = $this->getDBConnection( DB_REPLICA );
                return $this->newRevisionFromConds(
                        [
-                               'rev_timestamp' => $timestamp,
+                               'rev_timestamp' => $db->timestamp( $timestamp ),
                                'page_namespace' => $title->getNamespace(),
                                'page_title' => $title->getDBkey()
                        ],
index 8769330..50d1100 100644 (file)
@@ -23,6 +23,7 @@
 namespace MediaWiki\Storage;
 
 use Content;
+use InvalidArgumentException;
 use LogicException;
 use OutOfBoundsException;
 use Wikimedia\Assert\Assert;
@@ -72,7 +73,8 @@ class SlotRecord {
         * @return SlotRecord
         */
        private static function newDerived( SlotRecord $slot, array $overrides = [] ) {
-               $row = $slot->row;
+               $row = clone $slot->row;
+               $row->slot_id = null; // never copy the row ID!
 
                foreach ( $overrides as $key => $value ) {
                        $row->$key = $value;
@@ -85,39 +87,51 @@ class SlotRecord {
         * Constructs a new SlotRecord for a new revision, inheriting the content of the given SlotRecord
         * of a previous revision.
         *
+        * Note that a SlotRecord constructed this way are intended as prototypes,
+        * to be used wit newSaved(). They are incomplete, so some getters such as
+        * getRevision() will fail.
+        *
         * @param SlotRecord $slot
         *
         * @return SlotRecord
         */
        public static function newInherited( SlotRecord $slot ) {
+               // Sanity check - we can't inherit from a Slot that's not attached to a revision.
+               $slot->getRevision();
+               $slot->getOrigin();
+               $slot->getAddress();
+
+               // NOTE: slot_origin and content_address are copied from $slot.
                return self::newDerived( $slot, [
-                       'slot_inherited' => true,
-                       'slot_revision' => null,
+                       'slot_revision_id' => null,
                ] );
        }
 
        /**
         * Constructs a new Slot from a Content object for a new revision.
         * This is the preferred way to construct a slot for storing Content that
-        * resulted from a user edit.
+        * resulted from a user edit. The slot is assumed to be not inherited.
+        *
+        * Note that a SlotRecord constructed this way are intended as prototypes,
+        * to be used wit newSaved(). They are incomplete, so some getters such as
+        * getAddress() will fail.
         *
         * @param string $role
         * @param Content $content
-        * @param bool $inherited
         *
-        * @return SlotRecord
+        * @return SlotRecord An incomplete proto-slot object, to be used with newSaved() later.
         */
-       public static function newUnsaved( $role, Content $content, $inherited = false ) {
-               Assert::parameterType( 'boolean', $inherited, '$inherited' );
+       public static function newUnsaved( $role, Content $content ) {
                Assert::parameterType( 'string', $role, '$role' );
 
                $row = [
                        'slot_id' => null, // not yet known
-                       'slot_address' => null, // not yet known. need setter?
-                       'slot_revision' => null, // not yet known
-                       'slot_inherited' => $inherited,
-                       'cont_size' => null, // compute later
-                       'cont_sha1' => null, // compute later
+                       'slot_revision_id' => null, // not yet known
+                       'slot_origin' => null, // not yet known, will be set in newSaved()
+                       'content_size' => null, // compute later
+                       'content_sha1' => null, // compute later
+                       'slot_content_id' => null, // not yet known, will be set in newSaved()
+                       'content_address' => null, // not yet known, will be set in newSaved()
                        'role_name' => $role,
                        'model_name' => $content->getModel(),
                ];
@@ -126,23 +140,75 @@ class SlotRecord {
        }
 
        /**
-        * Constructs a SlotRecord for a newly saved revision, based on the proto-slot that was
-        * supplied to the code that performed the save operation. This adds information that
-        * has only become available during saving, particularly the revision ID and blob address.
-        *
-        * @param int $revisionId
-        * @param string $blobAddress
-        * @param SlotRecord $protoSlot The proto-slot that was provided to the code that then
-        *
-        * @return SlotRecord
+        * Constructs a complete SlotRecord for a newly saved revision, based on the incomplete
+        * proto-slot. This adds information that has only become available during saving,
+        * particularly the revision ID and content address.
+        *
+        * @param int $revisionId the revision the slot is to be associated with (field slot_revision_id).
+        *        If $protoSlot already has a revision, it must be the same.
+        * @param int $contentId the ID of the row in the content table describing the content
+        *        referenced by $contentAddress (field slot_content_id).
+        *        If $protoSlot already has a content ID, it must be the same.
+        * @param string $contentAddress the slot's content address (field content_address).
+        *        If $protoSlot already has an address, it must be the same.
+        * @param SlotRecord $protoSlot The proto-slot that was provided as input for creating a new
+        *        revision. $protoSlot must have a content address if inherited.
+        *
+        * @return SlotRecord If the state of $protoSlot is inappropriate for saving a new revision.
         */
-       public static function newSaved( $revisionId, $blobAddress, SlotRecord $protoSlot ) {
+       public static function newSaved(
+               $revisionId,
+               $contentId,
+               $contentAddress,
+               SlotRecord $protoSlot
+       ) {
                Assert::parameterType( 'integer', $revisionId, '$revisionId' );
-               Assert::parameterType( 'string', $blobAddress, '$blobAddress' );
+               Assert::parameterType( 'integer', $contentId, '$contentId' );
+               Assert::parameterType( 'string', $contentAddress, '$contentAddress' );
+
+               if ( $protoSlot->hasRevision() && $protoSlot->getRevision() !== $revisionId ) {
+                       throw new LogicException(
+                               "Mismatching revision ID $revisionId: "
+                               . "The slot already belongs to revision {$protoSlot->getRevision()}. "
+                               . "Use SlotRecord::newInherited() to re-use content between revisions."
+                       );
+               }
+
+               if ( $protoSlot->hasAddress() && $protoSlot->getAddress() !== $contentAddress ) {
+                       throw new LogicException(
+                               "Mismatching blob address $contentAddress: "
+                               . "The slot already has content at {$protoSlot->getAddress()}."
+                       );
+               }
+
+               if ( $protoSlot->hasAddress() && $protoSlot->getContentId() !== $contentId ) {
+                       throw new LogicException(
+                               "Mismatching content ID $contentId: "
+                               . "The slot already has content row {$protoSlot->getContentId()} associated."
+                       );
+               }
+
+               if ( $protoSlot->isInherited() ) {
+                       if ( !$protoSlot->hasAddress() ) {
+                               throw new InvalidArgumentException(
+                                       "An inherited blob should have a content address!"
+                               );
+                       }
+                       if ( !$protoSlot->hasField( 'slot_origin' ) ) {
+                               throw new InvalidArgumentException(
+                                       "A saved inherited slot should have an origin set!"
+                               );
+                       }
+                       $origin = $protoSlot->getOrigin();
+               } else {
+                       $origin = $revisionId;
+               }
 
                return self::newDerived( $protoSlot, [
-                       'slot_revision' => $revisionId,
-                       'cont_address' => $blobAddress,
+                       'slot_revision_id' => $revisionId,
+                       'slot_content_id' => $contentId,
+                       'slot_origin' => $origin,
+                       'content_address' => $contentAddress,
                ] );
        }
 
@@ -165,6 +231,47 @@ class SlotRecord {
                Assert::parameterType( 'object', $row, '$row' );
                Assert::parameterType( 'Content|callable', $content, '$content' );
 
+               Assert::parameter(
+                       property_exists( $row, 'slot_id' ),
+                       '$row->slot_id',
+                       'must exist'
+               );
+               Assert::parameter(
+                       property_exists( $row, 'slot_revision_id' ),
+                       '$row->slot_revision_id',
+                       'must exist'
+               );
+               Assert::parameter(
+                       property_exists( $row, 'slot_content_id' ),
+                       '$row->slot_content_id',
+                       'must exist'
+               );
+               Assert::parameter(
+                       property_exists( $row, 'content_address' ),
+                       '$row->content_address',
+                       'must exist'
+               );
+               Assert::parameter(
+                       property_exists( $row, 'model_name' ),
+                       '$row->model_name',
+                       'must exist'
+               );
+               Assert::parameter(
+                       property_exists( $row, 'slot_origin' ),
+                       '$row->slot_origin',
+                       'must exist'
+               );
+               Assert::parameter(
+                       !property_exists( $row, 'slot_inherited' ),
+                       '$row->slot_inherited',
+                       'must not exist'
+               );
+               Assert::parameter(
+                       !property_exists( $row, 'slot_revision' ),
+                       '$row->slot_revision',
+                       'must not exist'
+               );
+
                $this->row = $row;
                $this->content = $content;
        }
@@ -217,7 +324,8 @@ class SlotRecord {
         * @param string $name
         *
         * @throws OutOfBoundsException
-        * @return mixed Returns the field's value, or null if the field is NULL in the DB row.
+        * @throws IncompleteRevisionException
+        * @return mixed Returns the field's value, never null.
         */
        private function getField( $name ) {
                if ( !isset( $this->row->$name ) ) {
@@ -280,16 +388,35 @@ class SlotRecord {
         * @return int
         */
        public function getRevision() {
-               return $this->getIntField( 'slot_revision' );
+               return $this->getIntField( 'slot_revision_id' );
+       }
+
+       /**
+        * Returns the revision ID of the revision that originated the slot's content.
+        *
+        * @return int
+        */
+       public function getOrigin() {
+               return $this->getIntField( 'slot_origin' );
        }
 
        /**
         * Whether this slot was inherited from an older revision.
         *
+        * If this SlotRecord is already attached to a revision, this returns true
+        * if the slot's revision of origin is the same as the revision it belongs to.
+        *
+        * If this SlotRecord is not yet attached to a revision, this returns true
+        * if the slot already has an address.
+        *
         * @return bool
         */
        public function isInherited() {
-               return $this->getIntField( 'slot_inherited' ) !== 0;
+               if ( $this->hasRevision() ) {
+                       return $this->getRevision() !== $this->getOrigin();
+               } else {
+                       return $this->hasAddress();
+               }
        }
 
        /**
@@ -300,7 +427,7 @@ class SlotRecord {
         * @return bool
         */
        public function hasAddress() {
-               return $this->hasField( 'cont_address' );
+               return $this->hasField( 'content_address' );
        }
 
        /**
@@ -311,7 +438,7 @@ class SlotRecord {
         * @return bool
         */
        public function hasRevision() {
-               return $this->hasField( 'slot_revision' );
+               return $this->hasField( 'slot_revision_id' );
        }
 
        /**
@@ -330,7 +457,18 @@ class SlotRecord {
         * @return string
         */
        public function getAddress() {
-               return $this->getStringField( 'cont_address' );
+               return $this->getStringField( 'content_address' );
+       }
+
+       /**
+        * Returns the ID of the content meta data row associated with the slot.
+        * This information should be irrelevant to application logic, it is here to allow
+        * the construction of a full row for the revision table.
+        *
+        * @return int
+        */
+       public function getContentId() {
+               return $this->getIntField( 'slot_content_id' );
        }
 
        /**
@@ -340,10 +478,10 @@ class SlotRecord {
         */
        public function getSize() {
                try {
-                       $size = $this->getIntField( 'cont_size' );
+                       $size = $this->getIntField( 'content_size' );
                } catch ( IncompleteRevisionException $ex ) {
                        $size = $this->getContent()->getSize();
-                       $this->setField( 'cont_size', $size );
+                       $this->setField( 'content_size', $size );
                }
 
                return $size;
@@ -356,7 +494,7 @@ class SlotRecord {
         */
        public function getSha1() {
                try {
-                       $sha1 = $this->getStringField( 'cont_sha1' );
+                       $sha1 = $this->getStringField( 'content_sha1' );
                } catch ( IncompleteRevisionException $ex ) {
                        $format = $this->hasField( 'format_name' )
                                ? $this->getStringField( 'format_name' )
@@ -364,7 +502,7 @@ class SlotRecord {
 
                        $data = $this->getContent()->serialize( $format );
                        $sha1 = self::base36Sha1( $data );
-                       $this->setField( 'cont_sha1', $sha1 );
+                       $this->setField( 'content_sha1', $sha1 );
                }
 
                return $sha1;
index 0a7f416..26e2d45 100644 (file)
@@ -88,8 +88,7 @@ class WebRequest {
         * @codeCoverageIgnore
         */
        public function __construct() {
-               $this->requestTime = isset( $_SERVER['REQUEST_TIME_FLOAT'] )
-                       ? $_SERVER['REQUEST_TIME_FLOAT'] : microtime( true );
+               $this->requestTime = $_SERVER['REQUEST_TIME_FLOAT'];
 
                // POST overrides GET data
                // We don't use $_REQUEST here to avoid interference from cookies...
index 66bedb2..431ea06 100644 (file)
@@ -42,6 +42,10 @@ class MarkpatrolledAction extends FormAction {
                return 'patrol';
        }
 
+       protected function usesOOUI() {
+               return true;
+       }
+
        protected function getRecentChange( $data = null ) {
                $rc = null;
                // Note: This works both on initial GET url and after submitting the form
index 73315a0..22202c0 100644 (file)
@@ -2465,7 +2465,7 @@ abstract class ApiBase extends ContextSource {
                                realpath( __DIR__ ) ?: __DIR__ => [
                                        'path' => $IP,
                                        'name' => 'MediaWiki',
-                                       'license-name' => 'GPL-2.0+',
+                                       'license-name' => 'GPL-2.0-or-later',
                                ],
                                realpath( "$IP/extensions" ) ?: "$IP/extensions" => null,
                                realpath( $extDir ) ?: $extDir => null,
index 18c36de..4b93b31 100644 (file)
@@ -298,7 +298,7 @@ abstract class ApiFormatBase extends ApiBase {
 
                        if ( $this->getIsWrappedHtml() ) {
                                // This is a special output mode mainly intended for ApiSandbox use
-                               $time = microtime( true ) - $this->getConfig()->get( 'RequestTime' );
+                               $time = $this->getMain()->getRequest()->getElapsedTime();
                                $json = FormatJson::encode(
                                        [
                                                'status' => (int)( $this->mHttpStatus ?: 200 ),
index f924736..3048273 100644 (file)
@@ -465,7 +465,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                'host' => $showHostnames
                                                ? $lb->getServerName( $index )
                                                : '',
-                               'lag' => intval( $lag )
+                               'lag' => $lag
                        ];
                }
 
index d7648b1..90af65f 100644 (file)
        "apihelp-opensearch-summary": "Vyhledávání na wiki pomocí protokolu OpenSearch.",
        "apihelp-opensearch-param-search": "Hledaný řetězec.",
        "apihelp-opensearch-param-limit": "Maximální počet vrácených výsledků",
-       "apihelp-opensearch-param-namespace": "Jmenné prostory pro vyhledávání.",
+       "apihelp-opensearch-param-namespace": "Jmenné prostory pro vyhledávání. Ignorováno, pokud <var>$1search</var> začíná platným jmenným prostorem.",
        "apihelp-opensearch-param-suggest": "Pokud je <var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> vypnuto, nedělat nic.",
        "apihelp-opensearch-param-format": "Formát výstupu.",
        "apihelp-opensearch-example-te": "Najít stránky začínající na „<kbd>Te</kbd>“.",
        "apihelp-query+langlinks-summary": "Zobrazit všechny mezijazykové odkazy z daných stránek.",
        "apihelp-query+langlinks-param-lang": "Zobrazit pouze jazykové odkazy s tímto kódem jazyka.",
        "apihelp-query+linkshere-example-generator": "Získat informace o stránkách, které odkazují na [[Hlavní Stránka|Hlavní stránku]].",
+       "apihelp-query+prefixsearch-param-namespace": "Jmenné prostory pro vyhledávání. Ignorováno, pokud <var>$1search</var> začíná platným jmenným prostorem.",
        "apihelp-query+recentchanges-param-excludeuser": "Nezobrazovat změny od tohoto uživatele.",
        "apihelp-query+recentchanges-example-simple": "Seznam posledních změn.",
        "apihelp-query+redirects-param-limit": "Počet přesměrování, který má být zobrazen.",
index b07ab6d..3145523 100644 (file)
@@ -16,7 +16,7 @@
                        "Yusuke1109"
                ]
        },
-       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|説明文書]]\n* [[mw:Special:MyLanguage/API:FAQ|よくある質問]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api メーリングリスト]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 告知]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R バグの報告とリクエスト]\n</div>\n<strong>状態:</strong> このページに表示されている機能は全て動作するはずですが、この API は未だ活発に開発されており、変更される可能性があります。アップデートの通知を受け取るには、[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce メーリングリスト]に参加してください。\n\n<strong>誤ったリクエスト:</strong> 誤ったリクエストが API に送られた場合、\"MediaWiki-API-Error\" HTTP ヘッダーが送信され、そのヘッダーの値と送り返されるエラーコードは同じ値にセットされます。より詳しい情報は [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]] を参照してください。\n\n<p class=\"mw-apisandbox-link\"><strong>テスト:</strong> API のリクエストのテストは、[[Special:ApiSandbox]]で簡単に行えます。</p>",
+       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|説明文書]]\n* [[mw:Special:MyLanguage/API:FAQ|よくある質問]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api メーリングリスト]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 告知]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R バグの報告とリクエスト]\n</div>\n<strong>状態:</strong> MediaWiki APIは、積極的にサポートされ、改善された成熟した安定したインターフェースです。避けようとはしていますが、時には壊れた変更が加えられるかもしれません。アップデートの通知を受け取るには、[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce メーリングリスト]に参加してください。\n\n<strong>誤ったリクエスト:</strong> 誤ったリクエストが API に送られた場合、\"MediaWiki-API-Error\" HTTP ヘッダーが送信され、そのヘッダーの値と送り返されるエラーコードは同じ値にセットされます。より詳しい情報は [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]] を参照してください。\n\n<p class=\"mw-apisandbox-link\"><strong>テスト:</strong> API のリクエストのテストは、[[Special:ApiSandbox]]で簡単に行えます。</p>",
        "apihelp-main-param-action": "実行する操作です。",
        "apihelp-main-param-format": "出力する形式です。",
        "apihelp-main-param-smaxage": "<code>s-maxage</code> HTTP キャッシュ コントロール ヘッダー に、この秒数を設定します。エラーがキャッシュされることはありません。",
@@ -26,7 +26,9 @@
        "apihelp-main-param-requestid": "任意の値を指定でき、その値が結果に含められます。リクエストを識別するために使用できます。",
        "apihelp-main-param-servedby": "リクエストを処理したホスト名を結果に含めます。",
        "apihelp-main-param-curtimestamp": "現在のタイムスタンプを結果に含めます。",
+       "apihelp-main-param-responselanginfo": "結果に<var>uselang</var>と<var>errorlang</var>に使用される言語を含めます。",
        "apihelp-main-param-uselang": "メッセージの翻訳に使用する言語です。<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> は <kbd>siprop=languages</kbd> を付けると言語コードの一覧を返します。<kbd>user</kbd> を指定することで現在の利用者の個人設定の言語を、<kbd>content</kbd> を指定することでこのウィキの本文の言語を使用することもできます。",
+       "apihelp-main-param-errorsuselocal": "指定された場合、エラーテキストは{{ns:MediaWiki}}名前空間からローカルにカスタマイズされたメッセージを使用します。",
        "apihelp-block-summary": "利用者をブロックします。",
        "apihelp-block-param-user": "ブロックを解除する利用者名、IPアドレスまたはIPレンジ。<var>$1userid</var>とは同時に使用できません。",
        "apihelp-block-param-userid": "ブロックする利用者のID。<var>$1user</var>とは同時に使用できません。",
        "apihelp-block-param-allowusertalk": "自身のトークページの編集を許可する (<var>[[mw:Special:MyLanguage/Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> に依存)。",
        "apihelp-block-param-reblock": "その利用者がすでにブロックされている場合、ブロックを上書きします。",
        "apihelp-block-param-watchuser": "その利用者またはIPアドレスの利用者ページとトークページをウォッチします。",
+       "apihelp-block-param-tags": "ブロック記録の項目に適用する変更タグ。",
        "apihelp-block-example-ip-simple": "IPアドレス <kbd>192.0.2.5</kbd> を <kbd>First strike<kbd> という理由で3日ブロックする",
        "apihelp-block-example-user-complex": "利用者 <kbd>Vandal</kbd> を <kbd>Vandalism</kbd> という理由で無期限ブロックし、新たなアカウント作成とメールの送信を禁止する。",
        "apihelp-changeauthenticationdata-example-password": "現在の利用者のパスワードを <kbd>ExamplePassword</kbd> に変更する。",
        "apihelp-checktoken-summary": "<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> のトークンの妥当性を確認します。",
        "apihelp-checktoken-param-type": "調べるトークンの種類。",
        "apihelp-checktoken-param-token": "調べるトークン。",
+       "apihelp-checktoken-param-maxtokenage": "トークンの最大有効期限 (秒)。",
        "apihelp-checktoken-example-simple": "<kbd>csrf</kbd> トークンの妥当性を調べる。",
        "apihelp-clearhasmsg-summary": "現在の利用者の <code>hasmsg</code> フラグを消去します。",
        "apihelp-clearhasmsg-example-1": "現在の利用者の <code>hasmsg</code> フラグを消去する。",
        "apihelp-opensearch-summary": "OpenSearch プロトコルを使用してWiki内を検索します。",
        "apihelp-opensearch-param-search": "検索文字列。",
        "apihelp-opensearch-param-limit": "返す結果の最大数。",
-       "apihelp-opensearch-param-namespace": "検索する名前空間。",
+       "apihelp-opensearch-param-namespace": "検索する名前空間。<var>$1search</var>が有効な名前空間接頭辞で始まる場合は無視されます。",
        "apihelp-opensearch-param-suggest": "<var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> が false の場合、何もしません。",
        "apihelp-opensearch-param-redirects": "転送を処理する方法:\n;return: 転送ページそのものを返します。\n;resolve: 転送先のページを返します。$1limit より返される結果が少なくなるかもしれません。\n歴史的な理由により、$1format=json では \"return\" が、他の形式では \"resolve\" が既定です。",
        "apihelp-opensearch-param-format": "出力する形式。",
        "apihelp-query+prefixsearch-summary": "ページ名の先頭一致検索を行います。",
        "apihelp-query+prefixsearch-extended-description": "名前が似ていますが、このモジュールは[[Special:PrefixIndex]]と等価であることを意図しません。そのような目的では<kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> を <kbd>apprefix</kbd> パラメーターと共に使用してください。このモジュールの目的は <kbd>[[Special:ApiHelp/opensearch|action=opensearch]]</kbd> と似ています: 利用者から入力を受け取り、最も適合するページ名を提供するというものです。検索エンジンのバックエンドによっては、誤入力の訂正や、転送の回避、その他のヒューリスティクスが適用されることがあります。",
        "apihelp-query+prefixsearch-param-search": "検索文字列。",
-       "apihelp-query+prefixsearch-param-namespace": "検索する名前空間。",
+       "apihelp-query+prefixsearch-param-namespace": "検索する名前空間。<var>$1search</var>が有効な名前空間接頭辞で始まる場合は無視されます。",
        "apihelp-query+prefixsearch-param-limit": "返す結果の最大数。",
        "apihelp-query+prefixsearch-example-simple": "<kbd>meaning</kbd> で始まるページ名を検索する。",
        "apihelp-query+protectedtitles-summary": "作成保護が掛けられているページを一覧表示します。",
        "apihelp-tokens-param-type": "リクエストするトークンの種類。",
        "apihelp-tokens-example-edit": "編集トークンを取得する (既定)。",
        "apihelp-unblock-summary": "利用者のブロックを解除します。",
-       "apihelp-unblock-param-id": "解除するブロックのID (<kbd>list=blocks</kbd>で取得できます)。<var>$1user</var> とは同時に使用できません。",
+       "apihelp-unblock-param-id": "解é\99¤ã\81\99ã\82\8bã\83\96ã\83­ã\83\83ã\82¯ã\81®ID (<kbd>list=blocks</kbd>ã\81§å\8f\96å¾\97ã\81§ã\81\8dã\81¾ã\81\99\80\82<var>$1user</var> ã\81¾ã\81\9fã\81¯ <var>$1userid</var> ã\81¨ã\81¯å\90\8cæ\99\82ã\81«ä½¿ç\94¨ã\81§ã\81\8dã\81¾ã\81\9bã\82\93ã\80\82",
        "apihelp-unblock-param-user": "ブロックを解除する利用者名、IPアドレスまたはIPレンジ。<var>$1id</var>とは同時に使用できません。",
        "apihelp-unblock-param-reason": "ブロック解除の理由。",
        "apihelp-unblock-param-tags": "ブロック記録の項目に適用する変更タグ。",
        "apihelp-userrights-summary": "利用者の所属グループを変更します。",
        "apihelp-userrights-param-user": "利用者名。",
        "apihelp-userrights-param-userid": "利用者ID。",
-       "apihelp-userrights-param-add": "利用者をこのグループに追加します。",
+       "apihelp-userrights-param-add": "å\88©ç\94¨è\80\85ã\82\92ã\81\93ã\81®ã\82°ã\83«ã\83¼ã\83\97ã\81«è¿½å\8a ã\81\99ã\82\8bã\81\8bã\80\81æ\97¢ã\81«ã\83¡ã\83³ã\83\90ã\83¼ã\81®å ´å\90\88ã\81¯ã\80\81ã\81\9dã\81®ã\82°ã\83«ã\83¼ã\83\97ã\81®ã\83¡ã\83³ã\83\90ã\83¼ã\82·ã\83\83ã\83\97ã\81®æ\9c\89å\8a¹æ\9c\9fé\99\90ã\82\92æ\9b´æ\96°ã\81\97ã\81¾ã\81\99ã\80\82",
        "apihelp-userrights-param-reason": "変更の理由。",
        "apihelp-userrights-example-expiry": "利用者 <kbd>SometimeSysop</kbd> を 1ヶ月間 <kbd>sysop</kbd> グループに追加する。",
        "apihelp-watch-summary": "現在の利用者のウォッチリストにページを追加/除去します。",
index eab3afb..3cfac8f 100644 (file)
@@ -332,6 +332,13 @@ abstract class ContentHandler {
                return self::$handlers[$modelId];
        }
 
+       /**
+        * Clean up handlers cache.
+        */
+       public static function cleanupHandlersCache() {
+               self::$handlers = [];
+       }
+
        /**
         * Returns the localized name for a given content model.
         *
index 0eadc3c..1128d7b 100644 (file)
@@ -29,6 +29,8 @@ class WikiTextStructure {
        private $excludedElementSelectors = [
                // "it looks like you don't have javascript enabled..." – do not need to index
                'audio', 'video',
+               // CSS stylesheets aren't content
+               'style',
                // The [1] for references
                'sup.reference',
                // The ↑ next to references in the references section
index 5c79117..f0a17f7 100644 (file)
@@ -23,6 +23,7 @@
 
 use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\LBFactory;
 use Wikimedia\Rdbms\DatabaseDomain;
 
 /**
@@ -201,4 +202,30 @@ abstract class MWLBFactory {
 
                return $class;
        }
+
+       public static function setSchemaAliases( LBFactory $lbFactory ) {
+               $mainLB = $lbFactory->getMainLB();
+               $masterType = $mainLB->getServerType( $mainLB->getWriterIndex() );
+               if ( $masterType === 'mysql' ) {
+                       /**
+                        * When SQLite indexes were introduced in r45764, it was noted that
+                        * SQLite requires index names to be unique within the whole database,
+                        * not just within a schema. As discussed in CR r45819, to avoid the
+                        * need for a schema change on existing installations, the indexes
+                        * were implicitly mapped from the new names to the old names.
+                        *
+                        * This mapping can be removed if DB patches are introduced to alter
+                        * the relevant tables in existing installations. Note that because
+                        * this index mapping applies to table creation, even new installations
+                        * of MySQL have the old names (except for installations created during
+                        * a period where this mapping was inappropriately removed, see
+                        * T154872).
+                        */
+                       $lbFactory->setIndexAliases( [
+                               'ar_usertext_timestamp' => 'usertext_timestamp',
+                               'un_user_id' => 'user_id',
+                               'un_user_ip' => 'user_ip',
+                       ] );
+               }
+       }
 }
index 012837f..7479841 100644 (file)
@@ -517,7 +517,7 @@ class MWDebug {
                        return [];
                }
 
-               global $wgVersion, $wgRequestTime;
+               global $wgVersion;
                $request = $context->getRequest();
 
                // HHVM's reported memory usage from memory_get_peak_usage()
@@ -540,7 +540,7 @@ class MWDebug {
                        'gitRevision' => GitInfo::headSHA1(),
                        'gitBranch' => $branch,
                        'gitViewUrl' => GitInfo::headViewUrl(),
-                       'time' => microtime( true ) - $wgRequestTime,
+                       'time' => $request->getElapsedTime(),
                        'log' => self::$log,
                        'debugLog' => self::$debug,
                        'queries' => self::$query,
index 14307b5..67f9a79 100644 (file)
@@ -38,7 +38,6 @@ class TableDiffFormatter extends DiffFormatter {
        }
 
        /**
-        * @static
         * @param string $msg
         *
         * @return mixed
index 2b71db0..12b9b55 100644 (file)
@@ -50,8 +50,8 @@ class DumpNamespaceFilter extends DumpFilter {
                        "NS_PROJECT_TALK"   => NS_PROJECT_TALK,
                        "NS_FILE"           => NS_FILE,
                        "NS_FILE_TALK"      => NS_FILE_TALK,
-                       "NS_IMAGE"          => NS_IMAGE, // NS_IMAGE is an alias for NS_FILE
-                       "NS_IMAGE_TALK"     => NS_IMAGE_TALK,
+                       "NS_IMAGE"          => NS_FILE, // NS_IMAGE is an alias for NS_FILE
+                       "NS_IMAGE_TALK"     => NS_FILE_TALK,
                        "NS_MEDIAWIKI"      => NS_MEDIAWIKI,
                        "NS_MEDIAWIKI_TALK" => NS_MEDIAWIKI_TALK,
                        "NS_TEMPLATE"       => NS_TEMPLATE,
index ad0c217..5edb4b2 100644 (file)
@@ -27,7 +27,7 @@ use Wikimedia\Rdbms\DBConnRef;
 use Wikimedia\Rdbms\MaintainableDBConnRef;
 
 /**
- * DB accessable external objects.
+ * DB accessible external objects.
  *
  * In this system, each store "location" maps to a database "cluster".
  * The clusters must be defined in the normal LBFactory configuration.
index 3d812c9..879686f 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 /**
- * Example class for HTTP accessable external objects.
+ * Example class for HTTP accessible external objects.
  * Only supports reading, not storing.
  *
  * @ingroup ExternalStorage
index 0c6d022..5d7155e 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 /**
- * File backend accessable external objects.
+ * File backend accessible external objects.
  *
  * In this system, each store "location" maps to the name of a file backend.
  * The file backends must be defined in $wgFileBackends and must be global
index ec4a5fb..7fc45eb 100644 (file)
@@ -3374,6 +3374,8 @@ class LocalFileMoveBatch {
         * many rows where updated.
         */
        protected function doDBUpdates() {
+               global $wgCommentTableSchemaMigrationStage;
+
                $dbw = $this->db;
 
                // Update current image
@@ -3383,6 +3385,15 @@ class LocalFileMoveBatch {
                        [ 'img_name' => $this->oldName ],
                        __METHOD__
                );
+               if ( $wgCommentTableSchemaMigrationStage > MIGRATION_OLD ) {
+                       $dbw->update(
+                               'image_comment_temp',
+                               [ 'imgcomment_name' => $this->newName ],
+                               [ 'imgcomment_name' => $this->oldName ],
+                               __METHOD__
+                       );
+               }
+
                // Update old images
                $dbw->update(
                        'oldimage',
index 78e7625..9b58f92 100644 (file)
@@ -504,7 +504,7 @@ class HTMLForm extends ContextSource {
        /**
         * Prepare form for submission.
         *
-        * @attention When doing method chaining, that should be the very last
+        * @warning When doing method chaining, that should be the very last
         * method call before displayForm().
         *
         * @throws MWException
@@ -1006,7 +1006,7 @@ class HTMLForm extends ContextSource {
         * Display the form (sending to the context's OutputPage object), with an
         * appropriate error message or stack of messages, and any validation errors, etc.
         *
-        * @attention You should call prepareForm() before calling this function.
+        * @warning You should call prepareForm() before calling this function.
         * Moreover, when doing method chaining this should be the very last method
         * call just after prepareForm().
         *
index 38a9ede..908dc94 100644 (file)
@@ -112,12 +112,14 @@ class MssqlUpdater extends DatabaseUpdater {
 
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
+                       [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
                        [ 'addTable', 'content', 'patch-content.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models.sql' ],
                        [ 'migrateArchiveText' ],
                        [ 'addTable', 'actor', 'patch-actor-table.sql' ],
                        [ 'migrateActors' ],
+                       [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
                ];
        }
 
index bce4690..710cebf 100644 (file)
@@ -332,12 +332,14 @@ class MysqlUpdater extends DatabaseUpdater {
 
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
+                       [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
                        [ 'addTable', 'content', 'patch-content.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models.sql' ],
                        [ 'migrateArchiveText' ],
                        [ 'addTable', 'actor', 'patch-actor-table.sql' ],
                        [ 'migrateActors' ],
+                       [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
                ];
        }
 
index 60ac23c..43b74f1 100644 (file)
@@ -133,6 +133,7 @@ class OracleUpdater extends DatabaseUpdater {
 
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
+                       [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
                        [ 'addTable', 'content', 'patch-content.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models.sql' ],
index 2bfadf4..48f47f5 100644 (file)
@@ -487,6 +487,15 @@ class PostgresUpdater extends DatabaseUpdater {
 
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots-table.sql' ],
+                       [ 'dropPgIndex', 'slots', 'slot_role_inherited' ],
+                       [ 'dropPgField', 'slots', 'slot_inherited' ],
+                       [ 'addPgField', 'slots', 'slot_origin', 'INTEGER NOT NULL' ],
+                       [
+                               'addPgIndex',
+                               'slots',
+                               'slot_revision_origin_role',
+                               '( slot_revision_id, slot_origin, slot_role_id )',
+                       ],
                        [ 'addTable', 'content', 'patch-content-table.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models-table.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles-table.sql' ],
@@ -763,6 +772,18 @@ END;
                $this->db->query( "ALTER INDEX $old RENAME TO $new" );
        }
 
+       protected function dropPgField( $table, $field ) {
+               $fi = $this->db->fieldInfo( $table, $field );
+               if ( is_null( $fi ) ) {
+                       $this->output( "...$table table does not contain $field field.\n" );
+
+                       return;
+               } else {
+                       $this->output( "Dropping column '$table.$field'\n" );
+                       $this->db->query( "ALTER TABLE $table DROP COLUMN $field" );
+               }
+       }
+
        protected function addPgField( $table, $field, $type ) {
                $fi = $this->db->fieldInfo( $table, $field );
                if ( !is_null( $fi ) ) {
index 3a755b6..7ed6f86 100644 (file)
@@ -198,10 +198,12 @@ class SqliteUpdater extends DatabaseUpdater {
                        [ 'addTable', 'content', 'patch-content.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models.sql' ],
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
+                       [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'migrateArchiveText' ],
                        [ 'addTable', 'actor', 'patch-actor-table.sql' ],
                        [ 'migrateActors' ],
+                       [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
                ];
        }
 
index e0e54c8..9d7e051 100644 (file)
@@ -155,6 +155,10 @@ class WebInstaller extends Installer {
 
                if ( isset( $session['settings'] ) ) {
                        $this->settings = $session['settings'] + $this->settings;
+                       // T187586 MediaWikiServices works with globals
+                       foreach ( $this->settings as $key => $val ) {
+                               $GLOBALS[$key] = $val;
+                       }
                }
 
                $this->setupLanguage();
index 92eef95..c449110 100644 (file)
@@ -79,6 +79,7 @@
        "config-no-cli-uploads-check": "<strong>Alvertencia:</strong> el to directoriu predetermináu pa cargues <code>$1</code> nun tá comprobáu contra la vulnerabilidá d'execución arbitraria de scripts mientres la instalación per llínea de comandos.",
        "config-brokenlibxml": "El sistema tien una combinación de versiones de PHP y de libxml2 que ye pocu confiable y puede provocar corrupción oculta nos datos de MediaWiki y otres aplicaciones web. Actualiza a libxml2 2.7.3 o posterior ([https://bugs.php.net/bug.php?díi=45996 bug reportáu con PHP]). Instalación albortada.",
        "config-suhosin-max-value-length": "Suhosin ta instaláu y llinda el parámetru <code>length</code> GET a $1 bytes.\nEl componente ResourceLoader (xestor de recursos) de MediaWiki va trabayar nesta llende, pero eso va perxudicar el rendimientu.\nSi ye posible, tendríes d'establecer <code>suhosin.get.max_value_length</code> nel valor 1024 o superior en <code>php.ini</code> y establecer <code>$wgResourceLoaderMaxQueryLength</code> nel mesmu valor en <code>LocalSettings.php</code>.",
+       "config-using-32bit": "<strong>Atención:</strong> paez que'l sistema funciona con enteros de 32 bits. Esto ta [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit desaconseyáu].",
        "config-db-type": "Tipu de base de datos:",
        "config-db-host": "Servidor de la base de datos:",
        "config-db-host-help": "Si'l to servidor de base de datos ta n'otru servidor, escribe'l nome del equipu o la so dirección IP equí.\n\nSi tas utilizando alojamiento web compartíu, el to provisor tendría de date'l nome correctu del servidor na so documentación.\n\nSi vas instalar nun servidor Windows y a utilizar MySQL, l'usu de \"localhost\" como nome del servidor puede nun #funcionar. Si ye asina, intenta poner \"127.0.0.1\" como dirección IP local.\n\nSi utilices PostgreSQL, dexa esti campu vacío pa conectase al traviés d'un socket de Unix.",
        "config-db-schema-help": "Esti esquema de vezu va tar bien.\nCamúdalos solo si sabes que lo precises.",
        "config-pg-test-error": "Nun puede coneutase cola base de datos <strong>$1</strong>: $2",
        "config-sqlite-dir": "Direutoriu de datos SQLite:",
+       "config-sqlite-dir-help": "SQLite almacena tolos datos nun ficheru únicu.\n\nEl direutoriu que proporciones tien de poder escribise pol servidor web mientres la instalación.\n\n<strong>Nun</strong> tendría de tener accesu pela web, por eso nun se pon nel sitiu onde tán los ficheros PHP.\n\nL'instalador escribirá un ficheru <code>.htaccess</code> xunto con él, pero si esto falla dalguién podría tener accesu a la base de datos completa.\nEso incluye los datos d'usuariu completos (direcciones de corréu electrónicu, contraseñes con hash) lo mesmo que les revisiones desaniciaes y otros datos acutaos de la wiki.\n\nConsidera poner la base de datos en dalgún otru sitiu, por casu en <code>/var/lib/mediawiki/miowiki</code>.",
        "config-oracle-def-ts": "Espaciu de tables predetermináu:",
        "config-oracle-temp-ts": "Espaciu de tables temporal:",
        "config-type-mysql": "MySQL (o compatible)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki ye compatible colos siguientes sistemes de bases de datos:\n\n$1\n\nSi nun atopes na llista el sistema de base de datos que tas intentando utilizar, sigue les instrucciones enllazaes enriba p'activar la compatibilidá.",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] ye un sistema comercial de base de datos empresariales pa Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Cómo compilar PHP con compatibilidá pa SQLSRV])",
        "config-header-mysql": "Configuración de MySQL",
        "config-header-postgres": "Configuración de PostgreSQL",
        "config-header-sqlite": "Configuración de SQLite",
        "config-postgres-old": "Ríquese PostgreSQL $1 o posterior. Tienes la versión $2.",
        "config-mssql-old": "Ríquese Microsoft SQL Server $1 o posterior. Tienes la versión $2.",
        "config-sqlite-name-help": "Escueye'l nome qu'identifica la to wiki.\nNun uses espacios o guiones.\nEsti va usase como nome del ficheru de datos pa SQLite.",
+       "config-sqlite-parent-unwritable-group": "Nun puede crease el direutoriu de datos <code><nowiki>$1</nowiki></code> porque'l servidor web nun tien permisu d'escritura nel direutoriu padre <code><nowiki>$2</nowiki></code>.\n\nL'instalador determinó l'usuariu col que s'executa'l sirvidor web.\nDa-y permisos d'escritura nel direutoriu <code><nowiki>$3</nowiki></code> pa siguir.\nNun sistema Unix/Linux fai:\n\n<pre>cd $2\nmkdir $3\nchgrp $4 $3\nchmod g+w $3</pre>",
+       "config-sqlite-parent-unwritable-nogroup": "Nun puede crease'l direutoriu de datos <code><nowiki>$1</nowiki></code>, porque'l sirvidor web nun tien permisu d'escritura nel direutoriu padre <code><nowiki>$2</nowiki></code>.\n\nL'instalador nun pudo determinar l'usuariu col que s'executa'l sirvidor web.\nDa permisos d'escritura universal pa él (¡y pa otros!) nel direutoriu <code><nowiki>$3</nowiki></code> pa siguir.\nNun sistema Unix/Linux fai:\n\n<pre>cd $2\nmkdir $3\nchmod a+w $3</pre>",
+       "config-sqlite-mkdir-error": "Error al crear el direutoriu de datos «$1».\nComprueba la direición y tenta otra vuelta.",
+       "config-sqlite-dir-unwritable": "Nun puede escribise nel direutoriu «$1».\nCambia los sos permisos pa que'l sirvidor web pueda escribir nél, y tenta otra vuelta.",
+       "config-sqlite-connection-error": "$1.\n\nComprueba más abaxo'l direutoriu de datos ya'l nome de la base de datos y tenta otra vuelta.",
+       "config-sqlite-readonly": "El ficheru <code>$1</code> nun puede escribise.",
+       "config-sqlite-cant-create-db": "Nun pudo crease'l ficheru de la base de datos <code>$1</code>.",
+       "config-sqlite-fts3-downgrade": "PHP nun tien compatibilidá pa FTS3, baxando a una versión anterior les tables.",
+       "config-regenerate": "Rexenerar LocalSettings.php →",
+       "config-show-table-status": "¡Falló la consulta <code>SHOW TABLE STATUS</code>!",
+       "config-unknown-collation": "<strong>Avisu:</strong> La base de datos utiliza un orde alfabéticu ensin reconocer.",
+       "config-db-web-account": "Cuenta de la base de datos pal accesu web",
+       "config-db-web-help": "Escueye l'usuariu y contraseña que'l sirvidor web usará pa coneutase col sirvidor de la base de datos nel funcionamientu normal de la wiki.",
+       "config-db-web-account-same": "Utilizar la mesma cuenta que pa la instalación",
+       "config-db-web-create": "Crear la cuenta si nun esiste yá",
+       "config-db-web-no-create-privs": "La cuenta qu'especificasti pa la instalación nun tien permisos abondo pa crear una cuenta.\nLa cuenta qu'especifiques equí yá tien d'esistir.",
+       "config-mysql-engine": "Motor d'almacenamientu:",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
+       "config-mysql-binary": "Binariu",
        "config-mysql-utf8": "UTF-8",
        "config-mssql-auth": "Triba d'autenticación:",
        "config-site-name": "Nome de la wiki:",
        "config-admin-password": "Contraseña:",
        "config-optional-skip": "Yá toi aburríu, namái instala la wiki.",
        "config-profile-private": "Wiki privada",
+       "config-license": "Derechos d'autor y llicencia:",
+       "config-license-none": "Ensin pie de llicencia",
+       "config-license-cc-by-sa": "Creative Commons Reconocimientu-CompartirIgual",
+       "config-license-cc-by": "Creative Commons Reconocimientu",
+       "config-license-cc-by-nc-sa": "Creative Commons Reconocimientu-NonComercial-CompartirIgual",
+       "config-license-cc-0": "Creative Commons Zero (Dominiu públicu)",
+       "config-license-gfdl": "Llicencia de documentación llibre de GNU 1.3 o posterior",
+       "config-license-pd": "Dominiu públicu",
+       "config-license-cc-choose": "Escoyer una llicencia Creative Commons  personalizada",
+       "config-email-settings": "Configuración de corréu electrónicu",
+       "config-enable-email": "Activar el corréu electrónicu de salida",
+       "config-enable-email-help": "Si quies que'l corréu electrónicu funcione, les [http://www.php.net/manual/en/mail.configuration.php preferencies de corréu de PHP] tienen de tar configuraes correutamente.\nSi nun quies les funciones de corréu electrónicu, puedes desactivales equí.",
+       "config-email-user": "Activar el corréu electrónicu ente usuarios",
+       "config-logo": "URL del logo:",
+       "config-instantcommons": "Activar Instant Commons",
        "config-extensions": "Estensiones",
+       "config-skins": "Apariencies",
+       "config-skins-help": "Deteutáronse les apariencies de la llista anterior nel direutoriu <code>./skins</code>. Tienes d'activar siquier una, y escoyer la predeterminada.",
+       "config-skins-use-as-default": "Utilizar esta apariencia como predeterminada",
+       "config-skins-missing": "Nun s'atopó nenguna apariencia; MediaWiki utilizará una apariencia de respaldu hasta qu'instales delles apariencies afayadices.",
+       "config-skins-must-enable-some": "Tienes d'escoyer polo meno una apariencia p'activar.",
+       "config-skins-must-enable-default": "L'apariencia escoyida como predeterminada tien de tar activada.",
+       "config-install-step-done": "fecho",
+       "config-install-step-failed": "falló",
+       "config-install-extensions": "Incluyendo estensiones",
+       "config-install-database": "Configurando la base de datos",
+       "config-install-schema": "Creando l'esquema",
+       "config-install-pg-schema-not-exist": "L'esquema PostgreSQL nun esiste.",
        "config-download-localsettings": "Descargar <code>LocalSettings.php</code>",
        "config-help": "Ayuda",
        "config-nofile": "Nun pudo atopase'l ficheru \"$1\". ¿Desaniciose?",
+       "config-skins-screenshots": "$1 (imaxes de pantalla: $2)",
+       "config-screenshot": "imaxe de pantalla",
        "mainpagetext": "<strong>Instalóse MediaWiki.</strong>",
        "mainpagedocfooter": "Consulta la [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guía del usuariu] pa saber cómo usar el software wiki.\n\n== Primeros pasos ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Llista de les opciones de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ EMF de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de corréu de llanzamientos de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Llocaliza MediaWiki na to llingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Depriende como combatir la puxarra na to wiki]"
 }
index ba766e1..5b4718c 100644 (file)
@@ -23,7 +23,8 @@
                        "Macofe",
                        "Sethakill",
                        "Peter Bowman",
-                       "Ankam"
+                       "Ankam",
+                       "Railfail536"
                ]
        },
        "config-desc": "Instalator MediaWiki",
@@ -98,6 +99,7 @@
        "config-no-cli-uploads-check": "'''Ostrzeżenie:''' Katalog domyślny przesyłanych plików ( <code>$1</code> ) nie jest sprawdzona względem luki\n wykonania dowolnego skryptu podczas instalacji CLI w zabezpieczeniach.",
        "config-brokenlibxml": "Twój system jest kombinacją wersji PHP i libxml2, która zawiera błędy mogące powodować ukryte uszkodzenia danych w MediaWiki i innych aplikacjach sieci web.\nWykonaj aktualizację libxml2 do wersji 2.7.3 lub późniejszej ([https://bugs.php.net/bug.php?id=45996 bug filed with PHP]).\nInstalacja została przerwana.",
        "config-suhosin-max-value-length": "Jest zainstalowany Suhosin i ogranicza długość parametru GET <code>length</code> do $1 bajtów. Komponent ResourceLoader w MediaWiki wykona obejście tego ograniczenia, ale kosztem wydajności.\nJeśli to możliwe, należy ustawić <code>suhosin.get.max_value_length</code> na 1024 lub więcej w <code>php.ini</code> oraz ustawić <code>$wgResourceLoaderMaxQueryLength</code> w <code>LocalSettings.php</code> na tę samą wartość.",
+       "config-using-32bit": "<strong>Uwaga:</strong> twój system wydaje się działać na 32 bitowej architekturze. Jest to [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit niezalecane].",
        "config-db-type": "Typ bazy danych:",
        "config-db-host": "Adres serwera bazy danych:",
        "config-db-host-help": "Jeśli serwer bazy danych jest na innej maszynie, wprowadź jej nazwę domenową lub adres IP.\n\nJeśli korzystasz ze współdzielonego hostingu, operator serwera powinien podać Ci prawidłową nazwę serwera w swojej dokumentacji.\n\nJeśli instalujesz oprogramowanie na serwerze Windows i korzystasz z MySQL, użycie „localhost” może nie zadziałać jako nazwa hosta. Jeśli wystąpi ten problem, użyj „127.0.0.1” jako lokalnego adresu IP.\n\nJeżeli korzystasz z PostgreSQL, pozostaw to pole puste, aby połączyć się poprzez gniazdo Unixa.",
index abf60b2..30e2b9a 100644 (file)
@@ -7,7 +7,8 @@
                        "Aktron",
                        "Сербијана",
                        "Zoranzoki21",
-                       "Acamicamacaraca"
+                       "Acamicamacaraca",
+                       "Obsuser"
                ]
        },
        "config-desc": "Инсталација за Медијавики",
        "config-skins-screenshot": "$1 ($2)",
        "config-screenshot": "снимак екрана",
        "mainpagetext": "<strong>Медијавики је успешно инсталиран.</strong>",
-       "mainpagedocfooter": "Ð\9fогледаÑ\98Ñ\82е [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents ÐºÐ¾Ñ\80иÑ\81ниÑ\87ки Ð²Ð¾Ð´Ð¸Ñ\87] Ð·Ð° ÐºÐ¾Ñ\80иÑ\88Ñ\9bеÑ\9aе Ð¿Ñ\80огÑ\80ама.\n\n== Ð£Ð²Ð¾Ð´ ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Ð\9fомоÑ\9b Ñ\83 Ð²ÐµÐ·Ð¸ Ñ\81а Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aима]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Ð§ÐµÑ\81Ñ\82о Ð¿Ð¾Ñ\81Ñ\82авÑ\99ена Ð¿Ð¸Ñ\82аÑ\9aа]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Ð\94опиÑ\81ни Ñ\81пиÑ\81ак Ð¾ Ð¸Ð·Ð´Ð°Ñ\9aима Ð\9cедиÑ\98авикиÑ\98а]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Ð\9dаÑ\83Ñ\87иÑ\82е ÐºÐ°ÐºÐ¾ Ð´Ð° Ñ\81е Ð±Ð¾Ñ\80иÑ\82е Ð¿Ñ\80оÑ\82ив Ñ\81пама Ð½Ð° Ð\92аÑ\88ој вики]"
+       "mainpagedocfooter": "Ð\9fогледаÑ\98Ñ\82е [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents ÐºÐ¾Ñ\80иÑ\81ниÑ\87ки Ð²Ð¾Ð´Ð¸Ñ\87] Ð·Ð° ÐºÐ¾Ñ\80иÑ\88Ñ\9bеÑ\9aе Ð¿Ñ\80огÑ\80ама.\n\n== Ð£Ð²Ð¾Ð´ ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Ð\9fомоÑ\9b Ñ\83 Ð²ÐµÐ·Ð¸ Ñ\81а Ð¿Ð¾Ð´ÐµÑ\88аваÑ\9aима]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Ð§ÐµÑ\81Ñ\82о Ð¿Ð¾Ñ\81Ñ\82авÑ\99ана Ð¿Ð¸Ñ\82аÑ\9aа]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Ð\94опиÑ\81ни Ñ\81пиÑ\81ак Ð¾ Ð¸Ð·Ð´Ð°Ñ\9aима Ð\9cедиÑ\98авикиÑ\98а]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Ð\9dаÑ\83Ñ\87иÑ\82е ÐºÐ°ÐºÐ¾ Ð´Ð° Ñ\81е Ð±Ð¾Ñ\80иÑ\82е Ð¿Ñ\80оÑ\82ив Ñ\81пама Ð½Ð° Ñ\81воÑ\98ој вики]"
 }
index 118b0f9..7f3b2b1 100644 (file)
@@ -187,7 +187,7 @@ class JobQueueFederated extends JobQueue {
                // phpcs:ignore Generic.CodeAnalysis.ForLoopWithTestFunctionCall
                for ( $i = $this->maxPartitionsTry; $i > 0 && count( $jobsLeft ); --$i ) {
                        try {
-                               $partitionRing->getLiveRing();
+                               $partitionRing->getLiveLocationWeights();
                        } catch ( UnexpectedValueException $e ) {
                                break; // all servers down; nothing to insert to
                        }
index 21558f7..3b9c24d 100644 (file)
@@ -83,7 +83,7 @@ class HashRing {
         * @param string $item
         * @return string Location
         */
-       public function getLocation( $item ) {
+       final public function getLocation( $item ) {
                $locations = $this->getLocations( $item, 1 );
 
                return $locations[0];
@@ -136,19 +136,6 @@ class HashRing {
                return $this->sourceMap;
        }
 
-       /**
-        * Get a new hash ring with a location removed from the ring
-        *
-        * @param string $location
-        * @return HashRing|bool Returns false if no non-zero weighted spots are left
-        */
-       public function newWithoutLocation( $location ) {
-               $map = $this->sourceMap;
-               unset( $map[$location] );
-
-               return count( $map ) ? new self( $map ) : false;
-       }
-
        /**
         * Remove a location from the "live" hash ring
         *
@@ -174,7 +161,7 @@ class HashRing {
         * @return HashRing
         * @throws UnexpectedValueException
         */
-       public function getLiveRing() {
+       protected function getLiveRing() {
                $now = time();
                if ( $this->liveRing === null || $this->ejectionNextExpiry <= $now ) {
                        $this->ejectionExpiries = array_filter(
index 1c141ab..6e6ad7c 100644 (file)
@@ -16,7 +16,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  *
  * @file
- * @license GPL-2.0+
+ * @license GPL-2.0-or-later
  * @author Kunal Mehta <legoktm@member.fsf.org>
  */
 
index 57c253d..7b1a914 100644 (file)
@@ -94,9 +94,7 @@ class Timing implements LoggerAwareInterface {
                                'requestStart' => [
                                        'name'      => 'requestStart',
                                        'entryType' => 'mark',
-                                       'startTime' => isset( $_SERVER['REQUEST_TIME_FLOAT'] )
-                                               ? $_SERVER['REQUEST_TIME_FLOAT']
-                                               : $_SERVER['REQUEST_TIME'],
+                                       'startTime' => $_SERVER['REQUEST_TIME_FLOAT'],
                                        'duration'  => 0,
                                ],
                        ];
index 84c1182..4de8e77 100644 (file)
@@ -10,7 +10,7 @@ namespace Wikimedia\Http;
  * To use this with a request header, first parse the header value into an array of weights
  * using HttpAcceptParser, then call getBestSupportedKey.
  *
- * @license GPL-2.0+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  * @author Thiemo Kreuz
  */
index bce071e..df22b41 100644 (file)
@@ -4,7 +4,7 @@
  * Utility for parsing a HTTP Accept header value into a weight map. May also be used with
  * other, similar headers like Accept-Language, Accept-Encoding, etc.
  *
- * @license GPL-2.0+
+ * @license GPL-2.0-or-later
  * @author Daniel Kinzler
  */
 
index f26b985..6726aea 100644 (file)
@@ -281,7 +281,7 @@ class DBConnRef implements IDatabase {
        }
 
        public function estimateRowCount(
-               $table, $vars = '*', $conds = '', $fname = __METHOD__, $options = []
+               $table, $vars = '*', $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
        ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -460,7 +460,7 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function wasErrorReissuable() {
+       public function wasConnectionLoss() {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -468,6 +468,10 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       public function wasErrorReissuable() {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
+
        public function masterPosWait( DBMasterPos $pos, $timeout ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -618,6 +622,10 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
+       public function setIndexAliases( array $aliases ) {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
+
        /**
         * Clean up the connection when out of scope
         */
index 014c4af..2d90be6 100644 (file)
@@ -33,6 +33,7 @@ use Wikimedia\Timestamp\ConvertibleTimestamp;
 use Wikimedia;
 use BagOStuff;
 use HashBagOStuff;
+use LogicException;
 use InvalidArgumentException;
 use Exception;
 use RuntimeException;
@@ -62,27 +63,35 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        /** @var string Whether lock granularity is on the level of the entire database */
        const ATTR_DB_LEVEL_LOCKING = 'db-level-locking';
 
+       /** @var int New Database instance will not be connected yet when returned */
+       const NEW_UNCONNECTED = 0;
+       /** @var int New Database instance will already be connected when returned */
+       const NEW_CONNECTED = 1;
+
        /** @var string SQL query */
        protected $lastQuery = '';
        /** @var float|bool UNIX timestamp of last write query */
        protected $lastWriteTime = false;
        /** @var string|bool */
        protected $phpError = false;
-       /** @var string */
+       /** @var string Server that this instance is currently connected to */
        protected $server;
-       /** @var string */
+       /** @var string User that this instance is currently connected under the name of */
        protected $user;
-       /** @var string */
+       /** @var string Password used to establish the current connection */
        protected $password;
-       /** @var string */
+       /** @var string Database that this instance is currently connected to */
        protected $dbName;
-       /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
+       /** @var array[] Map of (table => (dbname, schema, prefix) map) */
        protected $tableAliases = [];
+       /** @var string[] Map of (index alias => index) */
+       protected $indexAliases = [];
        /** @var bool Whether this PHP instance is for a CLI script */
        protected $cliMode;
        /** @var string Agent name for query profiling */
        protected $agent;
-
+       /** @var array Parameters used by initConnection() to establish a connection */
+       protected $connectionParams = [];
        /** @var BagOStuff APC cache */
        protected $srvCache;
        /** @var LoggerInterface */
@@ -244,18 +253,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        protected $nonNativeInsertSelectBatchSize = 10000;
 
        /**
-        * Constructor and database handle and attempt to connect to the DB server
-        *
-        * IDatabase classes should not be constructed directly in external
-        * code. Database::factory() should be used instead.
-        *
+        * @note: exceptions for missing libraries/drivers should be thrown in initConnection()
         * @param array $params Parameters passed from Database::factory()
         */
-       function __construct( array $params ) {
-               $server = $params['host'];
-               $user = $params['user'];
-               $password = $params['password'];
-               $dbName = $params['dbname'];
+       protected function __construct( array $params ) {
+               foreach ( [ 'host', 'user', 'password', 'dbname' ] as $name ) {
+                       $this->connectionParams[$name] = $params[$name];
+               }
 
                $this->schema = $params['schema'];
                $this->tablePrefix = $params['tablePrefix'];
@@ -291,13 +295,22 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                // Set initial dummy domain until open() sets the final DB/prefix
                $this->currentDomain = DatabaseDomain::newUnspecified();
+       }
 
-               if ( $user ) {
-                       $this->open( $server, $user, $password, $dbName );
-               } elseif ( $this->requiresDatabaseUser() ) {
-                       throw new InvalidArgumentException( "No database user provided." );
+       /**
+        * Initialize the connection to the database over the wire (or to local files)
+        *
+        * @throws LogicException
+        * @throws InvalidArgumentException
+        * @throws DBConnectionError
+        * @since 1.31
+        */
+       final public function initConnection() {
+               if ( $this->isOpen() ) {
+                       throw new LogicException( __METHOD__ . ': already connected.' );
                }
-
+               // Establish the connection
+               $this->doInitConnection();
                // Set the domain object after open() sets the relevant fields
                if ( $this->dbName != '' ) {
                        // Domains with server scope but a table prefix are not used by IDatabase classes
@@ -305,6 +318,26 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
        }
 
+       /**
+        * Actually connect to the database over the wire (or to local files)
+        *
+        * @throws InvalidArgumentException
+        * @throws DBConnectionError
+        * @since 1.31
+        */
+       protected function doInitConnection() {
+               if ( strlen( $this->connectionParams['user'] ) ) {
+                       $this->open(
+                               $this->connectionParams['host'],
+                               $this->connectionParams['user'],
+                               $this->connectionParams['password'],
+                               $this->connectionParams['dbname']
+                       );
+               } else {
+                       throw new InvalidArgumentException( "No database user provided." );
+               }
+       }
+
        /**
         * Construct a Database subclass instance given a database type and parameters
         *
@@ -343,11 +376,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         *   - agent: Optional name used to identify the end-user in query profiling/logging.
         *   - srvCache: Optional BagOStuff instance to an APC-style cache.
         *   - nonNativeInsertSelectBatchSize: Optional batch size for non-native INSERT SELECT emulation.
+        * @param int $connect One of the class constants (NEW_CONNECTED, NEW_UNCONNECTED) [optional]
         * @return Database|null If the database driver or extension cannot be found
         * @throws InvalidArgumentException If the database driver or extension cannot be found
         * @since 1.18
         */
-       final public static function factory( $dbType, $p = [] ) {
+       final public static function factory( $dbType, $p = [], $connect = self::NEW_CONNECTED ) {
                $class = self::getClass( $dbType, isset( $p['driver'] ) ? $p['driver'] : null );
 
                if ( class_exists( $class ) && is_subclass_of( $class, IDatabase::class ) ) {
@@ -380,7 +414,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                };
                        }
 
+                       /** @var Database $conn */
                        $conn = new $class( $p );
+                       if ( $connect == self::NEW_CONNECTED ) {
+                               $conn->initConnection();
+                       }
                } else {
                        $conn = null;
                }
@@ -607,7 +645,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function writesOrCallbacksPending() {
                return $this->trxLevel && (
-                       $this->trxDoneWrites || $this->trxIdleCallbacks || $this->trxPreCommitCallbacks
+                       $this->trxDoneWrites ||
+                       $this->trxIdleCallbacks ||
+                       $this->trxPreCommitCallbacks ||
+                       $this->trxEndCallbacks
                );
        }
 
@@ -810,21 +851,38 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
        public function close() {
                if ( $this->conn ) {
+                       // Resolve any dangling transaction first
                        if ( $this->trxLevel() ) {
+                               // Meaningful transactions should ideally have been resolved by now
+                               if ( $this->writesOrCallbacksPending() ) {
+                                       $this->queryLogger->warning(
+                                               __METHOD__ . ": writes or callbacks still pending.",
+                                               [ 'trace' => ( new RuntimeException() )->getTraceAsString() ]
+                                       );
+                               }
+                               // Check if it is possible to properly commit and trigger callbacks
+                               if ( $this->trxEndCallbacksSuppressed ) {
+                                       throw new DBUnexpectedError(
+                                               $this,
+                                               __METHOD__ . ': callbacks are suppressed; cannot properly commit.'
+                                       );
+                               }
+                               // Commit the changes and run any callbacks as needed
                                $this->commit( __METHOD__, self::FLUSHING_INTERNAL );
                        }
-
+                       // Close the actual connection in the binding handle
                        $closed = $this->closeConnection();
                        $this->conn = false;
-               } elseif (
-                       $this->trxIdleCallbacks ||
-                       $this->trxPreCommitCallbacks ||
-                       $this->trxEndCallbacks
-               ) { // sanity
-                       throw new RuntimeException( "Transaction callbacks still pending." );
+                       // Sanity check that no callbacks are dangling
+                       if (
+                               $this->trxIdleCallbacks || $this->trxPreCommitCallbacks || $this->trxEndCallbacks
+                       ) {
+                               throw new RuntimeException( "Transaction callbacks still pending." );
+                       }
                } else {
-                       $closed = true;
+                       $closed = true; // already closed; nothing to do
                }
+
                $this->opened = false;
 
                return $closed;
@@ -859,11 +917,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        /**
-        * The DBMS-dependent part of query()
+        * Run a query and return a DBMS-dependent wrapper (that has all IResultWrapper methods)
+        *
+        * This might return things, such as mysqli_result, that do not formally implement
+        * IResultWrapper, but nonetheless implement all of its methods correctly
         *
         * @param string $sql SQL query.
-        * @return ResultWrapper|bool Result object to feed to fetchObject,
-        *   fetchRow, ...; or false on failure
+        * @return IResultWrapper|bool Iterator to feed to fetchObject/fetchRow; false on failure
         */
        abstract protected function doQuery( $sql );
 
@@ -1001,7 +1061,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $ret = $this->doProfiledQuery( $sql, $commentedSql, $isNonTempWrite, $fname );
 
                # Try reconnecting if the connection was lost
-               if ( false === $ret && $this->wasErrorReissuable() ) {
+               if ( false === $ret && $this->wasConnectionLoss() ) {
                        $recoverable = $this->canRecoverFromDisconnect( $sql, $priorWritesPending );
                        # Stash the last error values before anything might clear them
                        $lastError = $this->lastError();
@@ -1528,17 +1588,14 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function estimateRowCount(
-               $table, $vars = '*', $conds = '', $fname = __METHOD__, $options = []
+               $table, $vars = '*', $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
        ) {
-               $rows = 0;
-               $res = $this->select( $table, [ 'rowcount' => 'COUNT(*)' ], $conds, $fname, $options );
-
-               if ( $res ) {
-                       $row = $this->fetchRow( $res );
-                       $rows = ( isset( $row['rowcount'] ) ) ? (int)$row['rowcount'] : 0;
-               }
+               $res = $this->select(
+                       $table, [ 'rowcount' => 'COUNT(*)' ], $conds, $fname, $options, $join_conds
+               );
+               $row = $res ? $this->fetchRow( $res ) : [];
 
-               return $rows;
+               return isset( $row['rowcount'] ) ? (int)$row['rowcount'] : 0;
        }
 
        public function selectRowCount(
@@ -2142,9 +2199,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        if ( is_array( $table ) ) {
                                // A parenthesized group
                                if ( count( $table ) > 1 ) {
-                                       $joinedTable = '('
-                                               . $this->tableNamesWithIndexClauseOrJOIN( $table, $use_index, $ignore_index, $join_conds )
-                                               . ')';
+                                       $joinedTable = '(' .
+                                               $this->tableNamesWithIndexClauseOrJOIN(
+                                                       $table, $use_index, $ignore_index, $join_conds ) . ')';
                                } else {
                                        // Degenerate case
                                        $innerTable = reset( $table );
@@ -2220,7 +2277,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return string
         */
        protected function indexName( $index ) {
-               return $index;
+               return isset( $this->indexAliases[$index] )
+                       ? $this->indexAliases[$index]
+                       : $index;
        }
 
        public function addQuotes( $s ) {
@@ -2300,7 +2359,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        }
                }
 
-               return ' LIKE ' . $this->addQuotes( $s ) . ' ESCAPE ' . $this->addQuotes( $escapeChar ) . ' ';
+               return ' LIKE ' .
+                       $this->addQuotes( $s ) . ' ESCAPE ' . $this->addQuotes( $escapeChar ) . ' ';
        }
 
        public function anyChar() {
@@ -2828,14 +2888,22 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return false;
        }
 
-       public function wasErrorReissuable() {
-               return false;
+       public function wasConnectionLoss() {
+               return $this->wasConnectionError( $this->lastErrno() );
        }
 
        public function wasReadOnlyError() {
                return false;
        }
 
+       public function wasErrorReissuable() {
+               return (
+                       $this->wasDeadlock() ||
+                       $this->wasLockTimeout() ||
+                       $this->wasConnectionLoss()
+               );
+       }
+
        /**
         * Do not use this method outside of Database/DBError classes
         *
@@ -3875,12 +3943,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->tableAliases = $aliases;
        }
 
-       /**
-        * @return bool Whether a DB user is required to access the DB
-        * @since 1.28
-        */
-       protected function requiresDatabaseUser() {
-               return true;
+       public function setIndexAliases( array $aliases ) {
+               $this->indexAliases = $aliases;
        }
 
        /**
@@ -3890,7 +3954,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * This catches broken callers than catch and ignore disconnection exceptions.
         * Unlike checking isOpen(), this is safe to call inside of open().
         *
-        * @return resource|object
+        * @return mixed
         * @throws DBUnexpectedError
         * @since 1.26
         */
index b6428c7..885880a 100644 (file)
@@ -509,15 +509,16 @@ class DatabaseMssql extends Database {
         * @param string $conds
         * @param string $fname
         * @param array $options
+        * @param array $join_conds
         * @return int
         */
        public function estimateRowCount( $table, $vars = '*', $conds = '',
-               $fname = __METHOD__, $options = []
+               $fname = __METHOD__, $options = [], $join_conds = []
        ) {
                // http://msdn2.microsoft.com/en-us/library/aa259203.aspx
                $options['EXPLAIN'] = true;
                $options['FOR COUNT'] = true;
-               $res = $this->select( $table, $vars, $conds, $fname, $options );
+               $res = $this->select( $table, $vars, $conds, $fname, $options, $join_conds );
 
                $rows = -1;
                if ( $res ) {
index 8fb8db5..7537578 100644 (file)
@@ -562,13 +562,14 @@ abstract class DatabaseMysqlBase extends Database {
         * @param string|array $conds
         * @param string $fname
         * @param string|array $options
+        * @param array $join_conds
         * @return bool|int
         */
        public function estimateRowCount( $table, $vars = '*', $conds = '',
-               $fname = __METHOD__, $options = []
+               $fname = __METHOD__, $options = [], $join_conds = []
        ) {
                $options['EXPLAIN'] = true;
-               $res = $this->select( $table, $vars, $conds, $fname, $options );
+               $res = $this->select( $table, $vars, $conds, $fname, $options, $join_conds );
                if ( $res === false ) {
                        return false;
                }
@@ -1281,10 +1282,6 @@ abstract class DatabaseMysqlBase extends Database {
                return $this->lastErrno() == 1205;
        }
 
-       public function wasErrorReissuable() {
-               return $this->lastErrno() == 2013 || $this->lastErrno() == 2006;
-       }
-
        /**
         * Determines if the last failure was due to the database being read-only.
         *
@@ -1418,40 +1415,6 @@ abstract class DatabaseMysqlBase extends Database {
                return in_array( $name, $this->listViews( $prefix ) );
        }
 
-       /**
-        * Allows for index remapping in queries where this is not consistent across DBMS
-        *
-        * @param string $index
-        * @return string
-        */
-       protected function indexName( $index ) {
-               /**
-                * When SQLite indexes were introduced in r45764, it was noted that
-                * SQLite requires index names to be unique within the whole database,
-                * not just within a schema. As discussed in CR r45819, to avoid the
-                * need for a schema change on existing installations, the indexes
-                * were implicitly mapped from the new names to the old names.
-                *
-                * This mapping can be removed if DB patches are introduced to alter
-                * the relevant tables in existing installations. Note that because
-                * this index mapping applies to table creation, even new installations
-                * of MySQL have the old names (except for installations created during
-                * a period where this mapping was inappropriately removed, see
-                * T154872).
-                */
-               $renamed = [
-                       'ar_usertext_timestamp' => 'usertext_timestamp',
-                       'un_user_id' => 'user_id',
-                       'un_user_ip' => 'user_ip',
-               ];
-
-               if ( isset( $renamed[$index] ) ) {
-                       return $renamed[$index];
-               } else {
-                       return $index;
-               }
-       }
-
        protected function isTransactableQuery( $sql ) {
                return parent::isTransactableQuery( $sql ) &&
                        !preg_match( '/^SELECT\s+(GET|RELEASE|IS_FREE)_LOCK\(/', $sql );
index 984e1c0..0a5450c 100644 (file)
@@ -37,7 +37,7 @@ use stdClass;
 class DatabaseMysqli extends DatabaseMysqlBase {
        /**
         * @param string $sql
-        * @return resource
+        * @return mysqli_result
         */
        protected function doQuery( $sql ) {
                $conn = $this->getBindingHandle();
@@ -332,6 +332,13 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                        return (string)$this->conn;
                }
        }
+
+       /**
+        * @return mysqli
+        */
+       protected function getBindingHandle() {
+               return parent::getBindingHandle();
+       }
 }
 
 class_alias( DatabaseMysqli::class, 'DatabaseMysqli' );
index 38cc4ae..49c945e 100644 (file)
@@ -413,13 +413,14 @@ class DatabasePostgres extends Database {
         * @param string $conds
         * @param string $fname
         * @param array $options
+        * @param array $join_conds
         * @return int
         */
        public function estimateRowCount( $table, $vars = '*', $conds = '',
-               $fname = __METHOD__, $options = []
+               $fname = __METHOD__, $options = [], $join_conds = []
        ) {
                $options['EXPLAIN'] = true;
-               $res = $this->select( $table, $vars, $conds, $fname, $options );
+               $res = $this->select( $table, $vars, $conds, $fname, $options, $join_conds );
                $rows = -1;
                if ( $res ) {
                        $row = $this->fetchRow( $res );
@@ -798,7 +799,13 @@ __INDEXATTR__;
        }
 
        public function wasDeadlock() {
-               return $this->lastErrno() == '40P01';
+               // https://www.postgresql.org/docs/8.2/static/errcodes-appendix.html
+               return $this->lastErrno() === '40P01';
+       }
+
+       public function wasLockTimeout() {
+               // https://www.postgresql.org/docs/8.2/static/errcodes-appendix.html
+               return $this->lastErrno() === '55P03';
        }
 
        public function duplicateTableStructure(
index 83c8814..d5a7489 100644 (file)
@@ -69,24 +69,13 @@ class DatabaseSqlite extends Database {
         */
        function __construct( array $p ) {
                if ( isset( $p['dbFilePath'] ) ) {
-                       parent::__construct( $p );
-                       // Standalone .sqlite file mode.
-                       // Super doesn't open when $user is false, but we can work with $dbName,
-                       // which is derived from the file path in this case.
-                       $this->openFile( $p['dbFilePath'] );
-                       $lockDomain = md5( $p['dbFilePath'] );
-               } elseif ( !isset( $p['dbDirectory'] ) ) {
-                       throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." );
-               } else {
+                       $this->dbPath = $p['dbFilePath'];
+                       $lockDomain = md5( $this->dbPath );
+               } elseif ( isset( $p['dbDirectory'] ) ) {
                        $this->dbDir = $p['dbDirectory'];
-                       $this->dbName = $p['dbname'];
-                       $lockDomain = $this->dbName;
-                       // Stock wiki mode using standard file names per DB.
-                       parent::__construct( $p );
-                       // Super doesn't open when $user is false, but we can work with $dbName
-                       if ( $p['dbname'] && !$this->isOpen() ) {
-                               $this->open( $p['host'], $p['user'], $p['password'], $p['dbname'] );
-                       }
+                       $lockDomain = $p['dbname'];
+               } else {
+                       throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." );
                }
 
                $this->trxMode = isset( $p['trxMode'] ) ? strtoupper( $p['trxMode'] ) : null;
@@ -101,6 +90,8 @@ class DatabaseSqlite extends Database {
                        'domain' => $lockDomain,
                        'lockDirectory' => "{$this->dbDir}/locks"
                ] );
+
+               parent::__construct( $p );
        }
 
        protected static function getAttributes() {
@@ -126,6 +117,28 @@ class DatabaseSqlite extends Database {
                return $db;
        }
 
+       protected function doInitConnection() {
+               if ( $this->dbPath !== null ) {
+                       // Standalone .sqlite file mode.
+                       $this->openFile( $this->dbPath );
+               } elseif ( $this->dbDir !== null ) {
+                       // Stock wiki mode using standard file names per DB
+                       if ( strlen( $this->connectionParams['dbname'] ) ) {
+                               $this->open(
+                                       $this->connectionParams['host'],
+                                       $this->connectionParams['user'],
+                                       $this->connectionParams['password'],
+                                       $this->connectionParams['dbname']
+                               );
+                       } else {
+                               // Caller will manually call open() later?
+                               $this->connLogger->debug( __METHOD__ . ': no database opened.' );
+                       }
+               } else {
+                       throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." );
+               }
+       }
+
        /**
         * @return string
         */
@@ -146,7 +159,7 @@ class DatabaseSqlite extends Database {
         *  NOTE: only $dbName is used, the other parameters are irrelevant for SQLite databases
         *
         * @param string $server
-        * @param string $user
+        * @param string $user Unused
         * @param string $pass
         * @param string $dbName
         *
@@ -162,6 +175,10 @@ class DatabaseSqlite extends Database {
                }
                $this->openFile( $fileName );
 
+               if ( $this->conn ) {
+                       $this->dbName = $dbName;
+               }
+
                return (bool)$this->conn;
        }
 
@@ -192,7 +209,7 @@ class DatabaseSqlite extends Database {
                        throw new DBConnectionError( $this, $err );
                }
 
-               $this->opened = !!$this->conn;
+               $this->opened = is_object( $this->conn );
                if ( $this->opened ) {
                        # Set error codes only, don't raise exceptions
                        $this->conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
@@ -315,7 +332,7 @@ class DatabaseSqlite extends Database {
         * @return bool|ResultWrapper
         */
        protected function doQuery( $sql ) {
-               $res = $this->conn->query( $sql );
+               $res = $this->getBindingHandle()->query( $sql );
                if ( $res === false ) {
                        return false;
                }
@@ -451,7 +468,7 @@ class DatabaseSqlite extends Database {
         */
        function insertId() {
                // PDO::lastInsertId yields a string :(
-               return intval( $this->conn->lastInsertId() );
+               return intval( $this->getBindingHandle()->lastInsertId() );
        }
 
        /**
@@ -699,13 +716,6 @@ class DatabaseSqlite extends Database {
                return $this->lastErrno() == 5; // SQLITE_BUSY
        }
 
-       /**
-        * @return bool
-        */
-       function wasErrorReissuable() {
-               return $this->lastErrno() == 17; // SQLITE_SCHEMA;
-       }
-
        /**
         * @return bool
         */
@@ -713,6 +723,10 @@ class DatabaseSqlite extends Database {
                return $this->lastErrno() == 8; // SQLITE_READONLY;
        }
 
+       public function wasConnectionError( $errno ) {
+               return $errno == 17; // SQLITE_SCHEMA;
+       }
+
        /**
         * @return string Wikitext of a link to the server software's web site
         */
@@ -724,7 +738,7 @@ class DatabaseSqlite extends Database {
         * @return string Version information from the database
         */
        function getServerVersion() {
-               $ver = $this->conn->getAttribute( PDO::ATTR_SERVER_VERSION );
+               $ver = $this->getBindingHandle()->getAttribute( PDO::ATTR_SERVER_VERSION );
 
                return $ver;
        }
@@ -814,7 +828,7 @@ class DatabaseSqlite extends Database {
                        );
                        return "x'" . bin2hex( (string)$s ) . "'";
                } else {
-                       return $this->conn->quote( (string)$s );
+                       return $this->getBindingHandle()->quote( (string)$s );
                }
        }
 
@@ -1059,15 +1073,20 @@ class DatabaseSqlite extends Database {
                }
        }
 
-       protected function requiresDatabaseUser() {
-               return false; // just a file
-       }
-
        /**
         * @return string
         */
        public function __toString() {
-               return 'SQLite ' . (string)$this->conn->getAttribute( PDO::ATTR_SERVER_VERSION );
+               return is_object( $this->conn )
+                       ? 'SQLite ' . (string)$this->conn->getAttribute( PDO::ATTR_SERVER_VERSION )
+                       : '(not connected)';
+       }
+
+       /**
+        * @return PDO
+        */
+       protected function getBindingHandle() {
+               return parent::getBindingHandle();
        }
 }
 
index 28a8125..e5e2076 100644 (file)
@@ -357,7 +357,7 @@ interface IDatabase {
        public function getType();
 
        /**
-        * Open a connection to the database. Usually aborts on failure
+        * Open a new connection to the database (closing any existing one)
         *
         * @param string $server Database server host
         * @param string $user Database user name
@@ -492,8 +492,11 @@ interface IDatabase {
        public function getServerVersion();
 
        /**
-        * Closes a database connection.
-        * if it is open : commits any open transactions
+        * Close the database connection
+        *
+        * This should only be called after any transactions have been resolved,
+        * aside from read-only transactions (assuming no callbacks are registered).
+        * If a transaction is still open anyway, it will be committed if possible.
         *
         * @throws DBError
         * @return bool Operation success. true if already closed.
@@ -510,6 +513,10 @@ interface IDatabase {
         * Run an SQL query and return the result. Normally throws a DBQueryError
         * on failure. If errors are ignored, returns false instead.
         *
+        * If a connection loss is detected, then an attempt to reconnect will be made.
+        * For queries that involve no larger transactions or locks, they will be re-issued
+        * for convenience, provided the connection was re-established.
+        *
         * In new code, the query wrappers select(), insert(), update(), delete(),
         * etc. should be used where possible, since they give much better DBMS
         * independence and automatically quote or validate user input in a variety
@@ -822,11 +829,12 @@ interface IDatabase {
         * @param array|string $conds Filters on the table
         * @param string $fname Function name for profiling
         * @param array $options Options for select
+        * @param array|string $join_conds Join conditions
         * @return int Row count
         * @throws DBError
         */
        public function estimateRowCount(
-               $table, $vars = '*', $conds = '', $fname = __METHOD__, $options = []
+               $table, $vars = '*', $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
        );
 
        /**
@@ -1396,6 +1404,8 @@ interface IDatabase {
        /**
         * Determines if the last failure was due to a deadlock
         *
+        * Note that during a deadlock, the prior transaction will have been lost
+        *
         * @return bool
         */
        public function wasDeadlock();
@@ -1403,17 +1413,21 @@ interface IDatabase {
        /**
         * Determines if the last failure was due to a lock timeout
         *
+        * Note that during a lock wait timeout, the prior transaction will have been lost
+        *
         * @return bool
         */
        public function wasLockTimeout();
 
        /**
-        * Determines if the last query error was due to a dropped connection and should
-        * be dealt with by pinging the connection and reissuing the query.
+        * Determines if the last query error was due to a dropped connection
+        *
+        * Note that during a connection loss, the prior transaction will have been lost
         *
         * @return bool
+        * @since 1.31
         */
-       public function wasErrorReissuable();
+       public function wasConnectionLoss();
 
        /**
         * Determines if the last failure was due to the database being read-only.
@@ -1422,6 +1436,15 @@ interface IDatabase {
         */
        public function wasReadOnlyError();
 
+       /**
+        * Determines if the last query error was due to something outside of the query itself
+        *
+        * Note that the transaction may have been lost, discarding prior writes and results
+        *
+        * @return bool
+        */
+       public function wasErrorReissuable();
+
        /**
         * Wait for the replica DB to catch up to a given master position
         *
@@ -1927,6 +1950,21 @@ interface IDatabase {
         * @since 1.28
         */
        public function setTableAliases( array $aliases );
+
+       /**
+        * Convert certain index names to alternative names before querying the DB
+        *
+        * Note that this applies to indexes regardless of the table they belong to.
+        *
+        * This can be employed when an index was renamed X => Y in code, but the new Y-named
+        * indexes were not yet built on all DBs. After all the Y-named ones are added by the DBA,
+        * the aliases can be removed, and then the old X-named indexes dropped.
+        *
+        * @param string[] $aliases
+        * @return mixed
+        * @since 1.31
+        */
+       public function setIndexAliases( array $aliases );
 }
 
 class_alias( IDatabase::class, 'IDatabase' );
index 98108a7..32d9008 100644 (file)
@@ -42,19 +42,19 @@ interface ILBFactory {
         *
         * @param array $conf Array with keys:
         *  - localDomain: A DatabaseDomain or domain ID string.
-        *  - readOnlyReason : Reason the master DB is read-only if so [optional]
-        *  - srvCache : BagOStuff object for server cache [optional]
-        *  - memStash : BagOStuff object for cross-datacenter memory storage [optional]
-        *  - wanCache : WANObjectCache object [optional]
-        *  - hostname : The name of the current server [optional]
+        *  - readOnlyReason: Reason the master DB is read-only if so [optional]
+        *  - srvCache: BagOStuff object for server cache [optional]
+        *  - memStash: BagOStuff object for cross-datacenter memory storage [optional]
+        *  - wanCache: WANObjectCache object [optional]
+        *  - hostname: The name of the current server [optional]
         *  - cliMode: Whether the execution context is a CLI script. [optional]
-        *  - profiler : Class name or instance with profileIn()/profileOut() methods. [optional]
+        *  - profiler: Class name or instance with profileIn()/profileOut() methods. [optional]
         *  - trxProfiler: TransactionProfiler instance. [optional]
         *  - replLogger: PSR-3 logger instance. [optional]
         *  - connLogger: PSR-3 logger instance. [optional]
         *  - queryLogger: PSR-3 logger instance. [optional]
         *  - perfLogger: PSR-3 logger instance. [optional]
-        *  - errorLogger : Callback that takes an Exception and logs it. [optional]
+        *  - errorLogger: Callback that takes an Exception and logs it. [optional]
         * @throws InvalidArgumentException
         */
        public function __construct( array $conf );
@@ -323,4 +323,34 @@ interface ILBFactory {
         *   - ChronologyPositionIndex: timestamp used to get up-to-date DB positions for the agent
         */
        public function setRequestInfo( array $info );
+
+       /**
+        * Make certain table names use their own database, schema, and table prefix
+        * when passed into SQL queries pre-escaped and without a qualified database name
+        *
+        * For example, "user" can be converted to "myschema.mydbname.user" for convenience.
+        * Appearances like `user`, somedb.user, somedb.someschema.user will used literally.
+        *
+        * Calling this twice will completely clear any old table aliases. Also, note that
+        * callers are responsible for making sure the schemas and databases actually exist.
+        *
+        * @param array[] $aliases Map of (table => (dbname, schema, prefix) map)
+        * @since 1.31
+        */
+       public function setTableAliases( array $aliases );
+
+       /**
+        * Convert certain index names to alternative names before querying the DB
+        *
+        * Note that this applies to indexes regardless of the table they belong to.
+        *
+        * This can be employed when an index was renamed X => Y in code, but the new Y-named
+        * indexes were not yet built on all DBs. After all the Y-named ones are added by the DBA,
+        * the aliases can be removed, and then the old X-named indexes dropped.
+        *
+        * @param string[] $aliases
+        * @return mixed
+        * @since 1.31
+        */
+       public function setIndexAliases( array $aliases );
 }
index 2324553..32886e2 100644 (file)
@@ -75,6 +75,11 @@ abstract class LBFactory implements ILBFactory {
        /** @var callable[] */
        protected $replicationWaitCallbacks = [];
 
+       /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
+       protected $tableAliases = [];
+       /** @var string[] Map of (index alias => index) */
+       protected $indexAliases = [];
+
        /** @var bool Whether this PHP instance is for a CLI script */
        protected $cliMode;
        /** @var string Agent name for query profiling */
@@ -523,6 +528,17 @@ abstract class LBFactory implements ILBFactory {
                if ( $this->trxRoundId !== false ) {
                        $lb->beginMasterChanges( $this->trxRoundId ); // set DBO_TRX
                }
+
+               $lb->setTableAliases( $this->tableAliases );
+               $lb->setIndexAliases( $this->indexAliases );
+       }
+
+       public function setTableAliases( array $aliases ) {
+               $this->tableAliases = $aliases;
+       }
+
+       public function setIndexAliases( array $aliases ) {
+               $this->indexAliases = $aliases;
        }
 
        public function setDomainPrefix( $prefix ) {
index 8210507..767cc49 100644 (file)
@@ -615,4 +615,19 @@ interface ILoadBalancer {
         * @param array[] $aliases Map of (table => (dbname, schema, prefix) map)
         */
        public function setTableAliases( array $aliases );
+
+       /**
+        * Convert certain index names to alternative names before querying the DB
+        *
+        * Note that this applies to indexes regardless of the table they belong to.
+        *
+        * This can be employed when an index was renamed X => Y in code, but the new Y-named
+        * indexes were not yet built on all DBs. After all the Y-named ones are added by the DBA,
+        * the aliases can be removed, and then the old X-named indexes dropped.
+        *
+        * @param string[] $aliases
+        * @return mixed
+        * @since 1.31
+        */
+       public function setIndexAliases( array $aliases );
 }
index 99a24c2..35198ac 100644 (file)
@@ -54,6 +54,8 @@ class LoadBalancer implements ILoadBalancer {
        private $loadMonitorConfig;
        /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
        private $tableAliases = [];
+       /** @var string[] Map of (index alias => index) */
+       private $indexAliases = [];
 
        /** @var ILoadMonitor */
        private $loadMonitor;
@@ -1088,6 +1090,7 @@ class LoadBalancer implements ILoadBalancer {
                        $this->getLazyConnectionRef( self::DB_MASTER, [], $db->getDomainID() )
                );
                $db->setTableAliases( $this->tableAliases );
+               $db->setIndexAliases( $this->indexAliases );
 
                if ( $server['serverIndex'] === $this->getWriterIndex() ) {
                        if ( $this->trxRoundId !== false ) {
@@ -1757,6 +1760,10 @@ class LoadBalancer implements ILoadBalancer {
                $this->tableAliases = $aliases;
        }
 
+       public function setIndexAliases( array $aliases ) {
+               $this->indexAliases = $aliases;
+       }
+
        public function setDomainPrefix( $prefix ) {
                // Find connections to explicit foreign domains still marked as in-use...
                $domainsInUse = [];
index 679d51c..e00bee3 100644 (file)
@@ -22,7 +22,7 @@
 
 /**
  * Example virtual rest service for OpenStack Swift
- * @TODO: caching support (APC/memcached)
+ * @todo caching support (APC/memcached)
  * @since 1.23
  */
 class SwiftVirtualRESTService extends VirtualRESTService {
index 1955915..6a4d7c4 100644 (file)
@@ -838,7 +838,7 @@ class XMPReader implements LoggerAwareInterface {
                        return;
                }
 
-               if ( count( $this->mode[0] ) === 0 ) {
+               if ( count( $this->mode ) === 0 ) {
                        // This should never ever happen and means
                        // there is a pretty major bug in this class.
                        throw new RuntimeException( 'Encountered end element with no mode' );
index 7aec28e..9fe3e33 100644 (file)
@@ -206,7 +206,7 @@ class XMPValidate implements LoggerAwareInterface {
                        $this->logger->info( __METHOD__ . " Flash structure did not have all the required components" );
                        $val = null;
                } else {
-                       $val = ( "\0" | ( $val['Fired'] === 'True' )
+                       $val = ( 0 | ( $val['Fired'] === 'True' )
                                | ( intval( $val['Return'] ) << 1 )
                                | ( intval( $val['Mode'] ) << 3 )
                                | ( ( $val['Function'] === 'True' ) << 5 )
index ca7d747..32953df 100644 (file)
@@ -3254,7 +3254,8 @@ class WikiPage implements Page, IDBAccessObject {
                        $target->getId(),
                        $guser,
                        null,
-                       $tags
+                       $tags,
+                       $current->getId()
                );
 
                // Set patrolling and bot flag on the edits, which gets rollbacked.
index d329f69..855ce1d 100644 (file)
@@ -199,7 +199,7 @@ class StripState {
        /**
         * Get an array of parameters to pass to ParserOutput::setLimitReportData()
         *
-        * @unstable Should only be called by Parser
+        * @internal Should only be called by Parser
         * @return array
         */
        public function getLimitReport() {
index d48f744..124e2d3 100644 (file)
@@ -35,7 +35,7 @@ class ProfileSection {
         * the same moment that the function to be profiled terminates.
         *
         * This is typically called like:
-        * @code$section = new ProfileSection( __METHOD__ );@endcode
+        * @code $section = new ProfileSection( __METHOD__ ); @endcode
         *
         * @param string $name Name of the function to profile
         */
index f9b03c7..5ddb99b 100644 (file)
@@ -1532,27 +1532,31 @@ MESSAGE;
        /**
         * Convert an array of module names to a packed query string.
         *
-        * For example, [ 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' ]
-        * becomes 'foo.bar,baz|bar.baz,quux'
+        * For example, `[ 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' ]`
+        * becomes `'foo.bar,baz|bar.baz,quux'`.
+        *
+        * This process is reversed by ResourceLoaderContext::expandModuleNames().
+        * See also mw.loader#buildModulesString() which is a port of this, used
+        * on the client-side.
+        *
         * @param array $modules List of module names (strings)
         * @return string Packed query string
         */
        public static function makePackedModulesString( $modules ) {
-               $groups = []; // [ prefix => [ suffixes ] ]
+               $moduleMap = []; // [ prefix => [ suffixes ] ]
                foreach ( $modules as $module ) {
                        $pos = strrpos( $module, '.' );
                        $prefix = $pos === false ? '' : substr( $module, 0, $pos );
                        $suffix = $pos === false ? $module : substr( $module, $pos + 1 );
-                       $groups[$prefix][] = $suffix;
+                       $moduleMap[$prefix][] = $suffix;
                }
 
                $arr = [];
-               foreach ( $groups as $prefix => $suffixes ) {
+               foreach ( $moduleMap as $prefix => $suffixes ) {
                        $p = $prefix === '' ? '' : $prefix . '.';
                        $arr[] = $p . implode( ',', $suffixes );
                }
-               $str = implode( '|', $arr );
-               return $str;
+               return implode( '|', $arr );
        }
 
        /**
index 7478266..370046a 100644 (file)
@@ -98,9 +98,12 @@ class ResourceLoaderContext implements MessageLocalizer {
        }
 
        /**
-        * Expand a string of the form jquery.foo,bar|jquery.ui.baz,quux to
-        * an array of module names like [ 'jquery.foo', 'jquery.bar',
-        * 'jquery.ui.baz', 'jquery.ui.quux' ]
+        * Expand a string of the form `jquery.foo,bar|jquery.ui.baz,quux` to
+        * an array of module names like `[ 'jquery.foo', 'jquery.bar',
+        * 'jquery.ui.baz', 'jquery.ui.quux' ]`.
+        *
+        * This process is reversed by ResourceLoader::makePackedModulesString().
+        *
         * @param string $modules Packed module name list
         * @return array Array of module names
         */
index 3be687b..8bf7170 100644 (file)
@@ -620,7 +620,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
         *             'https://example.org/image.png' => [ 'as' => 'image' ],
         *         ];
         *     }
-        * @encode
+        * @endcode
         *
         * @par Example using HiDPI image variants
         * @code
@@ -636,7 +636,7 @@ abstract class ResourceLoaderModule implements LoggerAwareInterface {
         *             ],
         *         ];
         *     }
-        * @encode
+        * @endcode
         *
         * @see ResourceLoaderModule::getHeaders
         * @since 1.30
index e764e8b..57cdad9 100644 (file)
@@ -118,7 +118,7 @@ class NewFilesPager extends RangeChronologicalPager {
                        } else {
                                $rcQuery = ActorMigration::newMigration()->getJoin( 'rc_user' );
                                $tables += $rcQuery['tables'];
-                               $joins += $rcQuery['joins'];
+                               $jconds += $rcQuery['joins'];
                                $jcond = $rcQuery['fields']['rc_user'] . ' = ' . $imgQuery['fields']['img_user'];
                        }
                        $jconds['recentchanges'] = [
index ab791b4..d6523a7 100644 (file)
@@ -885,7 +885,7 @@ class User implements IDBAccessObject, UserIdentity {
                        return null;
                }
 
-               if ( !( $flags & self::READ_LATEST ) && isset( self::$idCacheByName[$name] ) ) {
+               if ( !( $flags & self::READ_LATEST ) && array_key_exists( $name, self::$idCacheByName ) ) {
                        return self::$idCacheByName[$name];
                }
 
index deb58b7..8089118 100644 (file)
@@ -14,6 +14,7 @@
                [ "(.+)ды$", "$1дов" ],
                [ "(.+)д$", "$1да" ],
                [ "(.+)ник$", "$1ника" ],
+               [ "(.+)тет$", "$1тета" ],
                [ "(.+)ные$", "$1ных" ]
        ],
        "prepositional": [
@@ -24,6 +25,7 @@
                [ "(.+)ды$", "$1дах" ],
                [ "(.+)д$", "$1де" ],
                [ "(.+)ник$", "$1нике" ],
+               [ "(.+)тет$", "$1тете" ],
                [ "(.+)ные$", "$1ных" ]
        ],
        "languagegen": [
index 2c93bc8..b4ecdd5 100644 (file)
        "expansion-depth-exceeded-warning": "La páxina pasó la fondura d'espansión",
        "parser-unstrip-loop-warning": "Deteutóse un bucle \"unstrip\"",
        "unstrip-depth-warning": "Pasóse la llende de recursividá d'unstrip ($1)",
+       "unstrip-depth-category": "Páxines onde se pasó la llende de fondura de «unstrip»",
+       "unstrip-size-warning": "Pasóse la llende de tamañu de «unstrip» ($1)",
+       "unstrip-size-category": "Páxines onde se pasó la llende de tamañu de «unstrip»",
        "converter-manual-rule-error": "Detectóse un error na regla de conversión manual de llingua",
        "undo-success": "La edición se pue esfacer.\nPor favor comprueba la comparanza d'abaxo pa confirmar que ye eso lo que quies facer, y depués guarda los cambios p'acabar d'esfacer la edición.",
        "undo-failure": "Nun pudo esfacese la edición por aciu d'ediciones intermedies conflictives.",
        "stub-threshold-disabled": "Desactivao",
        "recentchangesdays": "Díes que s'amuesen nos cambios recientes:",
        "recentchangesdays-max": "Máximo $1 {{PLURAL:$1|día|díes}}",
-       "recentchangescount": "Númberu d'ediciones p'amosar de mou predetermináu:",
-       "prefs-help-recentchangescount": "Incluye los cambios recientes, los historiales de páxines y los rexistros.",
+       "recentchangescount": "Númberu d'ediciones qu'amosar nos cambios recién, nos historiales de páxina y nos rexistros de mou predetermináu:",
+       "prefs-help-recentchangescount": "Númberu máximu: 1000",
        "prefs-help-watchlist-token2": "Esta ye la clave secreta pa la canal de noticies web de la to llista de vixilancia.\nCualquiera que la sepa podrá lleer la to llista de vixilancia; nun la compartas.\nSi lo necesites [[Special:ResetTokens|puedes reaniciala]].",
        "savedprefs": "Guardáronse les preferencies.",
        "savedrights": "Guardáronse los grupos {{GENDER:$1|del usuariu|de la usuaria}} $1.",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Máxima fondura d'espansión",
        "limitreport-expensivefunctioncount": "Cuenta de funciones d'analís costoses",
+       "limitreport-unstrip-depth": "Fondura de recursividá de «unstrip»",
+       "limitreport-unstrip-size": "Tamañu después d'espander «unstrip»",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Esparder plantíes",
        "expand_templates_intro": "Esta páxina especial toma testu y espande toles plantíes del mesmu de forma recursiva.\n Tamién espande les funciones d'análisis sintáuticu como\n<code><nowiki>{{</nowiki>#language:...}}</code>, y variables como\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nEn realidá, espande cuasi tolo qu'apaeza ente llaves dobles.",
        "expand_templates_title": "Títulu del contestu, pa {{FULLPAGENAME}}, etc.:",
index ee3523f..0684809 100644 (file)
        "rcfilters-activefilters": "چالیشقان فیلترلر",
        "rcfilters-days-title": "سوْن گۆنلر",
        "rcfilters-hours-title": "سوْن ساعاتلار",
+       "rcfilters-quickfilters-placeholder-title": "هله‌لیک هئچ بیر فیلتر ذخیره اوْلونماییبدیر",
        "rcfilters-savedqueries-defaultlabel": "ذخیره اوْلونموش فیلترلر",
+       "rcfilters-search-placeholder": "سوْن دییشیکلیکلری فیلترله (منودان سئچین یوْخسا فیلتر آدینی آختارین)",
        "rcfilters-filterlist-title": "فیلترلر",
        "rcfilters-filtergroup-authorship": "دییشدیرن",
        "rcfilters-filtergroup-automated": "اوْتوماتیک دییشدیرمه‌لر",
        "rcfilters-filtergroup-changetype": "دَییشیکلیک نوعو",
        "rcfilters-filter-pageedits-label": "صفحه دییشدیرمه‌لری",
        "rcfilters-filter-newpages-label": "صفحه یاراتما",
+       "rcfilters-filter-categorization-label": "بؤلمه دَییشیکلیکلری",
        "rcfilters-filtergroup-lastRevision": "سوْن نوسخه‌لر",
+       "rcfilters-filter-lastrevision-label": "سوْن نوسخه",
        "rcnotefrom": "آشاغی داکی دَییشیک لرده <strong>$3, $4</strong> (دن <strong>$1</strong> {{PLURAL:$5|چان گوستریلیب|چان گوستریلیب دیر}}).",
        "rclistfrom": "$3 $2 واختیندان باشلایاراق یئنی دییشیکلری گؤستر",
        "rcshowhideminor": "کیچیک دَییشیکلری $1",
index d12c898..ef0d078 100644 (file)
        "right-viewmyprivateinfo": "Праглядаць уласныя прыватныя зьвесткі (напрыклад, адрас электроннай пошты, сапраўднае імя)",
        "right-editmyprivateinfo": "Рэдагаваць уласныя прыватныя зьвесткі (напрыклад, адрас электроннай пошты, сапраўднае імя)",
        "right-editmyoptions": "Рэдагаваць уласныя налады",
-       "right-rollback": "хуткі адкат правак апошняга ўдзельніка, які рэдагаваў старонку",
-       "right-markbotedits": "пазнаÑ\87Ñ\8dнÑ\8cне Ð°Ð´ÐºÐ°Ñ\82аÑ\9e Ñ\8fк Ñ\80Ñ\8dдагаванÑ\8cне робатам",
-       "right-noratelimit": "нÑ\8fма Ð°Ð±Ð¼ÐµÐ¶Ð°Ð²Ð°Ð½Ñ\8cнÑ\8fÑ\9e Ð¿Ð° хуткасьці",
-       "right-import": "імпарт старонак зь іншых вікі",
-       "right-importupload": "імпарт старонак праз загрузку файлаў",
-       "right-patrol": "пазнаÑ\87Ñ\8dнÑ\8cне Ñ\80Ñ\8dдагаванÑ\8cнÑ\8fÑ\9e Ñ\8fк Â«Ð¿Ð°Ñ\82Ñ\80Ñ\83лÑ\8fванÑ\8bÑ\8f»",
+       "right-rollback": "Хуткі адкат правак апошняга ўдзельніка, які рэдагаваў старонку",
+       "right-markbotedits": "Ð\9fазнаÑ\87Ñ\8dнÑ\8cне Ð°Ð´ÐºÐ°Ñ\82аÑ\9e Ñ\8fк Ñ\80Ñ\8dдагаванÑ\8cнÑ\8fÑ\9e робатам",
+       "right-noratelimit": "Ð\9dÑ\8fма Ð°Ð±Ð¼ÐµÐ¶Ð°Ð²Ð°Ð½Ñ\8cнÑ\8fÑ\9e хуткасьці",
+       "right-import": "Імпарт старонак зь іншых вікі",
+       "right-importupload": "Імпарт старонак праз загрузку файлаў",
+       "right-patrol": "Ð\9fазнаÑ\87Ñ\8dнÑ\8cне Ñ\80Ñ\8dдагаванÑ\8cнÑ\8fÑ\9e Ñ\8fк Â«Ð¿Ð°Ñ\82Ñ\80Ñ\83лÑ\8fванÑ\8bÑ\85»",
        "right-autopatrol": "аўтаматычнае пазначэньне рэдагаваньняў як «патруляваных»",
        "right-patrolmarks": "прагляд пазначэньняў пра патруляваньне ў апошніх зьменах",
        "right-unwatchedpages": "прагляд сьпісу старонак, за якімі ніхто не назірае",
index fad50b2..378d9be 100644 (file)
        "rcfilters-liveupdates-button-title-off": "Prikaži nove izmjene uživo",
        "rcfilters-watchlist-markseen-button": "Označi sve izmjene viđenim",
        "rcfilters-watchlist-edit-watchlist-button": "Izmijeni spisak praćenih stranica",
-       "rcfilters-watchlist-showupdated": "Izmjene na stranicama koje niste posjetili otkako su izvršene prikazane su <strong>podebljano</strong>, s ispunjenim kružićima.",
+       "rcfilters-watchlist-showupdated": "Izmjene na stranicama koje niste posjetili otkako su izvršene istaknute su <strong>podebljanim slovima</strong>, s ispunjenim kružićima.",
        "rcfilters-preference-label": "Sakrij poboljšanu verziju nedavnih izmjena",
        "rcfilters-preference-help": "Poništava novi izgled interfejsa iz 2017. i sve alate dodane od tada.",
        "rcnotefrom": "Ispod {{PLURAL:$5|je izmjena|su izmjene}} od <strong>$3, $4</strong> (do <strong>$1</strong> prikazano).",
        "recentchangeslinked-feed": "Srodne izmjene",
        "recentchangeslinked-toolbox": "Srodne izmjene",
        "recentchangeslinked-title": "Srodne promjene sa \"$1\"",
-       "recentchangeslinked-summary": "Ova posebna stranica prikazuje promjene na povezanim stranicama.\nStranice koje su na vašem [[Special:Watchlist|spisku praćenja]] su '''podebljane'''.",
+       "recentchangeslinked-summary": "Upišite naziv stranice da biste vidjeli promjene koje vode na ili sa te stranice. (Da biste vidjeli članove neke kategorije, upišite Kategorija:Naziv kategorije). Promjene na stranicama na [[Special:Watchlist|spisku praćenja]] istaknute su <strong>podebljanim slovima</strong>.",
        "recentchangeslinked-page": "Naslov stranice:",
        "recentchangeslinked-to": "Prikaži izmjene stranica koji su povezane s datom stranicom",
        "recentchanges-page-added-to-category": "Stranica [[:$1]] dodana je u kategoriju",
        "notvisiblerev": "Obrisana je posljednja izmjena drugog korisnika",
        "watchlist-details": "Imate {{PLURAL:$1|$1 stranicu|$1 stranice|$1 stranica}} na spisku praćenja (plus stranice za razgovor).",
        "wlheader-enotif": "Uključeno je obavještenje e-poštom.",
-       "wlheader-showupdated": "Stranice koje su izmijenjene otkad ste ih posljednji put posjetili prikazane su <strong>podebljanim slovima</strong>.",
+       "wlheader-showupdated": "Stranice koje su izmijenjene otkad ste ih posljednji put posjetili istaknute su <strong>podebljanim slovima</strong>.",
        "wlnote": "Ispod {{PLURAL:$1|je posljednja izmjena|su <strong>$1</strong> posljednje izmjene|su <strong>$1</strong> posljednjih izmjena}} načinjenih {{PLURAL:$2|posljednjeg sata|u posljednjih <strong>$2</strong> sata|u posljednjih <strong>$2</strong> sati}}, od $3, $4.",
        "wlshowlast": "Prikaži posljednjih $1 sati $2 dana",
        "watchlist-hide": "Sakrij",
index 6b54759..27e1729 100644 (file)
        "category_header": "پەڕەکانی پۆلی «$1»",
        "subcategories": "ژێرپۆلەکان",
        "category-media-header": "میدیای پۆلی «$1»",
-       "category-empty": "''ئەم پۆلە ھەنووکە ھیچ پەڕە یان پەڕگەیەک لە خۆ ناگرێت.‌''",
+       "category-empty": "<em>ئەم پۆلە ھەنووکە ھیچ پەڕە یان پەڕگەیەک لە خۆ ناگرێت.‌</em>",
        "hidden-categories": "{{PLURAL:$1|پۆلی شارداوە|پۆلە شارداوەکان}}",
        "hidden-category-category": "پۆلە شاردراوەکان",
        "category-subcat-count": "{{PLURAL:$2|ئەم پۆلە تەنیا ژێرپۆلی ژێرەوەی تێدایە.|ئەم پۆلە {{PLURAL:$1|ژێرپۆل|$1 ژێرپۆل}}ی ژێرەوەی تێدایە، لە سەرجەم $2 ژێرپۆل.}}",
        "nstab-user": "پەڕەی بەکارھێنەر",
        "nstab-media": "میدیا",
        "nstab-special": "پەڕەی تایبەت",
-       "nstab-project": "پەڕەی پڕۆژە",
+       "nstab-project": "پەڕەی پرۆژە",
        "nstab-image": "پەڕگە",
        "nstab-mediawiki": "پەیام",
        "nstab-template": "داڕێژە",
        "tooltip-ca-nstab-user": "پەڕەی بەکارھێنەر تەماشا بکە",
        "tooltip-ca-nstab-media": "پەڕەی میدیا چاو لێ بکە",
        "tooltip-ca-nstab-special": "ئەمە پەڕەیەکی تایبەتە و دەستکاری ناکرێت",
-       "tooltip-ca-nstab-project": "بینینی پەڕەی پڕۆژە",
+       "tooltip-ca-nstab-project": "بینینی پەڕەی پرۆژە",
        "tooltip-ca-nstab-image": "بینینی پەڕەی پەڕگە",
        "tooltip-ca-nstab-mediawiki": "بینینی پەیامی سیستەم",
        "tooltip-ca-nstab-template": "بینینی قاڵبەکە",
index 68769ef..b8902d8 100644 (file)
@@ -66,7 +66,8 @@
                        "R12ntech",
                        "Joedalton",
                        "EeveeSylveon",
-                       "Kenn.jensen"
+                       "Kenn.jensen",
+                       "Saederup92"
                ]
        },
        "tog-underline": "Understreg henvisninger:",
        "postedit-confirmation-created": "Siden er blevet oprettet.",
        "postedit-confirmation-restored": "Siden er blevet genoprettet.",
        "postedit-confirmation-saved": "Din redigering er gemt.",
+       "postedit-confirmation-published": "Din ændring blev udgivet.",
        "edit-already-exists": "En ny side kunne ikke oprettes, fordi den allerede findes.",
        "defaultmessagetext": "Standardtekst",
        "content-failed-to-parse": "Kunne ikke fortolke $2-indholdet af $1-modellen: $3",
        "rcfilters-watchlist-edit-watchlist-button": "Rediger din liste med overvågede sider",
        "rcfilters-watchlist-showupdated": "Ændringer til sider du ikke har besøgt siden ændringerne blev gjort vises med <strong>fed</strong>, med faste markører.",
        "rcfilters-preference-label": "Skjul den forbedrede verson af Seneste ændringer",
-       "rcfilters-target-page-placeholder": "Indtast et sidenavn",
+       "rcfilters-target-page-placeholder": "Indtast et sidenavn (eller en kategori)",
        "rcnotefrom": "Nedenfor er op til '''$1''' {{PLURAL:$5|ændring|ændringer}} siden '''$2''' vist.",
        "rclistfromreset": "Nulstil datovalg",
        "rclistfrom": "Vis nye ændringer startende fra den $3 kl. $2",
        "uploadstash-errclear": "Rydning af filerne mislykkedes.",
        "uploadstash-refresh": "Opdatér filoversigten",
        "uploadstash-thumbnail": "vis miniature",
+       "uploadstash-bad-path": "Sti findes ikke.",
+       "uploadstash-bad-path-invalid": "Stien er ugyldig.",
        "uploadstash-bad-path-unknown-type": "Ukendt type »$1«.",
        "uploadstash-file-not-found-no-object": "Kunne ikke oprette lokalt filobjekt for miniaturebillede.",
        "uploadstash-not-logged-in": "Ingen bruger er logget ind, filer skal tilhøre brugere.",
        "tags-edit-chosen-placeholder": "Vælg nogle mærker",
        "tags-edit-chosen-no-results": "Ingen mærker fundet som matcher",
        "tags-edit-reason": "Årsag:",
+       "tags-edit-success": "Ændringerne blev udført.",
        "comparepages": "Sammenlign sider",
        "compare-page1": "Side 1",
        "compare-page2": "Side 2",
        "pagelang-use-default": "Brug standardsprog",
        "pagelang-select-lang": "Vælg sprog",
        "pagelang-reason": "Begrundelse",
+       "pagelang-submit": "Indsend",
        "right-pagelang": "Ændre sidesproget",
        "mediastatistics": "Mediestatistik",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%)",
        "mediastatistics-header-total": "Alle filer",
        "json-error-state-mismatch": "Ugyldig eller fejlbehæftet JSON",
        "json-error-syntax": "Syntaksfejl",
+       "headline-anchor-title": "Link til denne sektion",
        "special-characters-group-latin": "Latin",
        "special-characters-group-latinextended": "Udvidet latin",
        "special-characters-group-ipa": "IPA",
        "mw-widgets-dateinput-no-date": "Ingen dato valgt",
        "mw-widgets-dateinput-placeholder-day": "ÅÅÅÅ-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "ÅÅÅÅ-MM",
+       "mw-widgets-mediasearch-noresults": "Der blev ikke fundet noget resultat.",
        "mw-widgets-titleinput-description-new-page": "side eksisterer ikke endnu",
        "mw-widgets-titleinput-description-redirect": "omdiriger til $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Tilføj en kategori...",
        "log-action-filter-protect-move_prot": "Flyttede beskyttelse",
        "log-action-filter-upload-upload": "Ny overførsel",
        "authmanager-create-from-login": "For at oprette din konto, så udfyld venligst felterne.",
+       "authmanager-authplugin-setpass-bad-domain": "Ugyldig domæne.",
+       "authmanager-userdoesnotexist": "Brugerkontoen \"$1\" er ikke registreret.",
        "authmanager-email-label": "E-post",
        "authmanager-email-help": "E-postadresse",
+       "authmanager-realname-label": "Rigtige navn",
+       "authmanager-realname-help": "Brugerens egentlige navn",
        "authmanager-provider-temporarypassword": "Midlertidig adgangskode",
+       "authprovider-resetpass-skip-label": "Spring over",
        "specialpage-securitylevel-not-allowed-title": "Ikke tilladt",
        "cannotauth-not-allowed-title": "Adgang nægtet",
        "cannotauth-not-allowed": "Du har ikke tilladelse til at bruge denne side",
        "removecredentials-success": "Dine akkreditiver er blevet fjernet.",
        "credentialsform-provider": "Akkreditivtype:",
        "credentialsform-account": "Kontonavn:",
-       "edit-error-short": "Fejl: $1"
+       "edit-error-short": "Fejl: $1",
+       "edit-error-long": "Fejl:\n\n$1",
+       "pagedata-bad-title": "Ugyldig titel: $1"
 }
index aaaf785..aaddece 100644 (file)
        "wrongpasswordempty": "Password entered was blank.\nPlease try again.",
        "passwordtooshort": "Passwords must be at least {{PLURAL:$1|1 character|$1 characters}}.",
        "passwordtoolong": "Passwords cannot be longer than {{PLURAL:$1|1 character|$1 characters}}.",
-       "passwordtoopopular": "Commonly chosen passwords cannot be used. Please choose a more unique password.",
+       "passwordtoopopular": "Commonly chosen passwords cannot be used. Please choose a password that is more difficult to guess.",
        "password-name-match": "Your password must be different from your username.",
        "password-login-forbidden": "The use of this username and password has been forbidden.",
        "mailmypassword": "Reset password",
index d0257bf..fb13329 100644 (file)
        "apisandbox-deprecated-parameters": "Parámetros desaconsejados",
        "apisandbox-fetch-token": "Auto-llenar el token",
        "apisandbox-submit-invalid-fields-title": "Algunos campos no son válidos",
-       "apisandbox-submit-invalid-fields-message": "Por favor, corrige los campos señalados e inténtalo de nuevo.",
+       "apisandbox-submit-invalid-fields-message": "Corrige los campos señalados e inténtalo de nuevo.",
        "apisandbox-results": "Resultados",
        "apisandbox-sending-request": "Enviando pedido a la API...",
        "apisandbox-loading-results": "Recibiendo resultados de la API...",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Profundidad máxima de expansión",
        "limitreport-expensivefunctioncount": "Cuenta de la función expansiva del analizador",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Expandir plantillas",
        "expand_templates_intro": "Esta página especial toma un texto wiki y expande todas sus plantillas recursivamente.\nTambién expande las funciones sintácticas como <code><nowiki>{{</nowiki>#language:…}}</code>, y variables como\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>. De hecho, expande casi cualquier cosa que esté entre llaves dobles.",
        "expand_templates_title": "Título de la página, útil para expandir {{FULLPAGENAME}} o similares:",
index 2b1f1af..6c26d19 100644 (file)
        "recentchangeslinked-summary": "Sartu orrialde baten izena orrialdearekin lotutako edota orrialdetik lotutako orrialdeetan aldaketak ikusteko. (Kategoria baten kideak ikusteko, idatzi Kategoria: Kategoria izena). [[Special:Watchlist|Zure jarraipen zerrendan]] dauden orrietan aldaketak <strong>letra lodian</strong> daude.",
        "recentchangeslinked-page": "Orriaren izena:",
        "recentchangeslinked-to": "Lotutako orrietarako aldaketak erakutsi emandako orriaren ordez",
-       "recentchanges-page-added-to-category": "[[:$1]] Kategoriara gehitua",
+       "recentchanges-page-added-to-category": "«[[:$1]]» gehitu da kategoriara",
        "recentchanges-page-added-to-category-bundled": "[[:$1]] kategoriara gehitua, [[Special:WhatLinksHere/$1|horri hau beste orri batzuen artean sartuta dago]]",
        "recentchanges-page-removed-from-category": "[[:$1]] kategoriatik kendu da",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] kategoriatik kendua, [[Special:WhatLinksHere/$1|horri hau beste orri batzuen artean sartuta dago]]",
        "unblockiptext": "Erabili beheko formularioa lehenago blokeatutako IP helbide edo erabiltzaile baten idazketa baimenak leheneratzeko.",
        "ipusubmit": "Blokeoa ezabatu",
        "unblocked": "[[User:$1|$1]] desblokeatu egin da",
-       "unblocked-range": "$1 desblokeatuta izan da.",
+       "unblocked-range": "$1 desblokeatua izan da.",
        "unblocked-id": "$1 blokeaketa ezabatu da",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] desblokeatua izan da.",
        "blocklist": "Blokeatutako erabiltzaileak",
        "revdelete-restricted": "administratzaileentzako mugak ezarri dira",
        "revdelete-unrestricted": "administratzaileentzako mugak kendu dira",
        "logentry-block-block": "$1 {{GENDER:$2|administratzaileak}} {{GENDER:$4|$3}} blokeatu du. Iraupena: $5 $6",
-       "logentry-block-unblock": "$1 {{GENDER:$2|desblokeatuta}} {{GENDER:$4|$3}}",
+       "logentry-block-unblock": "$1 {{GENDER:$2|administratzaileak}} {{GENDER:$4|$3}} wikilaria desblokeatu du",
        "logentry-block-reblock": "$1 administratzaileak {{GENDER:$4|$3}} wikilariaren blokeoa {{GENDER:$2|aldatu du}}. Blokeoaldia: $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|administratzaileak}} {{GENDER:$4|$3}} blokeatu du. Iraupena: $5 $6",
        "logentry-suppress-reblock": "$1 administratzaileak {{GENDER:$4|$3}} wikilariaren blokeoa {{GENDER:$2|aldatu du}}. Blokeoaldia: $5 $6",
index 9086795..5120888 100644 (file)
        "expansion-depth-exceeded-warning": "صفحه حداکثر عمق بسط دادن تجاوز کرد",
        "parser-unstrip-loop-warning": "حلقه در دستور unstrip پیدا شد",
        "unstrip-depth-warning": "از حداکثر ارجاع در دستور unstrip تجاوز شد ($1)",
+       "unstrip-depth-category": "صفحاتی که از محدودیت عمق محتوی تخطی شده",
+       "unstrip-size-warning": "محدودیت عمق محتوی تخطی شده ($1)",
+       "unstrip-size-category": "صفحاتی که از محدودیت عمق محتوی تخطی شده",
        "converter-manual-rule-error": "خطا در قوانین مبدل دستی زبان",
        "undo-success": "این ویرایش را می‌توان خنثی کرد.\nلطفاً تفاوت زیر را بررسی کنید تا تأیید کنید که این چیزی است که می‌خواهید انجام دهید، سپس تغییرات زیر را ذخیره کنید تا خنثی‌سازی ویرایش را به پایان ببرید.",
        "undo-failure": "به علت تعارض با ویرایش‌های میانی، این ویرایش را نمی‌توان خنثی کرد.",
        "stub-threshold-disabled": "غیرفعال",
        "recentchangesdays": "تعداد روزهای نمایش داده‌شده در تغییرات اخیر:",
        "recentchangesdays-max": "حداکثر $1 {{PLURAL:$1|روز}}",
-       "recentchangescount": "تعداد Ù¾Û\8cØ´â\80\8cÙ\81رض Ù\88Û\8cراÛ\8cØ´â\80\8cÙ\87اÛ\8c Ù\86Ù\85اÛ\8cØ´ Û\8cاÙ\81تÙ\87:",
-       "prefs-help-recentchangescount": "اÛ\8cÙ\86 Ú¯Ø²Û\8cÙ\86Ù\87 Ø´Ø§Ù\85Ù\84 ØªØºÛ\8cÛ\8cرات Ø§Ø®Û\8cرØ\8c ØªØ§Ø±Û\8cØ®Ú\86Ù\87Ù\94 ØµÙ\81Ø­Ù\87â\80\8cÙ\87ا Ù\88 Ø³Û\8cاÙ\87Ù\87â\80\8cÙ\87ا Ù\85Û\8câ\80\8cØ´Ù\88د.",
+       "recentchangescount": "تعداد Ù\86Ù\85اÛ\8cØ´ Ù¾Û\8cØ´â\80\8cÙ\81رض Ù\88Û\8cراÛ\8cØ´â\80\8cÙ\87ا Ø¯Ø± ØªØºÛ\8cÛ\8cرات Ø§Ø®Û\8cرØ\8c ØªØ§Ø±Û\8cØ®Ú\86Ù\87 ØµÙ\81Ø­Ù\87 Ù\88 Ø³Û\8cاÙ\87Ù\87â\80\8cÙ\87ا:",
+       "prefs-help-recentchangescount": "حداکثر ØªØ¹Ø¯Ø§Ø¯: Û±Û°Û°Û°",
        "prefs-help-watchlist-token2": "این کلید رمز خوراک وب فهرست پی‌گیری‌های شماست.\nهرکس آن را بداند می‌تواند فهرست پی‌گیری‌هایتان را بخواند، بنابراین آن را به اشتراک نگذارید. اگر لازم باشد [[Special:ResetTokens|می‌توانید کلیدی نو ایجاد کنید]].",
        "savedprefs": "ترجیحات شما ذخیره شد.",
        "savedrights": "گروه‌های کاربری {{GENDER:$1|$1}} ذخیره شده‌است.",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|بایت|بایت}}",
        "limitreport-expansiondepth": "بیشترین عمق گسترش",
        "limitreport-expensivefunctioncount": "تعداد تابع تجزیه‌گر پرمصرف",
+       "limitreport-unstrip-depth": "بازگشت عمق محتوی",
+       "limitreport-unstrip-size": "اندازه پس‌گشایش محتوی",
+       "limitreport-unstrip-size-value": "\n$1/$2 {{PLURAL:$2|بایت|بایت}}",
        "expandtemplates": "بسط دادن الگوها",
        "expand_templates_intro": "این صفحهٔ ویژه، ویکی‌متنی را دریافت کرده و تمام الگوهای به‌کاررفته در آن را به طور بازگشتی بسط می‌دهد. همچنین تابع‌های تجزیه چون <code><nowiki>{{</nowiki>#language:…}}</code> و متغیرهایی چون  <code><nowiki>{{</nowiki>CURRENTDAY}}</code> را هم بسط می‌دهد — در واقع تقریباً هرچه را که داخل دوآکولاد باشد. این کار با صدازدن مرحلهٔ تجزیهٔ مربوط در خود مدیاویکی صورت می‌گیرد.",
        "expand_templates_title": "عنوان موضوع، برای {{FULLPAGENAME}} و غیره:",
index bcc4a64..da14636 100644 (file)
        "stub-threshold-disabled": "Ei käytössä",
        "recentchangesdays": "Näytettävien päivien määrä tuoreissa&nbsp;muutoksissa",
        "recentchangesdays-max": "Enintään $1 {{PLURAL:$1|päivä|päivää}}",
-       "recentchangescount": "Näytettävien muutoksien määrä oletuksena",
-       "prefs-help-recentchangescount": "Tämä sisältää tuoreet muutokset, muutoshistoriat ja lokit.",
+       "recentchangescount": "Näytettävien muutoksien määrä tuoreissa muutoksissa, sivujen historioissa ja logeissa oletuksena",
+       "prefs-help-recentchangescount": "Maksimiluku 1000",
        "prefs-help-watchlist-token2": "Tämä on salainen avain tarkkailulistasi verkkosyötteeseen.\nKuka tahansa, joka tietää sen voi lukea tarkkailulistaasi, joten älä paljasta sitä.\nJos sinun täytyy, [[Special:ResetTokens|voit uudistaa sen]].",
        "savedprefs": "Asetuksesi on tallennettu.",
        "savedrights": "Käyttäjän {{GENDER:$1|$1}} käyttäjäryhmät on tallennettu.",
        "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|tavu|tavua}}",
        "limitreport-templateargumentsize": "Mallineen argumenttien koko<br />(template argument size)",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|tavu|tavua}}",
-       "limitreport-expansiondepth": "Highest expansion depth",
+       "limitreport-expansiondepth": " Highest expansion depth",
        "limitreport-expensivefunctioncount": "Vaativien jäsenninfunktioiden lukumäärä",
        "expandtemplates": "Laajenna mallineet",
        "expand_templates_intro": "Tämä toimintosivu ottaa syötteeksi wikitekstiä ja laajentaa kaikki siinä olevat mallineet rekursiivisesti.\nSe myös laajentaa tuetut parserifunktiot kuten\n<code><nowiki>{{</nowiki>#language:...}}</code> ja -muuttujat kuten\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nKäytännössä se laajentaa melkein kaiken, joka on kaksoisaaltosulkeiden sisällä.",
index 8607c23..bcf91ef 100644 (file)
        "view": "Bilohi",
        "view-foreign": "Bilohi to $1",
        "edit": "Boli'o",
-       "edit-local": "Ubawa deskripsi lokal",
+       "edit-local": "Boli'a deskripsi lokal.",
        "create": "Mohutu",
        "create-local": "Duhengi deskripsi lokal",
        "delete": "Luluta",
-       "undelete_short": "Batali moluluto {{PLURAL:$1|tuwawu uba|$1 ubawa}}",
-       "viewdeleted_short": "Bilohi {{PLURAL:$1|tuwawu yiluluto uba|$1 yiluluto ubawa}}",
+       "undelete_short": "Batali moluluto {{PLURAL:$1|tuwawu boli'a|$1 biloli'o}}",
+       "viewdeleted_short": "Bilohi {{PLURAL:$1|tuwawu yiluluto boli'a|$1 yiluluto boli'a}}",
        "protect": "Dahawa",
        "protect_change": "boli'a",
-       "unprotect": "dudaha ubaalo",
+       "unprotect": "dudaha boli'olo",
        "newpage": "Halaman bohu",
        "talkpagelinktext": "lo'iya",
-       "specialpage": "Halaman uda'a",
+       "specialpage": "Halaman spesial",
        "personaltools": "Pilaakasi lo hihilawo",
        "talk": "Lo'iya",
        "views": "Bibilohu",
        "toolbox": "Pilaakasi",
-       "tool-link-userrights": "Boli'a lembo'a {{GENDER:$1|pengguna}}",
-       "tool-link-userrights-readonly": "Bilohi lembo'a {{GENDER:$1|pengguna}}",
-       "tool-link-emailuser": "Lawola email ode {{GENDER:$1|user}}",
+       "tool-link-userrights": "Boli'a lembo'a {{GENDER:$1|ta ohu'uwo}}",
+       "tool-link-userrights-readonly": "Bilohi lembo'a {{GENDER:$1|ta ohu'uwo}}",
+       "tool-link-emailuser": "Lawoli surel ode {{GENDER:$1|ta ohu'uwo}}",
        "imagepage": "Bilohi halaman berkas",
        "mediawikipage": "Bilohi halaman tahuli",
        "templatepage": "Bilohi halaman templat",
        "viewhelppage": "Bilohi halaman wubodu",
-       "categorypage": "Bilohi kategori halaman",
-       "viewtalkpage": "Bilohi u bilisala",
+       "categorypage": "Bilohi dalala lo halaman",
+       "viewtalkpage": "Bilohi u lo'iya",
        "otherlanguages": "To bahasa uweewo",
        "redirectedfrom": "Pilobale lonto $1",
-       "redirectpagesub": "Halaman pilobaleyalo",
+       "redirectpagesub": "Halaman pilobaleya",
        "redirectto": "Mobale ode",
        "lastmodifiedat": "Halaman botiye biloli'a pulitiyo $1,to $2.",
        "viewcount": "Halaman botiye ma hilu'o {{PLURAL:$1|$1 kali}}.<br />",
-       "protectedpage": "Halaman udaha-daha",
+       "protectedpage": "Halaman u daha-daha",
        "jumpto": "Lumanti'a ode:",
        "jumptonavigation": "navigasi",
        "jumptosearch": "lolohe",
-       "view-pool-error": "Ma'apu, server onggo sibuk sa'ati boti.\nNgohuntuwa pengguna mocoba momilehe halaman boti.\nWulatipo ngope'e to'u yi'o dipo mocoba momilehe halaman boti pooli.\n\n\n$1",
-       "generic-pool-error": "Ma'apu, server onggo sibuk sa'ati boti.\nNgohuntuwa pengguna mocoba momilohe halaman boti.\nWulatipo ngope'e to'u  yi'u dipo mocoba momilehe halaman boti pooli.",
+       "view-pool-error": "Ma'apu, server onggo sibuk sa'ati botiya.\nNgohuntuwa ta ohu'uwo hipohimontala momilehe halaman botiya.\nWulatipo ngope'e to'u yi'o diipo mohimontalo momilehe halaman botiye pooli.\n\n\n$1",
+       "generic-pool-error": "Ma'apu, server onggo sibuk sa'ati botiye.\nNgohuntuwa ta ohu'uwo hepohimotala momilohe halaman botiye.\nWulatipo ngope'e to'u  yi'u diipo mohimontalo momilehe halaman botiye pooli.",
        "pool-timeout": "Mohile wakutu mohulata u'unti",
-       "pool-queuefull": "Tahe'ambuwa hepohulata polu-polu",
+       "pool-queuefull": "Ta he'ambuwa hepohulata polu-polu",
        "pool-errorunknown": "Tilala u ja'otawa",
        "pool-servererror": "Ta hemorekeni pool botiye diya'a: $1",
        "poolcounter-usage-error": "Tilala lopohuna:$1",
        "helppage-top-gethelp": "Wubodu",
        "mainpage": "Halaman Bungaliyo",
        "mainpage-description": "Halaman bungaliyo",
-       "policy-url": "Project:Kebijakan",
+       "policy-url": "Project:Tinepo",
        "portal": "Buubu'a leembo'a",
        "portal-url": "Project:Buubu'a lembo'a",
        "privacy": "Tinepo privasi",
        "privacypage": "Project:Tinepo privasi",
        "badaccess": "Tilala haku momu'o",
-       "badaccess-group0": "Yi'o diya o iijini mohutu kalaja u hepohilemu",
-       "badaccess-groups": "Huhutu hepohilemu bilatasiyaliyo to pengguna {{PLURAL:$2|lembo'a}}$1.",
+       "badaccess-group0": "Yi'o ja o ijini mohutu karaja u hepohilemu",
+       "badaccess-groups": "Huhutu hepohilemu bilatasiyaliyo to ta ohu'uwo {{PLURAL:$2|lembo'a}}$1.",
        "versionrequired": "Paralu MediaWiki persi $1",
        "versionrequiredtext": "MediaWiki versi $1 paraluwolo wonu mopohuna lo halaman botiye.\nBilohi [[Special:Version|halaman versi]]",
        "ok": "OK",
        "retrievedfrom": "Yilotapu lonto \"$1\"",
        "youhavenewmessages": "{{PLURAL:$3|woluwo ulemu}} $1 ($2)",
-       "youhavenewmessagesfromusers": "{{PURAL:$4|woluwo ulemu}} $1 lonto {{PLURAL:$3|pengguna uwewo|$3 pengguna}} ($2)",
-       "youhavenewmessagesmanyusers": "Wolumo ulemu $1 lonto pengguna uwewo ($2)",
+       "youhavenewmessagesfromusers": "{{PURAL:$4|woluwo ulemu}} $1 lonto {{PLURAL:$3|ta ohu'uwo uwewo|$3 ta ohu'uwo}} ($2)",
+       "youhavenewmessagesmanyusers": "Wolumo ulemu $1 lonto ta ohu'uwo uwewo ($2)",
        "newmessageslinkplural": "{{PLURAL:$1|tuwawu tahuli bohu|999=tahuli bohu}}",
-       "newmessagesdifflinkplural": "{{PLURAL:$1|iluba|999=u iluba}} pulitiyo",
-       "youhavenewmessagesmulti": "Yio lootapu tahuli bohu to $1",
+       "newmessagesdifflinkplural": "{{PLURAL:$1|biloli'o|999=u biloli'o}} pulitiyo",
+       "youhavenewmessagesmulti": "Yio lo'otapu tahuli bohu to $1",
        "editsection": "boli'o",
-       "editold": "boli'a",
+       "editold": "boli'o",
        "viewsourceold": "Bilohi bungoliyo",
-       "editlink": "boli'a",
+       "editlink": "boli'o",
        "viewsourcelink": "Bilohi bungoliyo",
        "editsectionhint": "Momoli'o tayadu:$1",
        "toc": "Tuwango",
        "hidetoc": "wanto'a",
        "collapsible-collapse": "Wanto'a",
        "collapsible-expand": "Bu'ade",
-       "confirmable-confirm": "Delo {{GENDER:$1|yi'o}} yakini?",
+       "confirmable-confirm": "Delo {{GENDER:$1|yakini}} yi'o?",
        "confirmable-yes": "Jo",
        "confirmable-no": "De'e",
        "thisisdeleted": "Bilohi meyalo pohuwalinga $1",
        "viewdeleted": "Bilohi $1",
-       "restorelink": "{{PLURAL:$1|tuwawu yiluluto ubawa}}",
+       "restorelink": "{{PLURAL:$1|tuwawu biloli'o ma yiluluto}}",
        "feedlinks": "Paalo",
        "feed-invalid": "Hihile tayadu paalo dila banari.",
        "feed-unavailable": "Paalo sindikasi diyaluwo",
-       "site-rss-feed": "Palo $1 RSS",
+       "site-rss-feed": "Paalo $1 RSS",
        "site-atom-feed": "Paalo $1 Atom",
        "page-rss-feed": "Paalo $1 RSS",
        "page-atom-feed": "Paalo $1 Atom",
-       "red-link-title": "$1 (halaman diila sadi-sadia)",
-       "sort-descending": "Urutiya detibawa",
-       "sort-ascending": "Urutiya deyitaato",
+       "red-link-title": "$1 (halaman dipoluwo)",
+       "sort-descending": "Boluti ode tibawa",
+       "sort-ascending": "Boluti ode yitaato",
        "nstab-main": "Halaman",
-       "nstab-user": "Pengguna",
+       "nstab-user": "Halaman lo ta ohu'uwo",
        "nstab-media": "Halaman media",
        "nstab-special": "Halaman spesial",
        "nstab-project": "Halaman poroyek",
        "nstab-mediawiki": "Tahuli",
        "nstab-template": "Templat",
        "nstab-help": "Halaman wubodu",
-       "nstab-category": "Kategori",
+       "nstab-category": "Dalala",
        "mainpage-nstab": "Halaman bungaliyo",
        "nosuchaction": "Diya'a huhutu boyito",
-       "nosuchactiontext": "Huhutu u hepohile lo URL ja valid.\nYi'o lotalawa lopomaso lo URL, meyalo lodudu'a pranala u ja banari.\nUtiye olo kira-kira tuwotiyo woluwo bug to pilaakasi u hepomake {{SITENAME}}",
+       "nosuchactiontext": "Huhutu u hepohile lo URL ja valid.\nYi'o lotalawa lopotuwoto lo URL, meyalo lodudu'a wumbuta u ja banari.\nUtiye olo kira-kira tuwotiyo woluwo bug to pilaakasi u hepomake {{SITENAME}}",
        "nosuchspecialpage": "Diya'a halaman istimewa boyito",
-       "nospecialpagetext": "<molotolo>Yi'o hemohile halaman istimewa u ja sah.<molotolo>\n\nDaputari halaman istimewa mowali bilehela to [[Special:SpecialPages| {{int:specialpages}}]]",
-       "error": "Lotaalawa",
-       "databaseerror": "Lotaalawa tuwango data",
+       "nospecialpagetext": "<strong>Yi'o hemohile halaman istimewa u ja sah.<strong>\n\nDaputari halaman istimewa mowali bilehela to [[Special:SpecialPages| {{int:specialpages}}]]",
+       "error": "Tilala aba",
+       "databaseerror": "Tilala tuwango data",
        "databaseerror-text": "Ma tilala tuwawu basis kueri.\nUtiya kira-kira tuwotiyo woluwo bug to pilaakasi moluluhi'o.",
-       "databaseerror-textcl": "Ma tilala tuwawu basis kueri.",
+       "databaseerror-textcl": "Tilala tuwawu basis kueri.",
        "databaseerror-query": "Kueri $1",
        "databaseerror-function": "Huna: $1",
-       "databaseerror-error": "Lotaalawa: $1",
+       "databaseerror-error": "Tilala aba: $1",
        "transaction-duration-limit-exceeded": "Untuk mencegah penundaan replikasi yang tinggi, pengiriman ini dibatalkan karena durasi tulis ($1) melebihi batas $2 {{PLURAL:$2|detik|detik}}.\nJika Anda ingin mengganti banyak butir sekaligus, cobalah melakukan dalam operasi yang lebih kecil.",
-       "laggedslavemode": "<strong>Warning:</strong> Halaman kira ja o tuwanga lo'ubawa bohu",
+       "laggedslavemode": "<strong>Warning:</strong> Halaman kira ja o tuwango u lobohuwa.",
        "readonly": "Basis data unti-unti",
        "enterlockreason": "Masowa alasani longunti wawu omoluwa u'unti hu'oolo",
-       "missingarticle-rev": "(iluba#1:$1)",
-       "missingarticle-diff": "(Beda:$1,$2)",
+       "missingarticle-rev": "(biloli'o#1:$1)",
+       "missingarticle-diff": "(Hihede:$1,$2)",
        "readonly_lag": "Basis data ma iluntiya otomatis to'u basis data sekunder hemosinkronisasi wolo basis data utama",
-       "nonwrite-api-promise-error": "Lunggongo HTTP 'Promise-Non-Write-API-Action' ma yilawo dabo hihile pilohutu ode modul loluladu API.",
-       "internalerror": "Tilala todelomiyo",
-       "internalerror_info": "Tilala todelomiyo:$1",
+       "nonwrite-api-promise-error": "Lunggongo HTTP 'Promise-Non-Write-API-Action' ma yilawo dabo hihile pilohutu ode modul moluladu API.",
+       "internalerror": "Tilala lohihilawo",
+       "internalerror_info": "Tilala lohihilawo:$1",
        "internalerror-fatal-exception": "Ja wayitiyo fatal mengetik \"$1\"",
        "filecopyerror": "Jamowali mohemi tuwango \"$1\" de \"$2\"",
-       "filerenameerror": "Jamowali moganti tanggulo tuwango \"$1\" de \"$2\"",
+       "filerenameerror": "Jamowali molulo'a tanggulo tuwango \"$1\" de \"$2\"",
        "filedeleteerror": "Jamowali moluluta tuwango \"$1\"",
        "directorycreateerror": "Jamowali mohutu direktori \"$1\"",
        "directoryreadonlyerror": "Direktori \"$1\" bo pobaca.",
index e6183c5..0a665e3 100644 (file)
@@ -75,7 +75,7 @@
        "tog-watchlisthideminor": "הסתרת עריכות משניות ברשימת המעקב",
        "tog-watchlisthideliu": "הסתרת עריכות של משתמשים רשומים ברשימת המעקב",
        "tog-watchlistreloadautomatically": "רענון אוטומטי של רשימת המעקב בכל פעם שמסנן משתנה (דרוש JavaScript)",
-       "tog-watchlistunwatchlinks": "×\94×\95ספת ×§×\99ש×\95ר×\99 ×\94פסקת/×\94פע×\9cת ×\9eעק×\91 ×\9cער×\9bים ברשימת המעקב (דרוש JavaScript כדי שהקישור יתעדכן בעת לחיצה עליו)",
+       "tog-watchlistunwatchlinks": "×\94×\95ספת ×§×\99ש×\95ר×\99 ×\94פסקת/×\94פע×\9cת ×\9eעק×\91 ×\9c×\93פים ברשימת המעקב (דרוש JavaScript כדי שהקישור יתעדכן בעת לחיצה עליו)",
        "tog-watchlisthideanons": "הסתרת עריכות של משתמשים אנונימיים ברשימת המעקב",
        "tog-watchlisthidepatrolled": "הסתרת עריכות בדוקות ברשימת המעקב",
        "tog-watchlisthidecategorization": "הסתרת שינויים בקטגוריות",
        "privacy": "מדיניות הפרטיות",
        "privacypage": "Project:מדיניות הפרטיות",
        "badaccess": "שגיאת הרשאה",
-       "badaccess-group0": "אין {{GENDER:|לך|לך|לכם}} הרשאה לבצע את הפעולה ש{{GENDER:|ביקשת|ביקשת|ביקשתם}}.",
-       "badaccess-groups": "הפעולה ש{{GENDER:|ביקשת|ביקשת|ביקשתם}} לבצע מוגבלת למשתמשים ב{{PLURAL:$2|קבוצה הבאה|אחת הקבוצות הבאות}}: $1.",
+       "badaccess-group0": "אין לך הרשאה לבצע את הפעולה שביקשת.",
+       "badaccess-groups": "הפעולה שביקשת לבצע מוגבלת למשתמשים ב{{PLURAL:$2|קבוצה הבאה|אחת הקבוצות הבאות}}: $1.",
        "versionrequired": "נדרשת גרסה $1 של מדיה־ויקי",
        "versionrequiredtext": "גרסה $1 של תוכנת מדיה־ויקי נדרשת לשימוש בדף הזה.\n{{GENDER:|ראה|ראי|ראו}} [[Special:Version|מידע על הגרסה]].",
        "ok": "אישור",
        "sort-ascending": "מיון בסדר עולה",
        "nstab-main": "דף תוכן",
        "nstab-user": "דף משתמש",
-       "nstab-media": "מדיה",
+       "nstab-media": "×\93×£ ×\9e×\93×\99×\94",
        "nstab-special": "דף מיוחד",
        "nstab-project": "דף מיזם",
        "nstab-image": "קובץ",
        "laggedslavemode": "<strong>אזהרה:</strong> הדף עשוי שלא להכיל עדכונים אחרונים.",
        "readonly": "בסיס הנתונים נעול",
        "enterlockreason": "יש להקליד סיבה לנעילה, כולל הערכה למועד שחרור הנעילה",
-       "readonlytext": "×\91ס×\99ס ×\94נת×\95× ×\99×\9d × ×¢×\95×\9c ×\9bר×\92×¢ ×\9c×\94×\96נת × ×ª×\95× ×\99×\9d ×\95ש×\99× ×\95×\99×\99×\9d. ×\9b×\9b×\9c ×\94נר×\90×\94 מדובר בתחזוקה שוטפת, שלאחריה יחזור האתר לפעולתו הרגילה.\n\nמנהל המערכת שנעל את בסיס הנתונים סיפק את ההסבר הבא: $1",
+       "readonlytext": "×\91ס×\99ס ×\94נת×\95× ×\99×\9d × ×¢×\95×\9c ×\9bר×\92×¢ ×\9c×\94×\96נת × ×ª×\95× ×\99×\9d ×\95×\9cש×\99× ×\95×\99×\99×\9d ×\90×\97ר×\99×\9d. ×\9b×\9b×\9c ×\94נר×\90×\94, מדובר בתחזוקה שוטפת, שלאחריה יחזור האתר לפעולתו הרגילה.\n\nמנהל המערכת שנעל את בסיס הנתונים סיפק את ההסבר הבא: $1",
        "missing-article": "בסיס הנתונים לא מצא את הטקסט של הדף שהוא היה אמור למצוא, בשם \"$1\" $2.\n\nזה נגרם בדרך־כלל עקב לחיצה על קישור ישן לגרסה של דף שנמחק.\n\nאם זה אינו המקרה, זהו כנראה באג בתוכנה.\nנא לדווח על כך ל[[Special:ListUsers/sysop|מפעיל מערכת]], תוך שמירת פרטי כתובת ה־URL.",
        "missingarticle-rev": "(מספר גרסה: $1)",
        "missingarticle-diff": "(השוואת הגרסאות: $1, $2)",
        "unexpected": "ערך לא צפוי: \"$1\"=\"$2\".",
        "formerror": "שגיאה: לא ניתן היה לשלוח את הטופס.",
        "badarticleerror": "לא ניתן לבצע את הפעולה הזאת בדף זה.",
-       "cannotdelete": "×\9c×\90 × ×\99ת×\9f ×\94×\99×\94 ×\9c×\9e×\97×\95ק ×\90ת ×\94×\93×£ ×\90×\95 ×\94ק×\95×\91×¥ \"$1\".\n×\99×\99ת×\9b×\9f ×©×\94×\95×\90 ×\9b×\91ר × ×\9e×\97ק ×¢×\9cÖ¾×\99×\93×\99 ×\9eשת×\9eש אחר.",
+       "cannotdelete": "×\9c×\90 × ×\99ת×\9f ×\94×\99×\94 ×\9c×\9e×\97×\95ק ×\90ת ×\94×\93×£ ×\90×\95 ×\90ת ×\94ק×\95×\91×¥ \"$1\".\n×\99×\99ת×\9b×\9f ×©×\94×\95×\90 ×\9b×\91ר × ×\9e×\97ק ×¢×\9cÖ¾×\99×\93×\99 ×\9e×\99ש×\94×\95 אחר.",
        "cannotdelete-title": "לא ניתן למחוק את הדף \"$1\"",
        "delete-hook-aborted": "המחיקה הופסקה על־ידי מבנה Hook.\nלא ניתן הסבר.",
        "no-null-revision": "לא ניתן היה ליצור גרסת־דמה בדף \"$1\"",
        "title-invalid-interwiki": "כותרת הדף המבוקש מכילה קישור בינוויקי, שלא ניתן להשתמש בו בכותרות.",
        "title-invalid-talk-namespace": "כותרת הדף המבוקש מפנה לדף שיחה שאינו יכול להתקיים.",
        "title-invalid-characters": "כותרת הדף המבוקש מכילה תווים בלתי תקינים: \"$1\".",
-       "title-invalid-relative": "בכותרת יש נתיב יחסי. כותרת דפים יחסיות (./, ../) אינן תקינות, משום שלעתים קרובות הן יהיו בלתי־ניתנות להשגה כשתטופלנה על־ידי הדפדפן של המשתמש.",
+       "title-invalid-relative": "×\91×\9b×\95תרת ×\99ש × ×ª×\99×\91 ×\99×\97ס×\99. ×\9b×\95תר×\95ת ×\93פ×\99×\9d ×\99×\97ס×\99×\95ת (./, ../) ×\90×\99× ×\9f ×ª×§×\99× ×\95ת, ×\9eש×\95×\9d ×©×\9cעת×\99×\9d ×§×¨×\95×\91×\95ת ×\94×\9f ×\99×\94×\99×\95 ×\91×\9cת×\99Ö¾× ×\99תנ×\95ת ×\9c×\94ש×\92×\94 ×\9bשת×\98×\95פ×\9c× ×\94 ×¢×\9cÖ¾×\99×\93×\99 ×\94×\93פ×\93פ×\9f ×©×\9c ×\94×\9eשת×\9eש.",
        "title-invalid-magic-tilde": "כותרת הדף המבוקש מכילה רצף טילדות מיוחד שאינו תקין (<nowiki>~~~</nowiki>).",
        "title-invalid-too-long": "כותרת הדף המבוקש ארוכה מדי. היא צריכה להיות לכל היותר באורך של {{PLURAL:$1|בית אחד|$1 בתים}} בקידוד UTF-8.",
        "title-invalid-leading-colon": "כותרת הדף המבוקש מכילה תו נקודתיים בלתי תקין בתחילתה.",
        "actionthrottled": "הפעולה הוגבלה",
        "actionthrottledtext": "כאמצעי נגד שימוש לרעה, קיימת מגבלה על ביצוע פעולה זו פעמים רבות מדי בזמן קצר, וחרגת מהמגבלה הזאת.\nנא לנסות שוב בעוד מספר דקות.",
        "protectedpagetext": "דף זה מוגן כדי למנוע עריכה ופעולות אחרות.",
-       "viewsourcetext": "ב{{GENDER:|אפשרותך|אפשרותך|אפשרותכם}} לצפות בטקסט המקור של הדף ולהעתיקו.",
-       "viewyourtext": "ב{{GENDER:|אפשרותך|אפשרותך|אפשרותכם}} לצפות בטקסט המקור של <strong>העריכות {{GENDER:|שלך|שלך|שלכם}}</strong> בדף הזה ולהעתיקו.",
+       "viewsourcetext": "באפשרותך לצפות בטקסט המקור של הדף ולהעתיקו.",
+       "viewyourtext": "באפשרותך לצפות בטקסט המקור של <strong>העריכות שלך</strong> בדף הזה ולהעתיקו.",
        "protectedinterface": "דף זה הוא אחד הדפים המספקים הודעות מערכת לתוכנה שמפעילה את {{SITENAME}}, והוא מוגן כדי למנוע השחתות.\nכדי להוסיף או לשנות תרגומים של הודעות מערכת עבור כל אתרי הוויקי, יש להשתמש ב־[https://translatewiki.net/ translatewiki.net], פרויקט התרגום של מדיה־ויקי.",
-       "editinginterface": "<strong>×\90×\96×\94ר×\94:</strong> ×\94×\93×£ ×©{{GENDER:|×\90ת×\94 ×¢×\95ר×\9a\90ת ×¢×\95ר×\9bת|×\90ת×\9d ×¢×\95ר×\9b×\99×\9d}} הוא אחד הדפים המספקים הודעות מערכת לתוכנה שמפעילה את {{SITENAME}}.\nשינויים בדף הזה ישפיעו על ממשק המשתמש של משתמשים אחרים באתר.",
+       "editinginterface": "<strong>×\90×\96×\94ר×\94:</strong> ×\93×£ ×\96×\94 הוא אחד הדפים המספקים הודעות מערכת לתוכנה שמפעילה את {{SITENAME}}.\nשינויים בדף הזה ישפיעו על ממשק המשתמש של משתמשים אחרים באתר.",
        "translateinterface": "כדי להוסיף או לשנות תרגומים של הודעות מערכת עבור כל אתרי הוויקי, יש להשתמש ב־[https://translatewiki.net/ translatewiki.net], פרויקט התרגום של מדיה־ויקי.",
        "cascadeprotected": "דף זה מוגן מעריכה כי הוא מוכלל {{PLURAL:$1|בדף הבא, שמופעלת עליו|בדפים הבאים, שמופעלת עליהם}} הגנה מדורגת:\n$2",
        "namespaceprotected": "אין {{GENDER:|לך|לך|לכם}} הרשאה לערוך דפים במרחב השם <strong>$1</strong>.",
        "session_fail_preview": "מצטערים! לא ניתן לבצע את עריכתכם עקב אובדן מידע הכניסה.\n\nייתכן שנותקתם מהחשבון. <strong>אנא ודאו שאתם עדיין מחוברים לחשבון ונסו שוב.</strong>\nאם זה עדיין לא עובד, נסו [[Special:UserLogout|לצאת מהחשבון]] ולהיכנס אליו שנית, וודאו שהדפדפן שלכם מאפשר קבלת עוגיות מאתר זה.",
        "session_fail_preview_html": "מצטערים! לא ניתן לבצע את עריכתם עקב אובדן מידע הכניסה.\n\n<em>כיוון שב{{grammar:תחילית|{{SITENAME}}}} אפשרות השימוש ב־HTML גולמי מופעלת, התצוגה המקדימה מוסתרת כדי למנוע התקפות JavaScript.</em>\n\n<strong>אם זהו ניסיון עריכה לגיטימי, אנא נסו שוב.</strong>\nאם זה עדיין לא עובד, נסו [[Special:UserLogout|לצאת מהחשבון]] ולהיכנס אליו שנית, וודאו שהדפדפן שלכם מאפשר קבלת עוגיות מאתר זה.",
        "token_suffix_mismatch": "'''עריכתך נדחתה כיוון שהדפדפן שלך מחק את תווי הפיסוק באסימון העריכה.'''\nהעריכה נדחתה כדי למנוע בעיות כאלה בטקסט של הדף.\nלעתים התקלה מתרחשת עקב שימוש בשירות פרוקסי אנונימי פגום.",
-       "edit_form_incomplete": "<strong>חלקים מסוימים מטופס העריכה לא הגיעו לשרת; אנא {{GENDER:|בדוק|בִדקי|בִדקו}} שהעריכה לא נפגעה ו{{GENDER:|נסה|נסי|נסו}} שוב.</strong>",
+       "edit_form_incomplete": "<strong>חלקים מסוימים מטופס העריכה לא הגיעו לשרת; אנא {{GENDER:|בדוק|בדקי|בדקו}} שהעריכה לא נפגעה ו{{GENDER:|נסה|נסי|נסו}} שוב.</strong>",
        "editing": "עריכת הדף \"$1\"",
        "creating": "יצירת הדף \"$1\"",
        "editingsection": "עריכת הדף \"$1\" (פסקה)",
        "listfiles-latestversion-no": "לא",
        "file-anchor-link": "קובץ",
        "filehist": "היסטוריית הקובץ",
-       "filehist-help": "×\9c×\97צ×\95 על תאריך/שעה כדי לראות את הקובץ כפי שנראה בעת זו.",
+       "filehist-help": "× ×\99ת×\9f ×\9c×\9c×\97×\95×¥ על תאריך/שעה כדי לראות את הקובץ כפי שנראה בעת זו.",
        "filehist-deleteall": "מחיקת כל הגרסאות",
        "filehist-deleteone": "מחיקה",
        "filehist-revert": "שחזור",
        "filerevert-comment": "סיבה:",
        "filerevert-defaultcomment": "שוחזר לגרסה מ־$2, $1 ($3)",
        "filerevert-submit": "שחזור",
-       "filerevert-success": "<strong>[[Media:$1|$1]]</strong> שוחזר ל[$4 גרסה מ־$3, $2].",
+       "filerevert-success": "הקובץ <strong>[[Media:$1|$1]]</strong> שוחזר ל[$4 גרסה מ־$3, $2].",
        "filerevert-badversion": "אין גרסה מקומית קודמת של הקובץ שהועלתה בתאריך המבוקש.",
        "filerevert-identical": "הגרסה הנוכחית של הקובץ כבר זהה לגרסה שנבחרה.",
        "filedelete": "מחיקת $1",
        "filedelete-intro-old": "אתם מוחקים את הגרסה של '''[[Media:$1|$1]]''' מ־[$4 $3, $2].",
        "filedelete-comment": "סיבה:",
        "filedelete-submit": "מחיקה",
-       "filedelete-success": "'''$1''' נמחק.",
+       "filedelete-success": "הקובץ <strong>$1</strong> נמחק.",
        "filedelete-success-old": "הגרסה של '''[[Media:$1|$1]]''' מ־$3, $2 נמחקה.",
        "filedelete-nofile": "'''$1''' אינו קיים.",
        "filedelete-nofile-old": "אין גרסה ישנה של '''$1''' עם התכונות המבוקשות.",
        "deletereasonotherlist": "סיבה אחרת",
        "deletereason-dropdown": "* סיבות מחיקה נפוצות\n** ספאם\n** השחתה\n** הפרת זכויות יוצרים\n** לבקשת הכותב\n** הפניה שבורה",
        "delete-edit-reasonlist": "עריכת סיבות המחיקה",
-       "delete-toobig": "×\93×£ ×\96×\94 ×\9b×\95×\9c×\9c ×\9e×¢×\9c {{PLURAL:$1|×\92רס×\94 ×\90×\97ת|$1 ×\92רס×\90×\95ת}} ×\91×\94×\99ס×\98×\95ר×\99×\99ת ×\94ער×\99×\9b×\95ת ×©×\9c×\95. ×\9e×\97×\99קת ×\93פ×\99×\9d ×\9b×\90×\9c×\94 ×\94×\95×\92×\91×\9c×\94 ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ ×¤×\92×\99×¢×\94 ×\91×\91×\99צ×\95×¢×\99 ×\94×\90תר.",
+       "delete-toobig": "×\9c×\93×£ ×\96×\94 ×\99ש ×\94×\99ס×\98×\95ר×\99×\99ת ×¢×¨×\99×\9b×\95ת ×\92×\93×\95×\9c×\94, ×\95×\94×\95×\90 ×\9e×\9b×\99×\9c ×\99×\95תר {{PLURAL:$1|×\9e×\92רס×\94 ×\90×\97ת|×\9eÖ¾$1 ×\92רס×\90×\95ת}}.\n×\9e×\97×\99קת ×\93פ×\99×\9d ×\9b×\90×\9c×\94 ×\94×\95×\92×\91×\9c×\94 ×\9b×\93×\99 ×\9c×\9e× ×\95×¢ ×\91×¢×\99×\95ת ×\91תפק×\95×\93 ×©×\9c {{SITENAME}}.",
        "delete-warning-toobig": "דף זה כולל מעל {{PLURAL:$1|גרסה אחת|$1 גרסאות}} בהיסטוריית העריכות שלו. מחיקה שלו עלולה להפריע לפעולות בבסיס הנתונים; אנא שקלו שנית את המחיקה.",
        "deleteprotected": "אין {{GENDER:|באפשרותך|באפשרותך|באפשרותכם}} למחוק את הדף כי הוא מוגן.",
        "deleting-backlinks-warning": "<strong>אזהרה:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|דפים אחרים]] מקשרים לדף ש{{GENDER:|אתה עומד|את עומדת|אתם עומדים}} למחוק או מכלילים אותו.",
        "ipb-blocklist-contribs": "תרומות של {{GENDER:$1|$1}}",
        "ipb-blocklist-duration-left": "נותרו $1",
        "unblockip": "שחרור חסימה של משתמש",
-       "unblockiptext": "השתמשו בטופס שלהלן כדי להחזיר את הרשאות הכתיבה למשתמש או כתובת IP חסומים.",
+       "unblockiptext": "{{GENDER:|השתמש|השתמשי|השתמשו}} בטופס שלהלן כדי להחזיר את הרשאות הכתיבה לכתובת IP חסומה או למשתמש חסום.",
        "ipusubmit": "הסרת חסימה זו",
        "unblocked": "[[User:$1|$1]] {{GENDER:$1|שוחרר מחסימתו|שוחררה מחסימתה}}.",
        "unblocked-range": "$1 שוחרר מחסימתו.",
        "lockedbyandtime": "(על־ידי $1 ב־$3, $2)",
        "move-page": "העברת הדף \"$1\"",
        "move-page-legend": "העברת דף",
-       "movepagetext": "{{GENDER:|השתמש|השתמשי|השתמשו}} בטופס שלהלן כדי לשנות את השם של הדף הזה, ולהעביר את כל היסטוריית העריכות שלו לשם החדש.\nהשם הישן יהפוך לדף הפניה אל השם החדש.\n{{GENDER:|באפשרותך|באפשרותך|באפשרותכם}} לעדכן באופן אוטומטי דפי הפניה שכרגע מפנים לשם הנוכחי של הדף.\nאם {{GENDER:|תבחר|תבחרי|תבחרו}} לא לעשות זאת, אנא {{GENDER:|ודא|ודאי|ודאו}} לאחר ההעברה שאין [[Special:DoubleRedirects|הפניות כפולות]] או [[Special:BrokenRedirects|הפניות שבורות]].\nב{{GENDER:|אחריותך|אחריותך|אחריותכם}} לוודא שכל הקישורים ימשיכו לקשר למקומות שאליהם הם אמורים לקשר.\n\n{{GENDER:|שים|שימי|שימו}} לב שהדף <strong>לא</strong> יועבר אם כבר יש דף תחת השם החדש ש{{GENDER:|תבחר|תבחרי|תבחרו}}, אלא אם כן הדף עם השם החדש הוא הפניה ואין לו עריכות קודמות.\nזה אומר ש{{GENDER:|תוכל|תוכלי|תוכלו}} להחזיר את הדף לשם המקורי במקרה שתיעשה טעות, אבל לא ניתן \"לדרוס\" דף קיים.\n\n<strong>לתשומת {{GENDER:|לבך|לבך|לבכם}}:</strong>\nהעברה זו עלולה להיות שינוי דרסטי ומהותי לדף פופולרי;\nאנא {{GENDER:|ודא שאתה מבין|ודאי שאת מבינה|ודאו שאתם מבינים}} את התוצאות של הפעולה הזאת לפני ביצוע ההעברה.",
-       "movepagetext-noredirectfixer": "{{GENDER:|השתמש|השתמשי|השתמשו}} בטופס שלהלן כדי לשנות את השם של הדף הזה, ולהעביר את כל היסטוריית העריכות שלו לשם החדש.\nהשם הישן יהפוך לדף הפניה אל השם החדש.\nאנא {{GENDER:|ודא|ודאי|ודאו}} לאחר ההעברה שאין [[Special:DoubleRedirects|הפניות כפולות]] או [[Special:BrokenRedirects|הפניות שבורות]].\nב{{GENDER:|אחריותך|אחריותך|אחריותכם}} לוודא שכל הקישורים ימשיכו לקשר למקומות שאליהם הם אמורים לקשר.\n\n{{GENDER:|שים|שימי|שימו}} לב שהדף <strong>לא</strong> יועבר אם כבר יש דף תחת השם החדש ש{{GENDER:|תבחר|תבחרי|תבחרו}}, אלא אם כן הדף עם השם החדש הוא הפניה ואין לו עריכות קודמות.\nזה אומר ש{{GENDER:|תוכל|תוכלי|תוכלו}} להחזיר את הדף לשם המקורי במקרה שתיעשה טעות, אבל לא ניתן \"לדרוס\" דף קיים.\n\n<strong>לתשומת {{GENDER:|לבך|לבך|לבכם}}:</strong>\nהעברה זו עלולה להיות שינוי דרסטי ומהותי לדף פופולרי;\nאנא {{GENDER:|ודא שאתה מבין|ודאי שאת מבינה|ודאו שאתם מבינים}} את התוצאות של הפעולה הזאת לפני ביצוע ההעברה.",
+       "movepagetext": "ניתן להשתמש בטופס שלהלן כדי לשנות את השם של הדף הזה ולהעביר את כל היסטוריית העריכות שלו לשם החדש.\nהשם הישן יהפוך לדף הפניה אל השם החדש.\nבאפשרותך לעדכן באופן אוטומטי דפי הפניה שכרגע מפנים לשם הנוכחי של הדף.\nנא לוודא לאחר ההעברה שאין [[Special:DoubleRedirects|הפניות כפולות]] או [[Special:BrokenRedirects|הפניות שבורות]].\nכמו כן, באחריותך לוודא שכל הקישורים ימשיכו לקשר למקומות שאליהם הם אמורים לקשר.\n\nיש לשים לב לכך שהדף <strong>לא</strong> יועבר אם כבר יש דף תחת השם החדש, אלא אם כן הדף עם השם החדש הוא הפניה ואין לו עריכות קודמות.\nזה אומר שניתן יהיה להחזיר את הדף לשם המקורי במקרה שתיעשה טעות, אבל לא ניתן \"לדרוס\" דף קיים.\n\n<strong>לתשומת לבך:</strong>\nהעברה זו עלולה להיות שינוי דרסטי ומהותי לדף פופולרי;\nיש לקחת בחשבון את התוצאות של הפעולה הזאת לפני ביצוע ההעברה.",
+       "movepagetext-noredirectfixer": "ניתן להשתמש בטופס שלהלן כדי לשנות את השם של הדף הזה ולהעביר את כל היסטוריית העריכות שלו לשם החדש.\nהשם הישן יהפוך לדף הפניה אל השם החדש.\nנא לוודא לאחר ההעברה שאין [[Special:DoubleRedirects|הפניות כפולות]] או [[Special:BrokenRedirects|הפניות שבורות]].\nכמו כן, באחריותך לוודא שכל הקישורים ימשיכו לקשר למקומות שאליהם הם אמורים לקשר.\n\nיש לשים לב לכך שהדף <strong>לא</strong> יועבר אם כבר יש דף תחת השם החדש, אלא אם כן הדף עם השם החדש הוא הפניה ואין לו עריכות קודמות.\nזה אומר שניתן יהיה להחזיר את הדף לשם המקורי במקרה שתיעשה טעות, אבל לא ניתן \"לדרוס\" דף קיים.\n\n<strong>לתשומת לבך:</strong>\nהעברה זו עלולה להיות שינוי דרסטי ומהותי לדף פופולרי;\nיש לקחת בחשבון את התוצאות של הפעולה הזאת לפני ביצוע ההעברה.",
        "movepagetalktext": "אם האפשרות הזאת מסומנת, דף השיחה של הדף הזה יועבר אוטומטית לשם החדש, אלא אם קיים דף שיחה שאינו ריק תחת השם החדש. במקרה כזה, יש להעביר או למזג את הדפים באופן ידני, במידת הצורך.",
        "moveuserpage-warning": "'''אזהרה:''' אתם עומדים להעביר דף משתמש. שימו לב שרק הדף יועבר וששם המשתמש '''לא''' ישתנה.",
        "movecategorypage-warning": "<strong>אזהרה:</strong> אתם עומדים להעביר דף קטגוריה. שימו לב שרק הדף יועבר ושכל הדפים בקטגוריה הישנה <strong>לא</strong> יסווגו לקטגוריה החדשה.",
        "thumbnail_image-failure-limit": "היו לאחרונה ניסיונות רבים מדי ($1 או יותר) ליצור את התמונה הממוזערת הזאת. נא לנסות שוב מאוחר יותר.",
        "import": "ייבוא דפים",
        "importinterwiki": "ייבוא מאתר ויקי אחר",
-       "import-interwiki-text": "×\90× ×\90 ×\91×\97ר×\95 אתר ויקי וכותרת דף לייבוא.\nתאריכי העריכות ושמות העורכים יישמרו.\nכל פעולות הייבוא מאתרי ויקי אחרים נשמרות ב[[Special:Log/import|יומן הייבוא]].",
+       "import-interwiki-text": "× ×\90 ×\9c×\91×\97×\95ר אתר ויקי וכותרת דף לייבוא.\nתאריכי העריכות ושמות העורכים יישמרו.\nכל פעולות הייבוא מאתרי ויקי אחרים נשמרות ב[[Special:Log/import|יומן הייבוא]].",
        "import-interwiki-sourcewiki": "אתר המקור:",
        "import-interwiki-sourcepage": "דף המקור:",
        "import-interwiki-history": "העתקת כל היסטוריית העריכות של דף זה",
        "monthsall": "הכול",
        "confirmemail": "אימות כתובת דוא\"ל",
        "confirmemail_noemail": "אין לך כתובת דוא\"ל תקפה המוגדרת ב[[Special:Preferences|העדפות המשתמש]] שלך.",
-       "confirmemail_text": "{{GENDER:|עליך|עלייך|עליכם}} לאמת את כתובת הדוא\"ל {{GENDER:|שלך|שלך|שלכם}} לפני ש{{GENDER:|תוכל|תוכלי|תוכלו}} להשתמש בשירותי הדוא\"ל של {{SITENAME}}.\n{{GENDER:|לחץ|לחצי|לחצו}} על הכפתור שלמטה כדי לשלוח קוד אימות לכתובת הדוא\"ל ש{{GENDER:|הזנת|הזנת|הזנתם}}.\n{{GENDER:|פתח|פִתחי|פִתחו}} את הקישור בדפדפן {{GENDER:|שלך|שלך|שלכם}} כדי לאשר שכתובת הדוא\"ל תקפה.",
+       "confirmemail_text": "{{GENDER:|עליך|עלייך|עליכם}} לאמת את כתובת הדוא\"ל {{GENDER:|שלך|שלך|שלכם}} לפני ש{{GENDER:|תוכל|תוכלי|תוכלו}} להשתמש בשירותי הדוא\"ל של {{SITENAME}}.\n{{GENDER:|לחץ|לחצי|לחצו}} על הכפתור שלמטה כדי לשלוח קוד אימות לכתובת הדוא\"ל ש{{GENDER:|הזנת|הזנת|הזנתם}}.\nההודעה {{GENDER:|שתקבל|שתקבלי|שתקבלו}} תכלול קישור שמכיל קוד;\n{{GENDER:|פתח|פתחי|פתחו}} את הקישור בדפדפן {{GENDER:|שלך|שלך|שלכם}} כדי לאשר שכתובת הדוא\"ל תקפה.",
        "confirmemail_pending": "קוד האימות כבר נשלח לדואר האלקטרוני {{GENDER:|שלך|שלך|שלכם}};\nאם {{GENDER:|יצרת|יצרת|יצרתם}} את החשבון לאחרונה, כדאי להמתין מספר דקות עד שהדוא\"ל יגיע לפני בקשת קוד חדש.",
        "confirmemail_send": "לשלוח קוד אימות",
        "confirmemail_sent": "הדוא\"ל עם קוד האימות נשלח.",
        "logentry-import-upload": "$1 {{GENDER:$2|ייבא|ייבאה}} את הדף $3 באמצעות העלאת קובץ",
        "logentry-import-upload-details": "$1 {{GENDER:$2|ייבא|ייבאה}} את $3 באמצעות העלאת קובץ ({{PLURAL:$4|גרסה אחת|$4 גרסאות}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|ייבא|ייבאה}} את הדף $3 מאתר ויקי אחר",
-       "logentry-import-interwiki-details": "$1 {{GENDER:$2|ייבא|ייבאה}} את הדף $3 מ־$5&rlm; ({{PLURAL:$4|גרסה אחת|$4 גרסאות}})",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|ייבא|ייבאה}} את הדף $3 מתוך $5&rlm; ({{PLURAL:$4|גרסה אחת|$4 גרסאות}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|מיזג|מיזגה}} את הדף $3 לתוך הדף $4 (גרסאות עד $5)",
        "logentry-move-move": "$1 {{GENDER:$2|העביר|העבירה}} את הדף $3 לשם $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|העביר|העבירה}} את הדף $3 לשם $4 בלי להשאיר הפניה",
index dc56a3b..6f59922 100644 (file)
        "cantrollback": "Nem lehet visszaállítani: az utolsó szerkesztést végző felhasználó az egyetlen, aki a lapot szerkesztette.",
        "alreadyrolled": "[[:$1]] utolsó, [[User:$2|$2]] ([[User talk:$2|vita]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) általi szerkesztését nem lehet visszavonni:\nidőközben valaki már visszavonta vagy szerkesztette a lapot.\n\nAz utolsó szerkesztést [[User:$3|$3]] ([[User talk:$3|vita]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) végezte.",
        "editcomment": "A szerkesztési összefoglaló <em>$1</em> volt.",
-       "revertpage": "Visszaállítottam a lap korábbi változatát: [[Special:Contributions/$2|$2]]  ([[User talk:$2|vita]]) szerkesztéséről [[User:$1|$1]] szerkesztésére",
+       "revertpage": "Visszaállítottam a lap korábbi változatát [[Special:Contributions/$2|$2]] ([[User talk:$2|vita]]) szerkesztéséről [[User:$1|$1]] szerkesztésére",
        "revertpage-nouser": "Visszaállítottam a lap korábbi változatát (szerkesztőnév eltávolítva) szerkesztéséről [[User:$1|$1]] szerkesztésére",
        "rollback-success": "{{GENDER:$3|$1}} szerkesztéseit visszaállítottam {{GENDER:$4|$2}} utolsó változatára.",
        "rollback-success-notify": "$1 szerkesztései visszaállítva;\nhelyreállítva $2 utolsó változata. [$3 Változtatások megtekintése]",
index 60b9e82..d159c91 100644 (file)
@@ -24,7 +24,7 @@
        "tog-newpageshidepatrolled": "Celez patroliita pagini en la listo di nova pagino",
        "tog-hidecategorization": "Celar kategorizeso di la pagini",
        "tog-extendwatchlist": "Expansez surveyo-listo por montrar omna chanji, vice nur la maxim recenta",
-       "tog-usenewrc": "Chanji al grupo po pagino en recenta chanji e \"watchlist\"",
+       "tog-usenewrc": "Grupigar la modifiki por pagino en recenta chanji e \"watchlist\"",
        "tog-numberheadings": "Autonumerez tituli",
        "tog-showtoolbar": "Montrez redaktilo (JavaScript bezonesas)",
        "tog-editondblclick": "Redaktez pagini kande on klikus dufoye (JavaScript bezonesas)",
        "recreate-moveddeleted-warn": "<strong>Atencez: Vu rikreos pagino qua antee efacesis.</strong>\n\nVu mustas konsiderar se esos konvenanta o ne riskribor ol.\nPor vua konoco, la motivo dil antea efaco montresas hike:",
        "moveddeleted-notice": "Ica pagino efacesis.\nL'efaco-registraro e la movo-registraro di la pagino povas videsar sequante, por konsulto.",
        "edit-conflict": "Konflikto di editi.",
+       "postedit-confirmation-created": "La pagino kreesis.",
        "postedit-confirmation-saved": "Vua redakto konservesis",
        "content-model-wikitext": "texto Wiki",
        "content-model-javascript": "JavaScript",
        "content-json-empty-object": "vakua objekto",
        "content-json-empty-array": "vakua tabelo",
        "deprecated-self-close-category": "Pagini qui uzas nevalida etiketi HTML por klozajo",
+       "duplicate-args-category": "Pagini kun argumenti duopligita che shabloni",
+       "parser-unstrip-loop-warning": "Renkontresis nefinita procedo ('loop') en la funciono \"Unstrip\"",
        "undo-failure": "Ne povis nuligar la redakto pro konflikti kun intermeza redakti.",
        "viewpagelogs": "Videz registrari por ca pagino",
        "nohistory": "Ne esas redakto-historio por ica pagino.",
        "rev-deleted-comment": "(rezumo di redakti forigesis)",
        "rev-deleted-user": "(uzantonomo forigita)",
        "rev-deleted-event": "(detali dil registro forigesis)",
+       "rev-deleted-user-contribs": "[Uzero od IP-adreso eliminita - la redakto celesis de la kontributaji]",
        "rev-delundel": "montrar/celar",
        "rev-showdeleted": "montrar",
        "revdelete-show-file-submit": "Yes",
        "search-section": "(seciono $1)",
        "search-file-match": "(kongruanta kun la kontenajo)",
        "search-suggest": "Ka vu volis dicar: $1",
+       "search-rewritten": "Yen la rezulti por \"$1\". Serchez vice por \"$2\".",
        "search-interwiki-caption": "Altra projekti",
        "search-interwiki-default": "Rezultaji de $1:",
        "search-interwiki-more": "(plusa)",
        "prefs-personal": "Personala informo",
        "prefs-rc": "Recenta chanji",
        "prefs-watchlist": "Surveyo-listo",
+       "prefs-editwatchlist-edit": "Vidar e removar tituli de vua surveyo-listo",
        "prefs-watchlist-days": "Dii montrata en surveyaji:",
        "prefs-watchlist-days-max": "Maxime $1 {{PLURAL:$1|dio|dii}}",
        "prefs-watchlist-edits-max": "Maxima nombro: 1000",
        "prefs-misc": "Mixaji",
        "prefs-resetpass": "Chanjar pasovorto",
+       "prefs-changeemail": "Chanjar od efacar e-postal adreso",
        "prefs-email": "Selekti pri e-posto (e-mail)",
        "prefs-rendering": "Aspekto",
        "saveprefs": "Registragar",
        "restoreprefs": "Restaurar omna preferaji 'default' (en omna secioni)",
        "prefs-editing": "Grandeso dil areo por texto",
        "searchresultshead": "Preferaji di la rezultaji dil sercho",
+       "stub-threshold": "Limito por ligilar ad esbosuri ($1):",
+       "stub-threshold-disabled": "Sen efekto",
        "recentchangesdays": "Dii montrota en la recenta chanji:",
        "recentchangesdays-max": "Maximo $1 {{PLURAL:$1|dio|dii}}",
        "recentchangescount": "Quanto de redakti montrota kustume:",
        "savedprefs": "Vua preferaji registragesis.",
        "timezonelegend": "Tempala zono:",
        "localtime": "Lokala tempo:",
+       "timezoneuseoffset": "Altra (definez precize)",
        "servertime": "Kloko en la servanto:",
        "guesstimezone": "Obtenar la kloko dil \"browser\"",
        "timezoneregion-africa": "Afrika",
        "timezoneregion-pacific": "Pacifico",
        "allowemail": "Permisez e-posti de altra uzanti",
        "email-allow-new-users-label": "Permisez e-posti de la nova uzeri",
+       "email-blacklist-label": "Impedez la sequanta uzeri sendar e-posto a me:",
        "prefs-namespaces": "Nomari",
+       "default": "Ordinara ('default')",
        "prefs-files": "Arkivi",
        "prefs-emailconfirm-label": "Konfirmado dil e-posto (e-mail):",
        "youremail": "Vua e-adreso:",
        "yournick": "Signaturo:",
        "prefs-help-signature": "Komenti en la diskuto-pagini mustas signatesar, skribante 4 tildi (<nowiki>~~~~</nowiki>), qui transformesos en vua signaturo ed en l'indiko di la horo e dio quan vu signatis ol.",
        "badsiglength": "Vua signaturo es tro longa.\nOl mustas ne havar plu kam $1 {{PLURAL:$1|litero|literi}}.",
-       "yourgender": "Quale vu preferas esar priskribata?",
+       "yourgender": "Quale vu preferas esar mencionata?",
        "gender-unknown": "Lor mencionar vu, la programaro uzos sexuo-neutrala vorti tam ofte kam posibla",
        "gender-male": "Ilu redaktas wikiopagini",
        "gender-female": "Elu redaktas wikiopagini",
        "prefs-help-email-others": "Vu povas anke selektar se permisos altri skribar a vu per e-posto, per ligilo en vua uzanto-pagino o diskuto-pagino.\nVua e-posto adreso ne revelesos, kande l'altri skribos a vu.",
        "prefs-help-email-required": "E-postala adreso es bezonata.",
        "prefs-info": "Bazala informeso",
+       "prefs-i18n": "Internacioniigo",
        "prefs-signature": "Signaturo",
+       "prefs-timeoffset": "Registro dil tempo",
        "prefs-editor": "Redaktilo",
        "prefs-preview": "Previdar",
+       "prefs-advancedrc": "Progresiva selektaji (advanced options)",
+       "prefs-advancedrendering": "Progresiva selektaji (advanced options)",
+       "prefs-advancedsearchoptions": "Progresiva selektaji (advanced options)",
+       "prefs-advancedwatchlist": "Progresiva selektaji (advanced options)",
        "prefs-diffs": "Diferi",
        "userrights-user-editname": "Skribez uzantonomo:",
        "userrights-groupsmember": "Membro di:",
        "right-delete": "Efacar pagini",
        "right-browsearchive": "Serchar pagini efacita",
        "right-suppressrevision": "Vidar, celar e deskovrar specifika revizi di pagini de irga uzero",
+       "right-blockemail": "Blokusar uzero pri sendar e-posto",
        "right-rollback": "Rapide retrorular la redakti da la lasta uzero qua redaktis specigita pagino",
        "newuserlogpage": "Uzero-kreo-registro",
        "rightslog": "Uzero-yuri-registraro",
        "rcfilters-filter-logactions-label": "Agadi enrejistrata",
        "rcnotefrom": "Infre {{PLURAL:$5|esas la chanjo|esas la chanji}} de <strong>$3, $4</strong> (montrata til <strong>$1</strong>).",
        "rclistfrom": "Montrar nova chanji startante de $3 $2",
-       "rcshowhideminor": "$1 mikra redakti",
+       "rcshowhideminor": "$1 mikra redakturi",
        "rcshowhideminor-show": "Montrar",
        "rcshowhideminor-hide": "Celar",
        "rcshowhidebots": "$1 roboti",
        "recentchangeslinked-summary": "Skribez la nomo di ula pagino por vidar la modifiki en pagini ligita ad ol. (Por vidar la membri di ula kategoriio, skribez Kategorio:Nomo di la kategorio). Chanji en la pagini qui esas en [[Special:Watchlist|vua surveryo-listo]] aparas en <strong>dika literi</strong>.",
        "recentchangeslinked-page": "Nomo di la pagino:",
        "recentchangeslinked-to": "Montrez chanji a pagini ligita a la specigita pagino vice",
+       "autochange-username": "Automatala chanjo di MediaWiki",
        "upload": "Adkargar arkivo",
        "uploadbtn": "Adkargar arkivo",
        "reuploaddesc": "Retrovenar al adkargo-formularo.",
        "ignorewarning": "Ignorar la averto e gardar la arkivo irgakaze.",
        "badfilename": "La imajo-nomo chanjesis a \"$1\".",
        "fileexists": "Arkivo kun ta nomo ja existas.\nVolutez kontrolar <strong>[[:$1]]</strong> se {{GENDER:|vu}} ne esas certa pri chanjar olu.\n[[$1|thumb]]",
+       "filepageexists": "La pagino kun deskripto pri ica arkivo ja kreesis en <strong>[[:$1]]</strong>, tamen nul arkivo kun ica nomo existas ankore.\nLa rezumo pri ol quon vu skriptis ne aparos en la deskripto-pagino.\nPor ke la rezumo aparos ibe, vu mustos <strong>skribor ol manuale.</strong>\n[[$1|thumb]]",
        "uploadwarning": "Averto pri la adkargo di arkivo",
        "savefile": "Registragar arkivo",
        "uploaddisabled": "Pardonez, la adkargo esas desaktiva.",
        "unwatchthispage": "Ne plus surveyar",
        "notanarticle": "Ne esas artiklo",
        "watchlist-details": "{{PLURAL:$1|$1 pagino esas|$1 pagini esas }} en vua surveyo-listo (inkluzite diskuto-pagini).",
+       "wlheader-enotif": "L'informo per e-posto esas funcionanta.",
        "wlheader-showupdated": "Pagini qui modifikesis pos vua lasta vizito montresas en <strong>dika literi</strong>.",
-       "wlnote": "Yen la maxim recenta {{PLURAL:$1|chanjo|<strong>$1</strong> chanji}} dum la lasta {{PLURAL:$2|horo|<strong>$2</strong> hori}}, desde $3,$4.",
+       "wlnote": "Yen la maxim recenta {{PLURAL:$1|chanjo|<strong>$1</strong> chanji}} dum la lasta {{PLURAL:$2|horo|<strong>$2</strong> hori}}, de $3,$4.",
        "wlshowlast": "Montrez la lasta $1 hori $2 dii",
+       "wlshowhideminor": "mikra redakturi",
+       "wlshowhidebots": "Roboti (bots)",
+       "wlshowhideliu": "Uzeri enrejistrita",
+       "wlshowhideanons": "anonima uzeri",
+       "wlshowhidemine": "Mea redakturi",
        "watchlist-options": "Surveryo-listo selekti",
        "watching": "Surveyanta…",
        "unwatching": "Cesanta surveyar…",
        "undeletepage": "Vidar e restaurar efacita pagini",
        "undeletepagetext": "La sequanta {{PLURAL:$1|pagino|pagini}} efacesis ma {{PLURAL:$1|ol|li}} ankore esas en la arkivo ed esas restaurebla. La arkivo povas netigesar periodale.",
        "undeleterevisions": "$1 {{PLURAL:$1|revizo|revizi}} efacita",
+       "undeletehistory": "Se vu restauros la pagino, omna antea revizi restauresos en la korespondanta historiala pagino.\nSe nova pagino kun la sama titulo kreesis pos l'efaco, la restaurita revizuri aparos en lua historiala pagino.",
        "undeletebtn": "Restaurar",
        "undeletelink": "vidar/restaurar",
        "undeleteviewlink": "videz",
        "whatlinkshere-hidelinks": "$1 ligili",
        "whatlinkshere-hideimages": "$1 arkivo-ligili",
        "whatlinkshere-filters": "Filtrili",
+       "block": "Blokusar uzero",
        "blockip": "Blokusado di IP-adresi",
        "ipaddressorusername": "IP-adreso od uzantonomo:",
        "ipbexpiry": "Expiro:",
        "ipbreason": "Motivo:",
        "ipbreason-dropdown": "*Ordinara motivi por blokuso\n** Insertar nevera informi\n** Efacar kontenajo de pagini\n** Insertadar ligili ad extera reti\n** Insertar radoto aden pagini\n** Timidiganta ago\n** Trouzar multa konti\n** Neaceptebla uzeronomo",
+       "ipb-hardblock": "Impedar redakturi e modifikuri de uzeri qui facas 'login' de ica IP-adreso",
        "ipbcreateaccount": "Preventez kreo di konti",
+       "ipbemailban": "Impedar l'uzero sendar e-posto",
        "ipbsubmit": "Blokusar ica uzero",
        "ipbother": "Altra tempo:",
        "ipboptions": "2 horo:2 hours,1 dio:1 day,3 dii:3 days,1 semano:1 week,2 semani:2 weeks,1 monato:1 month,3 monati:3 months,6 monati:6 months,1 yaro:1 year,infinita:infinite",
+       "ipbwatchuser": "Vigilar la pagino di prizentado e la pagino di diskuto de ica uzero",
+       "ipb-disableusertalk": "Impedar l'uzero redaktar en lua propra diskutopagino dum la blokuzo",
        "badipaddress": "IP-adreso ne esas valida",
        "blockipsuccesssub": "Blokusado sucesis",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] blokusesis.<br />\nVidez [[Special:BlockList|IP-blokuslisto]] por revizor blokusadi.",
        "move-page-legend": "Rinomizar pagino",
        "movepagetext": "Uzante ica formularo onu povas rinomizar pagino, movante olua omna versionaro ad la nova titulo.\nLa antea titulo konvertesos a ridirektilo a la nova titulo.\nLa ligili a la antea titulo dil pagino ne chanjesos.\nVoluntez certigar ke ne esas [[Special:DoubleRedirects|duopla]] o [[Special:BrokenRedirects|ruptota ridirektili]].\nVu responsas ke la ligili duros direktante a la pagino korespondanta.\n\nMemorez ke la pagino '''ne''' rinomizesos se ja existus pagino kun la nova titulo, eceptuante ke la pagino esas vakua o ridirektilo sen versionaro.\nIco signifikas ke vu povos rinomizar pagino a olua originala titulo se eroras skribante la nova titulo, ma ne povos riskribar existanta pagino.\n\n'''EGARDEZ!'''\nIca povas esar drastika chanjo e ne-esperinda por populara pagino;\nvoluntez certigar ke vu komprenas la konsequi qui eventos ante durar adavane.",
        "movepagetext-noredirectfixer": "Uzar la formulario infre rinomizos la pagino, e tota lua historio-listo a la nova nomo.\nL'anciena titulo ridirektesos a la nova titulo.\nVerifikez la [[Special:DoubleRedirects|duopla]] e/o la [[Special:BrokenRedirects|krevita ridirekti]].\n<strong>Esas vua responso verifikar se omna ligili esas korekta.</strong>\n\nVidez ke la pagino <strong>ne rinomizesos se existar pagino kun la sama titulo</strong>, ecepte se ol ridirektesas a la prezenta pagino e ne havas pasinta historio pri redaktado.\nTo signifikas ke vu povas retroe rinomizar pagino a lua antea nomo se ol rinomizesis erore, e ke vu ne povas supresar existanta pagino per ridirektado di altra pagino.\n\n<strong>Atencez:</strong>\nLa rinomizo povas esar drastika chanjo por pagini qui esas populara;\nhavez klara certezo pri la konsequi di la posibla rinomizo di la pagino, ante facar ol!",
+       "movecategorypage-warning": "<strong>Atencez:</strong> Vu balde rinomizos pagino di \"KATEGORIO\". Nur la titulo di la kategorio chanjesos, ma <em>nula pagino kategoriizita segun l'anciena kategorio</em> modifikesos automatale por la nova kategorio.",
        "movenologintext": "Vu mustas esar registragita uzero ed [[Special:UserLogin|enirir]] por rinomizar pagino.",
        "newtitle": "Nova titulo:",
        "move-watch": "Surveyar ca pagino",
        "movelogpage": "Movo-registraro",
        "movereason": "Motivo:",
        "revertmove": "rekuperar",
+       "delete_and_move_text": "Pagino kun la titulo \"[[:$1]]\" ja existas.\nKa vu dezirus efacar ol, por movor ica pagino ad ita titulo?",
        "delete_and_move_confirm": "Yes, efacez la pagino",
        "delete_and_move_reason": "Efacita por permisar la chanjo di la nomo di la pagino \"[[$1]]\"",
        "move-leave-redirect": "Mantenez ridirektilo inter la du",
        "export-addcat": "Adjuntar",
        "allmessages": "Omna sistemo-mesaji",
        "allmessagesname": "Nomo",
+       "allmessagescurrent": "Nuna texti di mesajo",
        "allmessagestext": "Ico esas listo di omna sistemo-mesaji disponebla en la MediaWiki nomaro.\nVoluntez vizitar [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation MediaWiki Lokizado] e [https://translatewiki.net translatewiki.net] se vu volus kontributar ad generala MediaWiki lokizado.",
        "allmessages-language": "Linguo:",
        "thumbnail-more": "Grandigar",
        "tooltip-diff": "Montrez la chanji a la texto quin vu facis",
        "tooltip-compareselectedversions": "Vidar la diferaji inter la du selektita versioni di ca pagino.",
        "tooltip-watch": "Adjuntar ica pagino a vua listo di surveyaji",
+       "tooltip-watchlistedit-normal-submit": "Removar tituli",
+       "tooltip-watchlistedit-raw-submit": "Aktualigar surveyo-listo",
        "tooltip-recreate": "Rekrear pagino malgre ol efacesis",
        "tooltip-upload": "Adkargar imaji od altra arkivi",
        "tooltip-rollback": "\"Retrorular\" desfacas omna chanji ad ca pagino da la lasta kontributanto per un kliko",
        "autosumm-replace": "Kontenajo remplasigesis kun '$1'",
        "autoredircomment": "Ridirektas a [[$1]]",
        "autosumm-new": "Pagino kreesis kun '$1'",
+       "watchlistedit-normal-legend": "Removar tituli de surveyo-listo",
+       "watchlistedit-normal-explain": "La tituli de vua surveyo-listo montresas adinfre.\nPor removar ula titulo, markizez la buxo proxim ol, e kliktez \"{{int:Watchlistedit-normal-submit}}\".\nVu anke povas [[Special:EditWatchlist/raw|redaktar direkte la 'kruda' listo]].",
+       "watchlistedit-normal-submit": "Removar tituli",
+       "watchlistedit-normal-done": "{{PLURAL:$1|Singla titulo|$1 tituli}} removesis de vua surveyo-listo:",
        "watchlistedit-raw-title": "Redaktar texto di surveyo-listo",
        "watchlistedit-raw-legend": "Redaktar texto di surveyo-listo",
+       "watchlistedit-raw-explain": "Tituli en vua surveyo-listo montresas adinfre, e povas modifikesar per adjuntado od eskarto de la listo; nur un titulo per lineo.\nKande vu finos, kliktez \"{{int:Watchlistedit-raw-submit}}\".\nVu anke povas [[Special:EditWatchlist|uzar la redaktero ordinara ('standard')]].",
        "watchlistedit-raw-titles": "Tituli:",
+       "watchlistedit-raw-submit": "Aktualigar surveyo-listo",
+       "watchlistedit-too-many": "Esas multa pagini por montrar hike.",
        "watchlisttools-clear": "Vakuigar la surveyo-listo",
        "watchlisttools-view": "Vidar relatanta chanji",
        "watchlisttools-edit": "Vidar e redaktar surveyo-listo",
        "version": "Versiono",
        "version-specialpages": "Specala pagini",
        "version-other": "Altra",
+       "version-parser-function-hooks": "Funcioni \"hooks\" dil sintaxal analizilo (parser)",
        "version-version": "($1)",
        "version-license": "MediaWiki Licenco",
        "version-software-product": "Produkturo",
        "searchsuggest-containing": "quan kontenas...",
        "duration-days": "($1 {{PLURAL:$1|dio|dii}})",
        "duration-years": "$1 {{PLURAL:$1|yaro|yari}}",
+       "limitreport-title": "Analizo di dati pri profilo:",
+       "limitreport-ppvisitednodes": "Quanto di nodi vizitita dal preprocesoro",
+       "limitreport-postexpandincludesize": "Grandeso dil inkluzo pos expanso",
+       "limitreport-expansiondepth": "Maxima profundeso di expanso",
+       "limitreport-expensivefunctioncount": "Kontado di funcioni kustoza di analizo sintaxala",
        "expand_templates_output": "Rezulto",
        "expand_templates_ok": "O.K.",
        "expand_templates_preview": "Previdar",
        "special-characters-group-persian": "Persiana",
        "mw-widgets-dateinput-no-date": "Nula dato selektita",
        "mw-widgets-dateinput-placeholder-day": "YYYY-MM-DD",
+       "mw-widgets-titleinput-description-redirect": "Ridirektar ad $1",
        "sessionprovider-nocookies": "''Bisquiti'' forsan esas desacendita. Certigez ke vu acendar ''bisquiti'' e riprobez.",
        "randomrootpage": "Hazarda radikopagino",
        "log-action-filter-delete": "Tipo di efacado:"
index f92e8a7..b5403a5 100644 (file)
@@ -79,7 +79,7 @@
        "tog-hidecategorization": "페이지 분류 숨기기",
        "tog-extendwatchlist": "주시문서 목록에서 가장 최근의 편집만이 아닌 모든 편집을 보기",
        "tog-usenewrc": "최근 바뀜과 주시문서 목록의 문서별 그룹 바뀜",
-       "tog-numberheadings": "ì\9e\90ë\8f\99ì\9c¼ë¡\9c ë¨¸ë¦¿글 번호 매기기",
+       "tog-numberheadings": "ì\9e\90ë\8f\99ì\9c¼ë¡\9c ë¨¸ë¦¬글 번호 매기기",
        "tog-showtoolbar": "편집 도구 모음 보이기",
        "tog-editondblclick": "더블 클릭으로 문서 편집하기",
        "tog-editsectiononrightclick": "문단 제목을 오른쪽 클릭해서 문단 편집하기 활성화",
        "recentchanges-label-minor": "사소한 편집",
        "recentchanges-label-bot": "봇이 수행한 편집",
        "recentchanges-label-unpatrolled": "아직 점검하지 않은 편집",
-       "recentchanges-label-plusminus": "ë°\94ì\9d´í\8a¸ ì\88\98ë³\84 문서 크기의 차이",
+       "recentchanges-label-plusminus": "ë°\94ì\9d´í\8a¸ ì\88\98ë¡\9c í\91\9cí\98\84í\95\9c 문서 크기의 차이",
        "recentchanges-legend-heading": "<strong>범례:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|새 문서 목록]]도 보세요)",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "filehist-user": "사용자",
        "filehist-dimensions": "크기",
        "filehist-filesize": "파일 크기",
-       "filehist-comment": "댓글",
+       "filehist-comment": "설명",
        "imagelinks": "이 파일을 사용하는 문서",
        "linkstoimage": "다음 {{PLURAL:$1|문서 $1개}}가 이 파일을 가리키고 있습니다:",
        "linkstoimage-more": "$1개 이상의 {{PLURAL:$1|문서}}가 이 파일을 가리키고 있습니다.\n다음 목록은 이 파일을 {{PLURAL:$1|가리키는 처음 문서 $1개}}만 보여주고 있습니다.\n이 파일을 가리키는 [[Special:WhatLinksHere/$2|모든 문서 목록]]을 볼 수 있습니다.",
        "prefixindex-namespace": "접두어가 있는 모든 문서 ($1 이름공간)",
        "prefixindex-submit": "보이기",
        "prefixindex-strip": "목록에서 접두어 생략",
-       "shortpages": "은 문서 목록",
-       "longpages": " 문서 목록",
+       "shortpages": "내용이 적은 문서 목록",
+       "longpages": "내용이 많은 문서 목록",
        "deadendpages": "막다른 문서 목록",
        "deadendpagestext": "{{SITENAME}} 내의 다른 문서로 나가는 링크가 없는 문서의 목록입니다.",
        "protectedpages": "보호된 문서 목록",
        "ancientpages": "오래된 문서 목록",
        "move": "이동",
        "movethispage": "이 문서 이동하기",
-       "unusedimagestext": "다음은 어떠한 문서도 사용하지 않는 파일의 목록입니다.\n다른 사이트에서 URL 접근을 통해 파일을 사용할 수 있기 때문에, 아래 목록에 있는 파일도 실제로 사용 중일 가능성이 있다는 점을 주의해주세요.",
+       "unusedimagestext": "다음은 어떠한 문서에서도 사용하지 않는 파일의 목록입니다.\n다른 사이트에서 URL 접근을 통해 파일을 사용할 수 있기 때문에, 아래 목록에 있는 파일도 실제로 사용 중일 가능성이 있다는 점을 주의해주세요.",
        "unusedcategoriestext": "사용하지 않는 분류 문서의 목록입니다.",
        "notargettitle": "해당하는 문서 없음",
        "notargettext": "기능을 수행할 대상 문서나 사용자를 지정하지 않았습니다.",
        "allpagesbadtitle": "주어진 문서 제목이 잘못되었거나 다른 사이트로 연결되는 인터위키가 있습니다.\n문서 제목에 사용할 수 없는 문자를 사용했을 수 있습니다.",
        "allpages-bad-ns": "{{SITENAME}}에서는 \"$1\" 이름공간을 사용하지 않습니다.",
        "allpages-hide-redirects": "넘겨주기 숨기기",
-       "cachedspecial-viewing-cached-ttl": "ì\9d´ ë¬¸ì\84\9cì\9d\98 ìº\90ì\8b\9cë\90\9c í\8c\90ì\9d\84 ë³´ê³  ì\9e\88ì\9c¼ë©°, ìµ\9cë\8c\80 $1ë§\8cí\81¼ ì§\80ë\82\9c í\8c\90ì\9d¼ ì\88\98 ì\9d¼ ì\88\98 ì\9e\88ì\8aµë\8b\88ë\8b¤.",
+       "cachedspecial-viewing-cached-ttl": "이 문서의 캐시된 판을 보고 있으며, 최대 $1만큼 지난 판일 수 있습니다.",
        "cachedspecial-viewing-cached-ts": "현재 이 문서는 캐시 처리된 버전으로 현재 문서 상태를 반영하지 않을 수도 있습니다.",
        "cachedspecial-refresh-now": "최신판을 봅니다.",
        "categories": "분류 목록",
        "listusers-submit": "보기",
        "listusers-noresult": "사용자를 찾을 수 없습니다.",
        "listusers-blocked": "(차단됨)",
-       "activeusers": "활동하는 사용자 목록",
+       "activeusers": "활동 중인 사용자 목록",
        "activeusers-intro": "다음은 최근 $1{{PLURAL:$1|일}} 동안 활동한 사용자의 목록입니다.",
-       "activeusers-count": "마지막 {{PLURAL:$3|$3일}} 사이의 {{PLURAL:$1|활동}} $1회",
+       "activeusers-count": "최근 {{PLURAL:$3|$3일}} 사이의 {{PLURAL:$1|활동}} $1회",
        "activeusers-from": "다음으로 시작하는 사용자 표시:",
        "activeusers-groups": "그룹에 속한 사용자 표시:",
        "activeusers-excludegroups": "그룹에 속한 사용자 제외:",
index 2647c86..a07841e 100644 (file)
        "nextrevision": "Guhertoya nûtir →",
        "currentrevisionlink": "Guhertoya niha nîşan bide",
        "cur": "cudahî",
-       "next": "pêş",
+       "next": "pêşve",
        "last": "berê",
        "page_first": "ya pêşîn",
        "page_last": "ya paşîn",
        "textmatches": "Dîtinên di nivîsara rûpelan de",
        "notextmatches": "Di nav sernivîsan de nehat dîtin.",
        "prevn": "{{PLURAL:$1|$1}} paş",
-       "nextn": "{{PLURAL:$1|$1}} pêş",
+       "nextn": "{{PLURAL:$1|$1}} pêşve",
        "prev-page": "rûpela berî vê",
        "next-page": "rûpela pêş",
        "prevn-title": "{{PLURAL:$1|result|Encamên}} pêştir $1",
        "tag-filter": "Parzûna [[Special:Tags|nîşankirinê]]:",
        "tag-filter-submit": "Parzûn",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etîket}}]]: $2)",
+       "tag-mw-undo": "Betal bike",
        "tags-title": "Nîşankirin",
        "tags-tag": "Navê etîketê",
        "tags-active-header": "Çalak?",
index 61cdc9e..1038a88 100644 (file)
        "go": "Vanni",
        "searcharticle": "Vanni",
        "history": "Cronologîa da pàgina",
-       "history_short": "Stöia",
-       "history_small": "Stoia",
+       "history_short": "Cronologîa",
+       "history_small": "Cronologîa",
        "updatedmarker": "modificâ da-a mæ urtima vixita",
        "printableversion": "Verscion da stanpâ",
        "permalink": "Ingancio fisso",
        "badaccess-groups": "L'assion che ti vêu fâ a l'è permissa solo a i ûtenti {{PLURAL:$2|do gruppo|de un de sti gruppi}}: $1.",
        "versionrequired": "Ghe voeu a verscion $1 de MediaWiki",
        "versionrequiredtext": "Pe deuviâ sta pagina ghe veu a versción $1 do software MediaWiki. Amîa [[Special:Version|l'appoxita paggina]].",
-       "ok": "D'accòrdio",
+       "ok": "OK",
        "retrievedfrom": "Estræto da \"$1\"",
        "youhavenewmessages": "Ti gh'æ $1 ($2).",
        "youhavenewmessagesfromusers": "Ti g'hæ $1 da {{PLURAL:$3|un atro utente|$3 utenti}} ($2).",
        "rcfilters-hideminor-conflicts-typeofchange-global": "O filtro \"Modiffiche minoî\" o l'è in confito con un ò ciu filtri \"Tipo de modiffica\", percose çerte modiffiche no poeuan ese indicæ comme \"minoî\". I filtri in conflito son indicæ inte l'area \"Filtri attivi\" chì de d'ato.",
        "rcfilters-hideminor-conflicts-typeofchange": "Gh'è di tipi de modiffiche che no poeuan ese indicæ comme \"minoî\", quindi questo filtro o l'è in conflito co-i seguenti filtri \"Tipo de modiffica\": $1",
        "rcfilters-typeofchange-conflicts-hideminor": "Questo filtro \"Tipo di modifica\" o l'è in conflito co-o  filtro \"Modiffiche minoî\". Çerti tipi de modiffiche no poeuan ese indicæ comme \"minoî\".",
-       "rcfilters-filtergroup-lastRevision": "Urtima revixon",
+       "rcfilters-filtergroup-lastRevision": "Ùrtime verscioìn",
        "rcfilters-filter-lastrevision-label": "Urtima revixon",
        "rcfilters-filter-lastrevision-description": "Solo e modiffiche ciu recenti a 'na pagina.",
        "rcfilters-filter-previousrevision-label": "No l'urtima versción",
        "api-error-emptypage": "A creaçion de noeuve pagine voeue a no l'è consentia.",
        "api-error-publishfailed": "Errô interno: o server o no l'è ariescio a pubbricâ o documento temporannio.",
        "api-error-stashfailed": "Errô interno: o server o no l'è ariescio a memorizzâ o documento temporannio.",
-       "api-error-unknown-warning": "Avviso sconosciuo: $1",
+       "api-error-unknown-warning": "Avertiménto sconosciûo: \"$1\".",
        "api-error-unknownerror": "Errô sconosciuo: \"$1\"",
        "duration-seconds": "$1 {{PLURAL:$1|segondo|segondi}}",
        "duration-minutes": "$1 {{PLURAL:$1|menuto|menuti}}",
index 002ed6e..0b7578a 100644 (file)
        "monday": "دۏشٱمٱ",
        "tuesday": "ساٛشمٱ",
        "wednesday": "چارشأمە",
-       "thursday": "پأن شأمە",
+       "thursday": "پن شمٱ",
        "friday": "جومٱ",
        "saturday": "شٱمٱ",
-       "sun": "یئ شأمە",
+       "sun": "یٱشمٱ",
        "mon": "دۊشأمە",
        "tue": "ساٛشمٱ",
-       "wed": "چارشأمە",
-       "thu": "پأن شأمە",
+       "wed": "چارشمٱ",
+       "thu": "پٱن شمٱ",
        "fri": "جومە",
        "sat": "شأمە",
        "january": "جانڤیٱ",
@@ -88,7 +88,7 @@
        "november": "نوڤامر",
        "december": "داٛسامر",
        "january-gen": "جانڤیە",
-       "february-gen": "فۋریٱ",
+       "february-gen": "فڤریٱ",
        "march-gen": "مارس",
        "april-gen": "آڤریل",
        "may-gen": "مئی",
        "about": "دئبارە",
        "article": "مینوٙنە یا بألگە",
        "newwindow": "(د یئ گئل نیمدأری تازە ڤاش کو)",
-       "cancel": "أنجوم شیڤئسئن",
+       "cancel": "ٱنجوم شیڤسن",
        "moredotdotdot": "بیشتئر",
        "morenotlisted": "ئی نومگە کامئل بییە.",
        "mypage": "بألگە",
-       "mytalk": "چأک چئنە",
+       "mytalk": "چٱک چنٱ",
        "anontalk": "دئبارە تیرنئشوٙن ئی آی پی قئسە بأکیت",
        "navigation": "ناڤجۊری",
        "and": "&#32;و",
        "go": "رو",
        "searcharticle": "رو",
        "history": "ڤیرگار بألگە",
-       "history_short": "ۋیرگار",
+       "history_short": "ڤیرگار",
        "updatedmarker": "د آخئری دییئن مئنە ڤئ هنگوم کو",
        "printableversion": "نوسقٱ پلا بیاٛنی",
        "permalink": "هوم پیڤند همیشٱیی",
        "poolcounter-usage-error": "خأطا ڤئ کار گئرئتئن:$1",
        "aboutsite": "داٛبارٱ {{SITENAME}}",
        "aboutpage": "Project:دبارٱ",
-       "copyright": "مینوٙنە یا هان د دأسرئس $1 مأر یە کئ ڤئ یئ گئل شیڤە هأنی نیسأنە بوٙە.",
+       "copyright": "مینۊنٱیا هان د دٱسرس $1 مٱر یٱ کاٛ ڤ یاٛ گاٛل شیڤاٛ هٱنی نیسٱنٱ بۊٱ.",
        "copyrightpage": "{{ns:project}}:کوپی رایت",
        "currentevents": "روخ ڤنیا ایساٛنی",
        "currentevents-url": "Project:روخ ڤٱنیا ایساٛنی",
        "disclaimers": "تیٱپۊشکاریا",
        "disclaimerpage": "پوروجٱ: تیٱپوشی کردن همٱگیر",
-       "edithelp": "Ù\87Ù\88Ù\85Ù\8aارÛ\8c Ø³Û\8c Ú¤Û\8cراÛ\8cئشت",
+       "edithelp": "هومياری سی ڤیرایشت",
        "helppage-top-gethelp": "هومياری",
        "mainpage": "سرآسۊنٱ",
        "mainpage-description": "سرآسۊنٱ",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "د نۏ زنٱ بیٱ د\"$1\"",
        "youhavenewmessages": "{{PLURAL:$3|شوما داریت}} $1 ($2).",
-       "youhavenewmessagesfromusers": "{{PLURAL:$4|شوما}} $1 د {{PLURAL:$3|کاریار هأنی|$3 کاریاریا}}داریت($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|شوما}} $1 د {{PLURAL:$3|کاریار هٱنی|$3 کاریاریا}}داریت($2).",
        "youhavenewmessagesmanyusers": "شوما د $1 فئرە کاریار داریت($2).",
        "newmessageslinkplural": "{{PLURAL:$1|یئ گئل پئیغوم تازە|999=پئیغومیا تازە}}",
        "newmessagesdifflinkplural": "آخئر {{PLURAL:$1|آلئشت|آلئشتیا}}",
        "sort-descending": "کأم بییئن سأرجاخود",
        "sort-ascending": "زياد بيیئن سأرجادخود",
        "nstab-main": "بلگٱ",
-       "nstab-user": "بألگە کاریار",
+       "nstab-user": "بلگٱ کاریار",
        "nstab-media": "بألگە ڤارئسگأر",
        "nstab-special": "بلگٱیا ۋیجٱ",
        "nstab-project": "بألگە پوروجە",
        "nstab-mediawiki": "پئیغوٙم",
        "nstab-template": "چوٙأ",
        "nstab-help": "بألگە هومیاری",
-       "nstab-category": "دأسە",
+       "nstab-category": "دٱسٱ",
        "mainpage-nstab": "سرآسۊنٱ",
        "nosuchaction": "چئنی کونئشتگأری نییئش",
        "nosuchactiontext": "کاری کئ ڤا یوٙ آر ئل تیار بییە نادیارە.\nگاسی شوما یوٙ آر ئل نە دوروس نأنیسأنیتە، یا یئ گئل هوم پئیڤأند ئشتئڤا ڤارئد بییە.\nڤئ گاسی یئ گئل سیسئریک د نأرم أفزاز ڤئ کار گئرئتە بییە ڤا {{SITENAME}} ئشارە بأکە.",
        "perfcached": "رئسینە یا نئهایی د ڤیرگە قام بییە موٙکیس بینە و گاسی هأنی ڤئ هئنگوم سازی نأبینە.بیشتئروٙنە {{PLURAL:$4|یئ گئل نأتیجە|$4 یئ گئل نأتیجە}} د ڤیرگە قام بییە هان د دأسرئس.",
        "perfcachedts": "رئسینە یا نئهایی د ڤیرگە قام بییە موٙکیس بینە و گاسی هأنی ڤئ هئنگوم سازی نأبینە.بیشتئروٙنە {{PLURAL:$4|یئ گئل نأتیجە|$4 یئ گئل نأتیجە}} د ڤیرگە قام بییە هان د دأسرئس.",
        "querypage-no-updates": "نأبوٙە ئی بألگە ڤئ هئنگوم سازی با.\nرئسینە یا ئیچئ تازە کاری نأبینە.",
-       "viewsource": "سئÛ\8cÙ\84 Ø¯ Ø³Ø£Ø±Ú\86ئشÙ\85Û\95 Ø¨Ø£کیت",
+       "viewsource": "ساÙ\9bÛ\8cÙ\84 Ø¯ Ø³Ø±Ú\86Ø´Ù\85Ù± Ø¨Ù±کیت",
        "viewsource-title": "سئیل د سأرچئشمە $1 بأکیت",
        "actionthrottled": "کونئشتکاری نئهاگئری بییە",
        "actionthrottledtext": "سی نئهاگئری د دأرتیچ بییئن ئسپأم نأبوٙە کئ شوما چئنی کاری نە د یئ گاتی کوٙتا چأن گئل أنجوم بئییت.\nلوطف بأکیت د چأن دئیقە هأنی د نۊ تئلاش بأکیت.",
        "createacct-yourpassword-ph": "رازینە گوڤاردئن نە بأزە",
        "yourpasswordagain": "یئ گئل هأنی رازینە گوڤاردئن نە بأزە",
        "createacct-yourpasswordagain": "رازینە گوڤاردئن نە پوشت راس کو",
-       "createacct-yourpasswordagain-ph": "Û\8cئ Ú¯Ø¦Ù\84 Ù\87Ø£Ù\86Û\8c Ø±Ø§Ø²Û\8cÙ\86Û\95 Ú¯Ù\88ڤاردئÙ\86 Ù\86Û\95 Ø¨Ø£Ø²Û\95",
+       "createacct-yourpasswordagain-ph": "Û\8cاÙ\9b Ú¯Ø§Ù\9bÙ\84 Ù\87Ù±Ù\86Û\8c Ø±Ø§Ø²Û\8cÙ\86Ù± Ú¯Ù\88ڤاردÙ\86 Ø¨Ù±Ø²Ù±",
        "userlogin-remembermypassword": "مئنە د ساموٙنە ڤادار",
        "userlogin-signwithsecure": "ڤأصل بییئن أمن نە ڤئ کار بئیر",
        "yourdomainname": "پوشگئر شوما:",
        "password-change-forbidden": "شوما نئمی توٙنیت رازینە گوڤاردئن خوتوٙنە د ئی ڤیکی آلئشت بأکیت.",
        "externaldberror": "ئشتئڤایی د ئرتئڤاط ڤا رئسینە گا پیش ئوٙماە یا شوما صئلا یأنە کئ یئ گئل حئساڤ خارجی خوتوٙنە ڤئ هئنگوم سازی بأکیت ناریت.",
-       "login": "ڤاÙ\85Û\8cÙ\86 Ø¦Ù\88Ù\99مائن",
+       "login": "ڤاÙ\85Û\8cÙ\86 Ø§Û\8aمائن",
        "nav-login-createaccount": " ڤامین ئوٙمائن/راس کئردئن حئساڤ",
        "logout": "د ساموٙنە دئرئوٙمائن",
        "userlogout": "د ساموٙنە دئرئوٙمائن",
        "login-throttled": "شوما تا ئیسئ سی ڤامین ئوٙمائن فئرە تئلاش کئردیتە.\n$1 لوطف بأکیت سی تئلاش هأنی گوری بئسیت.",
        "login-abort-generic": "ڤامین ئوٙمائن توٙ ناخوش سأرنجوم بی- گأن بی",
        "login-migrated-generic": "حئساڤ کاریاری شوما جا ڤئ جا بییە، و نوم کاریاری شوما دە د ئی ڤیکی نیئش.",
-       "loginlanguagelabel": "زوٙن:$1",
+       "loginlanguagelabel": "زۊن:$1",
        "suspicious-userlogout": "د حاست ڤئ دأر رأتئن شوما تیە پوشی بییە سی یە کئ ڤئ نأظأر یما کئ ڤئ سی یئ گئل دوڤارتە نیأر گأن یا یئ گئل پوروکسی کئ ها د ڤیرگە کأش کئل بییە.",
        "createacct-another-realname-tip": "نوم راستأکی دئل ڤئ حاییە.\nأر شوما ڤئنە نئها ئمایە بأکیت، یە سی هوم نئسبأت دأئن کاریاری سی کاریاش ڤئ کار گئرئتئ بوٙە.",
        "pt-login": "ڤامین اۊمائن",
        "pt-login-button": "ڤامین ئوٙمائن",
        "pt-createaccount": "هساڤ راست بکیت",
-       "pt-userlogout": "د ساموٙنە دئرئوٙمائن",
+       "pt-userlogout": "د سامۊنٱ دراۊمائن",
        "php-mail-error-unknown": "خأطا نادیار د آلئشتگئر PHP's mail()",
        "user-mail-no-addy": "سی کئل کئردئن أنجومانامە د یئ گئل أنجومانامە بی تیرنئشوٙن أنجومانامه تئلاش بییە.",
        "user-mail-no-body": "سی کئل کئردئن أنجومانامە ڤا مینوٙنە حالی یا کوچئک بییئن سی دألیل یا غئر مأنطئقی بییئن ڤئ تئلاش بأکیت.",
        "bold_tip": "نیسئسە توٙپور",
        "italic_sample": "نیسئسە کأج و کولە",
        "italic_tip": "نیسئسە یا کأج و کولە",
-       "link_sample": "داسوٙن هوم پئیڤأند",
-       "link_tip": "هوم پئیڤأند مینجایی",
+       "link_sample": "داسوٙن هوم پیڤند",
+       "link_tip": "هوم پیڤند مینجایی",
        "extlink_sample": "http://www.example.com داسوٙن هوم پئیڤأند",
        "extlink_tip": "هوم پئیڤأند خارئجی(د ڤیر داشتوٙئیت)",
        "headline_sample": "سأرخأط نیسئسە",
        "headline_tip": "ریتئراز 2 خأط سأرڤأن",
-       "nowiki_sample": "د Ø¦Û\8cÚ\86ئ Û\8cئ Ú¯Ø¦Ù\84 Ù\86Û\8cسئسÛ\95 Ø¨Û\8c Ø´Ø¦Ú©Ù\84 Ú¤Ø§Ø±Ø¦Ø¯ Ø¨Ø£Ú©Û\8cت.",
-       "nowiki_tip": "د شئکل ڤیکی تیە پوٙشی بأک",
+       "nowiki_sample": "د Ø§Û\8cÚ\86اÙ\9b Û\8cاÙ\9b Ú¯Ø§Ù\9bÙ\84 Ù\86Û\8cسسٱ Ú¤Ø§Ø±Ø¯ Ø¨Ù±Ú©Û\8cت",
+       "nowiki_tip": "د شکل ڤیکی تیٱپۊشی بٱک",
        "image_sample": "Example.jpg",
        "image_tip": "جانیا چار قئر گئرئتە",
        "media_sample": "Example.ogg",
-       "media_tip": "جانیا هوم پئیڤأند",
-       "sig_tip": "ئÙ\85ضا شوما ڤا گاتدیس",
+       "media_tip": "جانیا هوم پیڤند",
+       "sig_tip": "اÙ\9bÙ\85زا شوما ڤا گاتدیس",
        "hr_tip": "خأط آسوٙ ڤأنە(جئگا جئگا ڤئ کار گئرئتئن)",
-       "summary": "چئکئسە",
+       "summary": "چکسٱ",
        "subject": "ذاسوٙن/سأرتال:",
        "minoredit": "یٱ یاٛ گاٛل ڤیرایشت کوچکٱ",
-       "watchthis": "دÛ\8cئÙ\86 Ø¦Û\8c Ø¨Ø£Ù\84Ú¯Û\95",
+       "watchthis": "دÛ\8cاÙ\9bÙ\86 Ø§Û\8c Ø¨Ù\84Ú¯Ù±",
        "savearticle": "اٛمایٱ کردن بلگٱ",
        "preview": "پيش سئيل",
-       "showpreview": "Ù\86ئشÙ\88Ù\99 Ø¯Ø£Ø¦Ù\86 Ù¾Û\8cØ´ Ø³Ø¦یل",
-       "showdiff": "Ù\86ئشÙ\88Ù\99 Ø¯Ø£Ø¦Ù\86 Ø¢Ù\84ئشت کاریا",
+       "showpreview": "Ù\86Ø´Û\8a Ø¯Ù±Ø¦Ù\86 Ù¾Û\8cØ´ Ø³Ø§Ù\9bیل",
+       "showdiff": "Ù\86Ø´Û\8a Ø¯Ù±Ø¦Ù\86 Ø¢Ù\84شتکاریا",
        "blankarticle": "<strong>زنئار:</strong> بلگه ای که شما دروس کردیته حالیه.\nار شما د نو ری \"$1\" بپورنیت, بلگه وه شکل که هیچ مینونه ای دش نبا دروس بوئه.",
-       "anoneditwarning": "<strong>زئÙ\86ار:</strong> Ø´Ù\88Ù\85ا Ù\87Ø£Ù\86Û\8c Ù\86Û\8cÙ\88Ù\99Ù\85اÛ\8cتÛ\95 Ú¤Ø§Ù\85Û\8cÙ\86. ØªÛ\8cرÙ\86ئشÙ\88Ù\99Ù\86 Ø¢Û\8c Ù¾Û\8c Ø´Ù\88Ù\85ا Ø³Û\8c Ù\87أر Ú¯Ø§ØªÛ\8c Ú©Ø¦ Ø¢Ù\84ئشتکارÛ\8c Ø¨Ø£Ú©Û\8cت Ø³Û\8c Ú©Ù\88Ù\84 Ø®Ø£Ù\84Ú© Ø¯Û\8cارÛ\8c Ù\85Û\8c Ú©Û\95. Ø£Ø± <strong>[$1 Ø±Ù\88ئÛ\8cت Ú¤Ø§Ù\85Û\8cÙ\86]</strong> Û\8cا <strong>[$2 Û\8cئ Ú¯Ø¦Ù\84 Ø­Ø¦Ø³Ø§Ú¤ Ú©Ø§Ø±Û\8cارÛ\8c Ø±Ø§Ø³ Ø¨Ø£Ú©Û\8cت]</strong>Ø\8c Ú¤Û\8cراÛ\8cئشتÛ\8cا Ø´Ù\88Ù\85ا Ú¤Ø¦ Ù\86Ù\88Ù\85 Ú©Ø§Ø±Û\8cارÛ\8c Ø®Ù\88تÙ\88Ù\99 Ø¯Û\8cارÛ\8c Ù\85Û\8c Ú©Û\95 Ù\88 Ø³Û\8c Ø´Ù\88Ù\85ا Ø¨Û\8cتأرÛ\95.",
+       "anoneditwarning": "<strong>زاÙ\9bÙ\86ار:</strong> Ø´Ù\88Ù\85ا Ù\87Ù±Ù\86Û\8c Ù\86Û\8cÛ\8aÙ\85اÛ\8cتٱ Ú¤Ø§Ù\85Û\8cÙ\86. ØªÛ\8cرÙ\86Ø´Û\8aÙ\86 Ø¢Û\8c Ù¾Û\8c Ø´Ù\88Ù\85ا Ø³Û\8c Ù\87ر Ú¯Ø§ØªÛ\8c Ú©Ø§Ù\9b Ø¢Ù\84شتکارÛ\8c Ø¨Ù±Ú©Û\8cت Ø³Û\8c Ú©Ù\88Ù\84 Ø®Ù±Ù\84Ú© Ø¯Û\8cارÛ\8c Ù\85Û\8c Ú©Ù±. Ù±Ø± <strong>[$1 Ø±Ù\88ئÛ\8cت Ú¤Ø§Ù\85Û\8cÙ\86]</strong> Û\8cا <strong>[$2 Û\8cاÙ\9b Ú¯Ø§Ù\9bÙ\84 Ù\87ساڤ Ú©Ø§Ø±Û\8cارÛ\8c Ø±Ø§Ø³ Ø¨Ù±Ú©Û\8cت]</strong>Ø\8c Ú¤Û\8cراÛ\8cشتÛ\8cا Ø´Ù\88Ù\85ا Ú¤ Ù\86Ù\88Ù\85 Ú©Ø§Ø±Û\8cارÛ\8c Ø®Ù\88تÛ\8a Ø¯Û\8cارÛ\8c Ù\85Û\8c Ú©Ù± Ù\88 Ø³Û\8c Ø´Ù\88Ù\85ا Ø¨Û\8cترٱ.",
        "anonpreviewwarning": "<em>شوما نیوٙمایتە ڤامین. تیرنئشوٙن آی پی شوما د ڤیرگار ڤیرایئشت ئی بألگە ئمایە بوٙە.</em>",
        "missingsummary": "<strong>ڤیر دیارکو:</strong> شوما هأنی یئ گئل چئکئسە ڤیرایئشتی نە نئها ئمایە کاری نأکئردیتە.\nأر شوما د نۊ د ری \"$1\" بأپوٙرنیت، ڤیرایئشت کاری شوما حالی ئمایە بوٙە.",
        "selfredirect": "<strong>هوشدار:</strong> شوما د حال و بال ڤاگأردوٙنی ئی بألگە د خوش هیین.\nگاسی دال ئشتئڤایی سی ڤاگأردوٙنی ئنتئخاڤ کئردیتە، یا گاسی بألگە نە ئشتئڤایی ڤیرایئشت کاری می کیت.\nأر ری \"$1\" دۊ گئل بأپوٙرنیت، ڤاگأردوٙنی راس موٙە.",
        "subject-preview": "داسوٙن/پیش سئیل سأرخأط:",
        "previewerrortext": "یئ گئل خأطا د گاتی کئ شوما میهاستیت یئ گئل پیش سئل د آلئشتیاتوٙ داشتوٙین پیش ئوٙماە.",
        "blockedtitle": "کاریار نئهاگئری بی",
-       "blockedtext": "<strong>Ù\86Ù\88Ù\85 Ú©Ø§Ø±Û\8cارÛ\8c Ø´Ù\88Ù\85ا Û\8cا ØªÛ\8cرÙ\86ئشÙ\88Ù\99Ù\86 Ø¢Û\8c Ù¾Û\8c Ø´Ù\88Ù\85ا Ù\86ئÙ\87اگئرÛ\8c Ø¨Û\8cÛ\8cÛ\95.</strong>\n\n\n$1 Ú¤Ø¦Ù\86Û\95 Ù\86ئÙ\87اگئرÛ\8c Ú©Ø¦Ø±Ø¯Û\95.\nدأÙ\84Û\8cÙ\84ئش Ù\87ا Ø¯ Ø¦Û\8cÚ\86ئ<em>$2</em>.\n\nØ´Ù\88رÙ\88Ù\99 Ø¯ Ù\86ئÙ\87اگئرÛ\8c:$8\nآخئر Ù\86ئÙ\87اگئرÛ\8c:$6\nکارÛ\8cارÛ\8c Ú©Ø¦ Ù\87ا Ú¤Ø£Ø±ØªÛ\8cÛ\95 Ù\88 Ù\86ئÙ\87اگئرÛ\8c Ø¨Û\8cÛ\8cÛ\95:$7\n\nØ´Ù\88Ù\85ا Ù\85Û\8c ØªÙ\88Ù\99Ù\86Û\8cت Ú¤Ø§ $1 Û\8cا [[{{MediaWiki:Grouppage-sysop}}|سأردÛ\8cÚ¤Ù\88Ù\99Ù\86کار]] Ù\87Ø£Ù\86Û\8c Ù¾Ø¦Û\8cڤأÙ\86د Ø¨Ø¦Û\8cرÛ\8cت Ù\88 Ø³Û\8c Ù\86ئÙ\87اگئرÛ\8c Ú¤Ø§ Ú¤Ø¦ Ú\86Ø£Ú© Ú\86ئÙ\86Û\95 Ú©Ø§Ø±Û\8c Ø¨Ø£Ú©Û\8cت.\nØ£Ù\84ڤأت Ø¯ Ú¤Û\8cر Ø¯Ø§Ø´ØªÙ\88Ù\99ئÛ\8cت Ú©Ø¦ Ø´Ù\88Ù\85ا Ù\86ئÙ\85Û\8c ØªÙ\88Ù\99Ù\86Û\8cت Ø®Ù\88صÛ\89صÛ\8cأت Ø£Ù\86جÙ\88Ù\85اÙ\86اÙ\85Û\95 Ú©Ø¦Ù\84 Ú©Ø¦Ø±Ø¯Ø¦Ù\86 Ø³Û\8c Ø¦Û\8c Ú©Ø§Ø±Û\8cار Ù\86Û\95 Ú¤Ø¦ Ú©Ø§Ø± Ø¨Ø¦Û\8cرÛ\8cتØ\8c Ù\85أر Û\8cÛ\95 Ú©Ø¦ Û\8cئ Ú¯Ø¦Ù\84 ØªÛ\8cرÙ\86ئشÙ\88Ù\99Ù\86 Ø£Ù\86جÙ\88Ù\85اÙ\86اÙ\85Û\95 Ù\86ازار Ù\86Û\95 [[Special:Preferences|تأرجÛ\8cحات Ú©Ø§Ø±Û\8cارÛ\8c]] Ø®Ù\88تÙ\88Ù\99 Ø¯Û\8cارÛ\8c Ú©Ø¦Ø±Ø¯Ø¦Ù\88Ù\99Û\8cت Ù\88 ØªÙ\88Ù\99Ù\86ئستÙ\88Ù\99Û\8cت Ú¤Ø¦ Ù\86Û\95 Ú¤Ø¦ Ú©Ø§Ø± Ø¨Ø¦Û\8cرÛ\8cت .\nتÛ\8cرÙ\86ئشÙ\88Ù\99Ù\86 Ø¢Û\8c Ù¾Û\8c Ø¦Û\8cسئÙ\86Û\8c Ø´Ù\88Ù\85ا $3Û\95Ø\8c Ù\88 Ù\86Ù\88Ù\85 Ø¯Û\8cارکÙ\88Ù\86 Ù\86ئÙ\87اگئرÛ\8c #$5 Û\95.\nÙ\84Ù\88Ø·Ù\81 Ø¨Ø£Ú©Û\8cت Ù\87Ø£Ù\85Û\95 Ú\86Û\8cاÙ\86Û\95 Ø¯ Ù\87أر Ø­Ø§Ø³ØªÛ\95 Û\8cÛ\8c Ú©Ø¦ Ø¯Ø§Ø±Û\8cت Ø¨Ù\88Ù\99ئیت.",
+       "blockedtext": "<strong>Ù\86Ù\88Ù\85 Ú©Ø§Ø±Û\8cارÛ\8c Ø´Ù\88Ù\85ا Û\8cا ØªÛ\8cرÙ\86Ø´Û\8aÙ\86 Ø¢Û\8c Ù¾Û\8c Ø´Ù\88Ù\85ا Ù\86اÙ\9bÙ\87اگرÛ\8c Ø¨Û\8cÙ±.</strong>\n\n\n$1 Ú¤Ù\86Ù± Ù\86اÙ\9bÙ\87اگرÛ\8c Ú©Ø±Ø¯Ù±.\nدÙ\84Û\8cÙ\84Ø´ Ù\87ا Ø¯ Ø§Û\8cÚ\86اÙ\9b<em>$2</em>.\n\nØ´Ù\88رÛ\8a Ø¯ Ù\86اÙ\9bÙ\87اگرÛ\8c:$8\nآخر Ù\86اÙ\9bÙ\87اگرÛ\8c:$6\nکارÛ\8cارÛ\8c Ú©Ø§Ù\9b Ù\87ا Ú¤Ù±Ø±ØªÛ\8cÙ± Ù\88 Ù\86اÙ\9bÙ\87اگرÛ\8c Ø¨Û\8cÙ±:$7\n\nØ´Ù\88Ù\85ا Ù\85Û\8c ØªÛ\8aÙ\86Û\8cت Ú¤Ø§ $1 Û\8cا [[{{MediaWiki:Grouppage-sysop}}|سردÛ\8cÚ¤Û\8aÙ\86کار]] Ù\87Ù±Ù\86Û\8c Ù¾Û\8cÚ¤Ù\86د Ø¨Ø§Ù\9bÛ\8cرÛ\8cت Ù\88 Ø³Û\8c Ù\86اÙ\9bÙ\87اگرÛ\8c Ú¤Ø§ Ú¤ Ú\86Ù±Ú© Ú\86Ù\86Ù± Ú©Ø§Ø±Û\8c Ø¨Ù±Ú©Û\8cت.\nÙ±Ù\84ڤت Ø¯ Ú¤Û\8cر Ø¯Ø§Ø´ØªÛ\8aئÛ\8cت Ú©Ø§Ù\9b Ø´Ù\88Ù\85ا Ù\86Ù\85Û\8c ØªÛ\8aÙ\86Û\8cت Ú\86Û\8cا Ù±Ù\86جÙ\88Ù\85اÙ\86اÙ\85Ù± Ú©Ø§Ù\9bÙ\84 Ú©Ø±Ø¯Ù\86 Ø³Û\8c Ø§Û\8c Ú©Ø§Ø±Û\8cار Ù\86Ù± Ú¤ Ú©Ø§Ø± Ø¨Ø§Ù\9bÛ\8cرÛ\8cتØ\8c Ù\85ٱر Û\8cÙ± Ú©Ø§Ù\9b Û\8cاÙ\9b Ú¯Ù±Ù\84 ØªÛ\8cرÙ\86Ø´Û\8aÙ\86 Ù±Ù\86جÙ\88Ù\85اÙ\86اÙ\85Ù± Ù\86ازار Ù\86Ù± [[Special:Preferences|تٱرجÛ\8cئات Ú©Ø§Ø±Û\8cارÛ\8c]] Ø®Ù\88تÛ\8a Ø¯Û\8cارÛ\8c Ú©Ø±Ø¯Û\8aئÛ\8cت Ù\88 ØªÛ\8aÙ\86ستÛ\8aÛ\8cت Ú¤ Ù\86Ù± Ú¤ Ú©Ø§Ø± Ø¨Ø§Ù\9bÛ\8cرÛ\8cت .\nتÛ\8cرÙ\86Ø´Û\8aÙ\86 Ø¢Û\8c Ù¾Û\8c Ø§Û\8cساÙ\9bÙ\86Û\8c Ø´Ù\88Ù\85ا $3 Ù±Ø\8c Ù\88 Ù\86Ù\88Ù\85 Ø¯Û\8cارکÙ\88Ù\86 Ù\86اÙ\9bÙ\87اگرÛ\8c #$5 Ù±.\nÙ\84Ù\88تÙ\81 Ø¨Ù±Ú©Û\8cت Ù\87Ù\85Ù± Ú\86Û\8cاÙ\86Ù± Ø¯ Ù\87ر Ù\87استٱÛ\8cÛ\8c Ú©Ø§Ù\9b Ø¯Ø§Ø±Û\8cت Ø¨Û\8aئیت.",
        "autoblockedtext": "<strong>نوم کاریاری شوما یا تیرنئشوٙن آی پی شوما سی یە کئ یئ گئل کاریاری هأنی ڤئ نە ڤئ کار گئرئتە خودأنجومأن ڤئ دأس $1 نئهاگئری بییە.</strong>\n\n\n$1 ڤئنە نئهاگئری کئردە.\nدألیلئش ها د ئیچئ\n<em>$2</em>.\n\nشوروٙ د نئهاگئری:$8\nآخئر نئهاگئری:$6\nکاریاری کئ ها ڤأرتیە و نئهاگئری بییە:$7\n\nشوما می توٙنیت ڤا $1 یا [[{{MediaWiki:Grouppage-sysop}}|سأردیڤوٙنکار]] هأنی پئیڤأند بئیریت و سی نئهاگئری ڤا ڤئ چأک چئنە کاری بأکیت.\nألڤأت د ڤیر داشتوٙئیت کئ شوما نئمی توٙنیت خوصۉصیأت أنجومانامە کئل کئردئن سی ئی کاریار نە ڤئ کار بئیریت، مأر یە کئ یئ گئل تیرنئشوٙن أنجومانامە نازار نە [[Special:Preferences|تأرجیحات کاریاری]] خوتوٙ دیاری کئردئوٙیت و توٙنئستوٙیت ڤئ نە ڤئ کار بئیریت .\nتیرنئشوٙن آی پی ئیسئنی شوما $3ە، و نوم دیارکون نئهاگئری #$5 ە.\nلوطف بأکیت هأمە چیانە د هأر حاستە یی کئ داریت بوٙئیت.",
        "blockednoreason": "هیچ دألیلی گوتە نأبییە",
        "whitelistedittext": "$1 لوطف بأکیت بألگە یا نە ڤیرایئشت کاری بأکیت.",
        "nosuchsectiontitle": "بأرجا پئیدا نأبوٙە",
        "nosuchsectiontext": "شوما سی ڤیرایئشت کاری جایی کئ ڤوجوٙد نارە تئلاش کئردیتە.\nگاسی ڤئ ئوٙسئ کئ شوما بألگە نە دئیتە جا ڤئ جا بییە یا پاکسا بییە.",
        "loginreqtitle": "ڤامین ئوٙمائن گأرأکە",
-       "loginreqlink": "ڤاÙ\85Û\8cÙ\86 Ø¦Ù\88Ù\99مائن",
+       "loginreqlink": "ڤاÙ\85Û\8cÙ\86 Ø§Û\8aمائن",
        "loginreqpagetext": "$1 لوطف بأکیت بألگە یا هأنی نە سئیل بأکیت.",
        "accmailtitle": "رازینە گوڤاردئن کئل بی",
        "accmailtext": "یئ گئل رازینە گوڤاردئن شامسأکی سی[[User talk:$1|$1]] سی $2 کئل بییە.بوٙە ڤئنە د گات ڤئ کار گئرئتئن بألگە ڤامین ئوٙمائن <em>[[Special:آلئشت دأئن رازینە گوڤاردئن|آلئشت دأئن رازینە گوڤاردئن]]</em> آلئشت کاری با.",
        "nohistory": "هیچ ویرگار ویرایشتی د ای بلگه نئ.",
        "currentrev": "آخرین دوواره دیئن",
        "currentrev-asof": "آخري وانئری چی $1",
-       "revisionasof": "دوۋارٱ دیاٛن $1",
+       "revisionasof": "دوڤارٱ دیاٛن $1",
        "revision-info": "دوواره سیل بیه چی $1 وا $2",
-       "previousrevision": "ۋانیٱری داٛمایی←",
+       "previousrevision": "ڤانیٱری داٛمایی←",
        "nextrevision": "ڤانئیأری تازە تئر",
        "currentrevisionlink": "آخئری ڤانئیأری",
        "cur": "تازٱ باۋ",
        "page_first": "أڤئلی",
        "page_last": "آخئر",
        "histlegend": "انتخاو فرخدار:جعویا رادیو نه سی دوواره دیئن و وارسی نشو دار بکید و یا ری رئتن کلیک بکید .<br />\nشرح نوشته: '''({{int:cur}})''' = وا آخری دوواره دیئن فرخ داره '''({{ int:last}})'''= وا دواره دیئن انجوم دئنی فرخ داره  '''{{int:minoreditletter}}''' =ویرایشت کؤچک.",
-       "history-fieldset-title": "ۋیرگار دوۋارٱ نیٱری",
+       "history-fieldset-title": "ڤیرگار دوڤارٱ نیٱری",
        "history-show-deleted": "فقط پاكسا بيه",
        "histfirst": "قديمي تري",
        "histlast": "تازه تري",
        "historysize": "({{PLURAL:$1|1 بایت|$1 بایتیا}})",
        "historyempty": "(حالی)",
-       "history-feed-title": "ویرگار دوواره دیئن",
-       "history-feed-description": "دوواره دیئن ویرگار سی بلگه د ویکی",
+       "history-feed-title": "ڤیرگار دوڤارٱ دیاٛن",
+       "history-feed-description": "دوڤارٱ دیاٛن ڤیرگار سی بلگٱ د ڤیکی",
        "history-feed-item-nocomment": "$1 د\n$2",
        "history-feed-empty": "بلگه حاسته بیه وجود ناره.\nشایت وه د ویکی پاکسا بیه، یا نومش آلشت بیه.\nسی بلگیا مرتوط تازه [[ویجه:پی جوری|پی جوری د ویکی]] کوششت بکید.",
        "history-edit-tags": "ڤیرایئشت کاری ڤانئیأریا گولئ ڤورچی بییە",
        "mergelog": "سریک سازی پهرستنومه",
        "revertmerge": "بی لوئه",
        "mergelogpagetext": "شما د هار نوم گه آخرین چیا وه یک شیوسن ویرگار یه بلگه نه د بلگه تر میئنیت.",
-       "history-title": "دوواره دیئن ویرگار$1",
+       "history-title": "دوڤارٱ دیاٛن ڤیرگار $1",
        "difference-title": "فرخ مینجا وانیریا \"$1\"",
        "difference-title-multipage": "فرخ مینجا بلگه یا \"$1\" و \"$2\"",
        "difference-multipage": "(فرخ مینجا بلگه یا)",
        "searchprofile-advanced-tooltip": "نوم جايا نوم ديار بگرد",
        "search-result-size": "$1 ({{PLURAL:$2|1 کٱلیمٱ|$2 کٱلیمٱیا}})",
        "search-result-category-size": "{{PLURAL:$1|1 أندوم|$1 أندومیا}} ({{PLURAL:$2|1 زیردأسە|$2 زیردأسە یا}}، {{PLURAL:$3|1 جانیا|$3 جانیایا}}",
-       "search-redirect": "(ۋورگشتن سی $1)",
+       "search-redirect": "(ڤورگشتن سی $1)",
        "search-section": "(بهرجا $1)",
        "search-category": "(دسه $1)",
        "search-file-match": "(یکی کردن مینونه جانیا)",
        "search-interwiki-more": "(بیشتر)",
        "search-relatedarticle": "مرتوط",
        "searchrelated": "مرتوط",
-       "searchall": "ھأمە",
+       "searchall": "همٱ",
        "showingresults": "نمائشت بیشترونه {{PLURAL:$1|'''۱''' نتیجه|'''$1''' نتیجه}} د هار، شرو د شماره'''$2'''.",
        "showingresultsinrange": "نمائشت بیشترونه {{PLURAL:$1|'''۱''' نتیجه|'''$1''' نتیجه}} د هار، شرو د شماره'''$2''' تا شماره '''$3'''.",
        "search-showingresults": "{{PLURAL:$4|نتیجه یا<strong>$1</strong> د <strong>$3</strong>|نتیجه یا<strong>$1 - $2</strong د <strong>$3</strong>}}",
        "searchdisabled": "مئن جوری د {{SITENAME}} کنشتگر نئ.\nموقتاً می تونیت مئن جوری Google نه بونیت وه کار.\nد ویرتو با که نتیجه یایی که د مئن جوری وا او روشت وه دست میان شایت وه روز نبان.",
        "search-error": "یه گل خطا سی اوسنی که پی جوری می کردیت اتفاق افتائه:$1",
        "preferences": "خوصوٙیات هأنی",
-       "mypreferences": "خوصوٙیات هأنی",
+       "mypreferences": "چیا هٱنی",
        "prefs-edits": "شومارە ڤیرایئشتیا:",
        "prefsnologintext2": "لطف بکیت بیایت وامین و ترجیحات خوتونه آلشت بئیت.",
        "prefs-skin": "پوس",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|د آخری دیئن}}",
        "enhancedrc-history": "ڤیرگار",
        "recentchanges": "آلشتیا ایساٛنی",
-       "recentchanges-legend": "گزینه یا آلشتیا ایسنی",
+       "recentchanges-legend": "گوزینٱیا آلشتیا ایسناٛنی",
        "recentchanges-summary": "دو بیشتر آلشتیا تازباو نه د ویکی نه د ای بلگه پیگری کو.",
        "recentchanges-noresult": "هیژ آلشتی د درازا دوره دیار بیه وا ای معیاریا یکی نبی.",
        "recentchanges-feed-description": "دو بیشتر آلشتیا تازباو نه د ویکی که ها د هوال حون پیگری کو.",
        "rcshowhideminor-show": "نشو دئن",
        "rcshowhideminor-hide": "قام کردن",
        "rcshowhidebots": "$1 رواتيا یا بوتيا",
-       "rcshowhidebots-show": "نشو دئن",
+       "rcshowhidebots-show": "نشۊ دٱئن",
        "rcshowhidebots-hide": "قام کردن",
        "rcshowhideliu": "$1 کاریاریا ثوت نام کرده",
        "rcshowhideliu-show": "نئشوٙ دأئن",
        "rcshowhideliu-hide": "قام کئردئن",
        "rcshowhideanons": "کاریار نادیار $1",
        "rcshowhideanons-show": "نئشوٙ دأئن",
-       "rcshowhideanons-hide": "Ù\82اÙ\85 Ú©Ø¦Ø±Ø¯Ø¦ن",
+       "rcshowhideanons-hide": "Ù\82اÙ\85 Ú©Ø±Ø¯ن",
        "rcshowhidepatr": "$1 ویرایشتیا تیه پرس بیه",
        "rcshowhidepatr-show": "نئشوٙ دأئن",
        "rcshowhidepatr-hide": "قام کئردئن",
        "rcshowhidemine": "ڤیرایئشتیا مئ $1",
        "rcshowhidemine-show": "نئشوٙ دأئن",
-       "rcshowhidemine-hide": "Ù\82اÙ\85 Ú©Ø¦Ø±Ø¯Ø¦ن",
+       "rcshowhidemine-hide": "Ù\82اÙ\85 Ú©Ø±Ø¯ن",
        "rcshowhidecategorization": "جأرغە کاری بألگە $1",
        "rcshowhidecategorization-show": "نئشوٙ دأئن",
        "rcshowhidecategorization-hide": "قام کئردئن",
        "rclinks": "آخرین آلشتیا $1 د آخرین رۊزیا دیاری بٱک $2",
        "diff": "فرق",
-       "hist": "ۋیرگار",
-       "hide": "Ù\82اÙ\85 Ú©Ø¦Ø±Ø¯Ø¦ن",
-       "show": "Ù\86ئشÙ\88Ù\99 Ø¯Ø£ئن",
+       "hist": "ڤیرگار",
+       "hide": "Ù\82اÙ\85 Ú©Ø±Ø¯ن",
+       "show": "Ù\86Ø´Û\8a Ø¯Ù±ئن",
        "minoreditletter": "م",
        "newpageletter": "ن",
        "boteditletter": "ب",
        "recentchangeslinked": "آلشتیا تی یکی",
        "recentchangeslinked-feed": "آلشتیا تی یکی",
        "recentchangeslinked-toolbox": "آلشتیا تاٛ یٱک",
-       "recentchangeslinked-title": "آلشتیا تی یکی د $1",
+       "recentchangeslinked-title": "آلشتیا تاٛ یکی د $1",
        "recentchangeslinked-summary": "ای نوم بلگٱ تازٱ د بلگٱیایی کاٛ ۋا بلگٱیا ۋیجٱ هوم پیۋند بینٱ آلشت بیٱ(یا سی ٱندومیا دٱسٱ بٱنی بیٱ)\nبلگٱیایی کاٛ هان د [[Special:Watchlist|your watchlist]]و گٱپ بینٱ",
        "recentchangeslinked-page": "نوم بألگە:",
        "recentchangeslinked-to": "آلشتیایی که د بلگه یا هوم پیوند بینه وه جا بلگه دئیه بیه نشو بیه",
        "uploadlogpage": "سوارکرد",
        "uploadlogpagetext": "نومگه هاری یه گل نومگه د آخری سوارکرد جانیایا هئ.\nسی د نو سیل کردن[[Special:NewFiles|عسگدونی جانیایا تازه نه]] به ونیت.",
        "filename": "نوم جانیا",
-       "filedesc": "چكسته",
+       "filedesc": "چکسٱ",
        "fileuploadsummary": "چکسه",
        "filereuploadsummary": "آلشتیا جانیا:",
        "filestatus": "حال و بال کپی رایت",
        "listfiles-latestversion-yes": "هأری",
        "listfiles-latestversion-no": "تە",
        "file-anchor-link": "جانیا",
-       "filehist": "ۋیرگار جانیا",
+       "filehist": "ڤیرگار جانیا",
        "filehist-help": "ری  ويرگاريا بپورنيت تا نسقه مرتوط بونيت.",
        "filehist-deleteall": "هأمە نئ پاکسا کو",
        "filehist-deleteone": "پاکسا کئردئن",
        "filehist-revert": "لئرنیئن",
-       "filehist-current": "تازٱ باۋ",
-       "filehist-datetime": "ويرگار/وخت",
+       "filehist-current": "تازٱ باڤ",
+       "filehist-datetime": "ڤيرگار/ڤٱخت",
        "filehist-thumb": "ٱسگ کوچک بیٱ",
        "filehist-thumbtext": "كوچک کردن سی نوسقٱ چی $1",
        "filehist-nothumb": "هیچ بن کلیکی نئ",
        "filehist-user": "کاریار",
        "filehist-dimensions": "بعديا",
        "filehist-filesize": "انازه فایل",
-       "filehist-comment": "ۋیر و باۋر",
+       "filehist-comment": "ڤیر و باڤر",
        "imagelinks": "د کار گرتن جانیا",
        "linkstoimage": "دمال بيه {{PLURAL:$1|ديس ونيا بلگه|$1 ديس ون بلگيا}} دای فایل:",
        "linkstoimage-more": "بیشتر د $1 بلگه د ای جانیا هوم پیوند {{PLURAL:$1|بیه|بینه}}.\nنومگه هاری تئنا {{PLURAL:$1|اولین هوم پیوند|اولین $1 هوم پیوند}} د ای بلگه نه نشو می ئه.\n[[Special:WhatLinksHere/$2|نومگه کامل]] ئم هیئش.",
        "usermessage-summary": "رئتن د سامونه پیغوم",
        "usermessage-editor": "پیغوم فرسن سیستم",
        "usermessage-template": "ویکی وارسگر:پیغوم کاریار",
-       "watchlist": "سئÛ\8cÙ\84 Ø¨Ø£رگ",
-       "mywatchlist": "سئÛ\8cÙ\84 Ø¨Ø£رگ",
+       "watchlist": "ساÙ\9bÛ\8cÙ\84 Ø¨رگ",
+       "mywatchlist": "ساÙ\9bÛ\8cÙ\84 Ø¨رگ",
        "watchlistfor2": "سي $1 $2",
        "nowatchlist": "شما هیچی د سیل برگ خوتو ناریت",
        "watchlistanontext": "لطفن بیایت وامین و ویرایشتیا نه د سیل برگتو سیل بکیت.",
        "notvisiblerev": "آخری وانئری که د دس یه کاریار هنی انجوم بیه پاکسا بیه.",
        "watchlist-details": "{{PLURAL:$1|$1 بلگٱ|$1 بلگٱیا}} د ساٛیل برگتۊ هیچ بلگٱ قساٛ کردنی نی.",
        "wlheader-enotif": "ڤارئسیاری أنجومانامە کونئشتکار بییە.",
-       "wlheader-showupdated": "بÙ\84Ú¯Ù\87 Û\8cاÛ\8cÛ\8c Ú©Ù\87 Ø¯ Ø¢Ø®Ø±Û\8cÙ\86 Ú©Ø±ØªÛ\8c Ú©Ù\87 Ø´Ù\85ا Ø¯Ø´Ù\88 Ø¯Û\8cئÙ\86 Ú©Ø±Ø¯Û\8cتÙ\87 Ø¢Ù\84شت Ø¨Û\8cÙ\86Ù\87 Ø¯ <strong>تÙ\88پر</strong>Ù\86Ø´Ù\88Ù\86 Ø¯Ø¦Ù\87 Ø¨Û\8cÙ\86Ù\87",
+       "wlheader-showupdated": "بÙ\84Ú¯Ù± Û\8cاÛ\8cÛ\8c Ú©Ø§Ù\9b Ø¯ Ø¢Ø®Ø±Û\8cÙ\86 Ø¨Ø§Ø±Û\8c Ú©Ø§Ù\9b Ú©Ù\87 Ø´Ù\85ا Ø³Ø§Ù\9bÛ\8cÙ\84Ø´Û\8a Ú©Ø±Ø¯Û\8cتٱ Ø¯ <strong>تÛ\8aÙ¾Ù\88ر</strong>Ù\86Ø´Û\8aÙ\86 Ø¯Ø¦Ù± Ø¨Û\8aاÙ\9bÙ\86",
        "wlnote": "د هار {{PLURAL:$1|آلشت|<strong>$1</strong> آلشتی}} که د {{PLURAL:$2|ساعت|<strong>$2</strong> ساعت}} دماتر انجوم بیه هیئش، ویرگار آخرین واجوری انجام شده موجود است، ویرگار آخری واجوری: $3، $4",
        "wlshowlast": "آخرین$1 ساعتیا $2و روزیا  نشو بیئه",
        "wlshowtime": "نئشوٙ دأئن د آخأر",
        "wlshowhideanons": "کاریار نادیار",
        "wlshowhidepatr": "تیە پایی د ڤیرایئشتیا",
        "wlshowhidemine": "ڤیرایئشتیا مئ",
-       "watchlist-options": "Ú\86Û\8cا Ø³Ø¦Û\8cÙ\84 Ø¨Ø£رگ",
+       "watchlist-options": "Ú\86Û\8cا Ø³Ø§Ù\9bÛ\8cÙ\84 Ø¨رگ",
        "watching": "د حال و بال دیئن...",
        "unwatching": "د حال ندیئن...",
        "watcherrortext": "یه گل اشگال د گات آلشت کردن میزونکاری نومگه سیل برگتو سی «$1» پیش اوما.",
        "sp-contributions-deleted": "هومیاریا پاکسا بیه کاریار",
        "sp-contributions-uploads": "سواركرديا",
        "sp-contributions-logs": "نیسنن رخ ونیا",
-       "sp-contributions-talk": "چأک چئنە",
+       "sp-contributions-talk": "چٱک چنٱ",
        "sp-contributions-userrights": "دیوونداری حقوق کاریار",
        "sp-contributions-blocked-notice": "د دسرسی ای کاریا د ایسنی نهاگری بیه.\nآخری برشت د پهرستنومه نهاگری ها د سرچشمه هاری:",
        "sp-contributions-blocked-notice-anon": "ای آی پی ایسنی دسرسی ناره.\nآخری برشت د پهرستنومه ها د سرچشمه هاری:",
        "sp-contributions-submit": "پئی جوٙری",
        "whatlinkshere": "کوم هوم پیۋندیا هان ایچاٛ",
        "whatlinkshere-title": "بلگه ای که د $1 هوم پیوند بیه",
-       "whatlinkshere-page": "بألگە",
+       "whatlinkshere-page": "بلگٱ",
        "linkshere": "بلگیا نهایی د '''[[:$1]]''' هوم پیوند بیه",
        "nolinkshere": "هیژ بگله ای د  '''[[:$1]]''' هوم پیوند نبیه",
        "nolinkshere-ns": "هیچ بلگه ای د نومجا انتخاو بیه وه'''[[:$1]]''' هوم پیوند ناره.",
        "whatlinkshere-prev": "{{PLURAL:$1|دمایی|دمایی $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|نهایی|نهایی $1}}",
        "whatlinkshere-links": "هوم پیوندیا",
-       "whatlinkshere-hideredirs": "$1 ۋاگردۊنیا",
+       "whatlinkshere-hideredirs": "$1 ڤارگردۊنیا",
        "whatlinkshere-hidetrans": "$1 چٱن نتیجٱیی",
-       "whatlinkshere-hidelinks": "هوم پیۋندیا $1",
+       "whatlinkshere-hidelinks": "هوم پیڤندیا $1",
        "whatlinkshere-hideimages": "جانیا هوم پیۋندیا $1",
        "whatlinkshere-filters": "فيلتريا",
        "autoblockid": "خود نهاگری #$1",
        "tooltip-t-print": "نوسقٱ پاٛلا بیاٛنی سی ای بلگٱ",
        "tooltip-t-permalink": "هوم پیڤند همیشٱیی سی دوڤارٱ دیاٛن ای بلگٱ",
        "tooltip-ca-nstab-main": "دياٛن مینۊنٱ بلگٱ",
-       "tooltip-ca-nstab-user": "دÙ\8aئÙ\86 Ø¨Ù\84Ú¯Ù\87 کاریار",
+       "tooltip-ca-nstab-user": "دÙ\8aاÙ\9bÙ\86 Ø¨Ù\84Ú¯Ù± کاریار",
        "tooltip-ca-nstab-media": "دیئن بلگه وارسگر",
-       "tooltip-ca-nstab-special": "یٱ یاٛ گاٛل بلگٱ ۋیجٱ یٱ؛ نبۊٱ ڤیرایشتش بٱکیت",
+       "tooltip-ca-nstab-special": "یٱ یاٛ گاٛل بلگٱ ڤیجٱ یٱ؛ نبۊٱ ڤیرایشتش بٱکیت",
        "tooltip-ca-nstab-project": "ديئن بلگه پروجه",
        "tooltip-ca-nstab-image": "ديئن بلگه جانیا",
-       "tooltip-ca-nstab-mediawiki": "دÛ\8cئÙ\86 Ù¾Û\8cغÙ\88Ù\85 Ø³Ø§Ù\85Ù\88Ù\86Ù\87",
+       "tooltip-ca-nstab-mediawiki": "دÛ\8cاÙ\9bÙ\86 Ù¾Û\8cغÙ\88Ù\85 Ø³Ø§Ù\85Û\8aÙ\86Ù±",
        "tooltip-ca-nstab-template": "ديئن قالو",
        "tooltip-ca-nstab-help": "ديئن بلگه هومیاری",
        "tooltip-ca-nstab-category": "ديئن بلگه دسه بنی",
        "tooltip-minoredit": "یه نه د عنوان حیرده ویرایشت ثوت کو",
-       "tooltip-save": "آلشتياتونه اماییه بكيد",
+       "tooltip-save": "آلشتیاتۊنٱ اٛمایٱ بٱکیت",
        "tooltip-preview": "پیش سیل آلشتیاتو،لطف بکیت وه نونه دما د اماییه کاریشو وه کار بیئریت!",
        "tooltip-diff": "آلشتیا نه که شما د ای متن راس کردیته نشو بیئه",
-       "tooltip-compareselectedversions": "فرخیا مینجا دو تا د دو بار دیئن ای بلگه نه بوینیت",
+       "tooltip-compareselectedversions": "فرخیا مینجا د تا د دو بار دیاٛن ای بلگٱ نٱ بۉنیت",
        "tooltip-watch": "ای بلگه نه د سیل برگتو اضاف بکید",
        "tooltip-watchlistedit-normal-submit": "ؤرداشتن سرونیا",
        "tooltip-watchlistedit-raw-submit": "وه هنگوم سازی سیل برگ",
        "exif-bitspersample": "نقطه یا سی هر اندوم",
        "exif-compression": "شیوات جم و جور کردن",
        "exif-photometricinterpretation": "ترکیو پیکسل",
-       "exif-orientation": "سرÚ\86Ø´Ù\85Ù\87",
+       "exif-orientation": "سرÚ\86Ø´Ù\85Ù±",
        "exif-samplesperpixel": "شماره اندومیا",
        "exif-planarconfiguration": "سرجایک کردن رسینه",
        "exif-ycbcrsubsampling": "نسوت زیرنمونه Y وه C",
        "exif-copyrighted-true": "کپی رایت بیه",
        "exif-copyrighted-false": "حال و بال کپی رایت میزوکاری نبیه",
        "exif-unknowndate": "گات نادیار",
-       "exif-orientation-1": "عادی",
+       "exif-orientation-1": "Ø¢دی",
        "exif-orientation-2": "پشت ری بیه افقی",
        "exif-orientation-3": "180 گرینج لر دئه",
        "exif-orientation-4": "پشت ری بیه عمودی",
        "logentry-patrol-patrol": "$1 نسقه $4 بلگه $3 نه چی یه گل چی تیه نئری بیه {{GENDER:$2|نشودار کرد}}",
        "logentry-patrol-patrol-auto": "$1 نسقه $4 بلگه $3 نه وه حال و بار خودانجوم چی یه گل بلگه تیه نیئر بیه {{GENDER:$2|نشودار کرد}}",
        "logentry-newusers-newusers": "حساو کاریاری $1 {{GENDER:$2|دروس بیه}}",
-       "logentry-newusers-create": "حساو کاریاری $1 {{GENDER:$2|راس بی}}",
+       "logentry-newusers-create": "هساڤ کاریاری $1 {{GENDER:$2|راس بی}}",
        "logentry-newusers-create2": "حساو کاریاری $3،وه دس $1 {{GENDER:$2|دروس بی}}",
        "logentry-newusers-byemail": "حساو کاریاری $3 وه دس $1 {{GENDER:$2|ره وندیاری بی}} و رازینه گواردن وا انجومانام کل بی",
        "logentry-newusers-autocreate": "حساو $1  خودانجومن {{GENDER:$2|دروس بی}}",
index 2bdfca3..88577dd 100644 (file)
        "createaccount": "Sukurti paskyrą",
        "userlogin-resetpassword-link": "Pamiršote savo slaptažodį?",
        "userlogin-helplink2": "Padėti prisijungti",
-       "userlogin-loggedin": "Jūs jau prisijungęs kaip {{GENDER:$1|$1}}.\nNaudokite žemiau pateiktą pavidalą, kad prisijungtumėte kaip kitas naudotojas.",
+       "userlogin-loggedin": "Jūs jau prisijungęs kaip {{GENDER:$1|$1}}.\nĮveskite prisijungimo duomenis į žemiau esančius laukelius, kad prisijungtumėte kaip kitas naudotojas.",
        "userlogin-reauth": "Turite vėl prisijungti patvirtinimui, kad esate {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Sukurti kitą paskyrą",
        "createacct-emailrequired": "Elektroninio pašto adresas",
        "createacct-another-submit": "Sukurti paskyrą",
        "createacct-continue-submit": "Tęsti paskyros kūrimą",
        "createacct-another-continue-submit": "Tęsti paskyros kūrimą",
-       "createacct-benefit-heading": "{{SITENAME}} sukurtas žmonių kaip jūs.",
+       "createacct-benefit-heading": "{{SITENAME}} kuria tokie žmonės kaip Jūs.",
        "createacct-benefit-body1": "{{PLURAL:$1|keitimas|keitimai|keitimų}}",
        "createacct-benefit-body2": "{{PLURAL:$1|puslapis|puslapiai|puslapių}}",
        "createacct-benefit-body3": "Neseni {{PLURAL:$1|autorius|autoriai|autorių}}",
index 2e4bc59..e1c432c 100644 (file)
        "history": "Geschiedenisse",
        "history_short": "Geschiedenisse",
        "updatedmarker": "bie-ewörken sinds mien leste bezeuk",
-       "printableversion": "Aofdrokbaore versie",
-       "permalink": "Vaste verwiezing",
+       "printableversion": "Ofdrukbåre versy",
+       "permalink": "Vaste verwysing",
        "print": "Aofdrokken",
        "view": "Leasen",
        "view-foreign": "Bekieken op $1",
        "personaltools": "Persoonlike instellingen",
        "talk": "Oaverleg",
        "views": "Weergaven",
-       "toolbox": "Hulpmiddels",
+       "toolbox": "Hülpmiddels",
+       "tool-link-emailuser": "Disse {{GENDER:$1|gebruker}} een bericht stüren",
        "imagepage": "Bestaandszied bekieken",
        "mediawikipage": "Tiejige bekieken",
        "templatepage": "Mal bekieken",
        "viewhelppage": "Hulpzied bekieken",
        "categorypage": "Kategoriezied bekieken",
        "viewtalkpage": "Bekiek overlegzied",
-       "otherlanguages": "Aandere talen",
+       "otherlanguages": "Andere talen/språken",
        "redirectedfrom": "(deurestuurd vanaof \"$1\")",
        "redirectpagesub": "Deurverwieszied",
        "redirectto": "Deurverwiezen naor:",
        "disclaimerpage": "Project:Veurbehoud",
        "edithelp": "Hulpe mit bewarken",
        "helppage-top-gethelp": "Hulpe",
-       "mainpage": "Veurblad",
+       "mainpage": "Vöärblad",
        "mainpage-description": "Veurblad",
        "policy-url": "Project:Beleid",
-       "portal": "Gebrukersportaol",
+       "portal": "Gebrukersportål",
        "portal-url": "Project:Gebrukersportaol",
        "privacy": "Gegevensbeleid",
        "privacypage": "Project:Gegevensbeleid",
        "userrights": "Gebrukersrechtenbeheer",
        "userrights-lookup-user": "Beheer gebrukersgroepen",
        "userrights-user-editname": "Vul n gebrukersnaam in:",
-       "editusergroup": "Bewark {{GENDER:$1|gebrukersgroepen}}",
+       "editusergroup": "Gebrukersgruppen bewarken",
        "editinguser": "Doonde mit t wiezigen van de gebrukersrechten van '''[[User:$1|$1]]''' $2",
        "userrights-editusergroup": "Bewark gebrukersgroep",
        "saveusergroups": "Gebrukergroepen opslaon",
        "nchanges": "$1 {{PLURAL:$1|wieziging|wiezigingen}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|sinds joew leste bezeuk}}",
        "enhancedrc-history": "geschiedenisse",
-       "recentchanges": "Leste wiezigingen",
+       "recentchanges": "Lätste wysigingen",
        "recentchanges-legend": "Opsies veur leste wiezigingen",
        "recentchanges-summary": "Op disse zied ku'j de leste wiezigingen van disse wiki bekieken.",
        "recentchanges-noresult": "Der waren in disse periode gien wiezigingen die an de kriteria voldoon.",
        "recentchanges-page-removed-from-category": "[[:$1]] is vortedaon uut kategorie",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] vortedaon uut kategorie, [[Special:WhatLinksHere/$1|disse zied zit in aandere ziejen in-esleuten]]",
        "autochange-username": "Automatiese wieziging van MediaWiki",
-       "upload": "Bestaand opsturen",
-       "uploadbtn": "Bestaand opsturen",
+       "upload": "Bestand upstüren",
+       "uploadbtn": "Bestand upstüren",
        "reuploaddesc": "Weerumme naor de opstuurzied",
        "upload-tryagain": "Bestaandsbeschrieving biewarken",
        "uploadnologin": "Nyt an-emeld",
        "unusedtemplates": "Ongebruukten mallen",
        "unusedtemplatestext": "Hieronder staon alle ziejen in de naamruumte \"{{ns:template}}\" die nargens gebruukt wörden.\nVergeet niet de verwiezingen nao te kieken veurda'j de mal vortdoon.",
        "unusedtemplateswlh": "aandere verwiezingen",
-       "randompage": "Netzelde welk artikel",
+       "randompage": "Netselvde welk artikel",
        "randompage-nopages": "Der staon gien ziejen in de {{PLURAL:$2|naamruumte|naamruumtes}}: $1.",
        "randomincategory": "Netzelde welke zied in n kategorie",
        "randomincategory-invalidcategory": "\"$1\" is gien geldige kategorienaam.",
        "listusers-desc": "Sorteren in aoflopende volgorde",
        "usereditcount": "$1 {{PLURAL:$1|bewarking|bewarkingen}}",
        "usercreated": "{{GENDER:$3|Eregistreerd}} op $1 um $2",
-       "newpages": "Nieje artikels",
+       "newpages": "Nye artikels",
        "newpages-submit": "Bekiek",
        "newpages-username": "Gebrukersnaam:",
        "ancientpages": "Oudste artikels",
        "magiclink-tracking-isbn": "Ziejen die magiese ISBN-verwiezingen gebruken",
        "specialloguserlabel": "Uutvoerende gebruker:",
        "speciallogtitlelabel": "Doel (ziednaam of gebruker):",
-       "log": "Logboeken",
+       "log": "Logboken",
        "all-logs-page": "Alle publieke logboeken",
        "alllogstext": "Dit is t kombinasielogboek van {{SITENAME}}.\nJe kunnen oek kiezen veur bepaolde logboeken en filteren op gebruker (heufdlettergeveulig) en titel (heufdlettergeveulig).",
        "logempty": "Der steet gien passende informasie in t logboek.",
        "trackingcategories": "Volgkategorieën",
        "mailnologin": "Nyt an-emeld.",
        "mailnologintext": "Je mutten [[Special:UserLogin|an-emeld]] ween en n geldig e-mailadres in \"[[Special:Preferences|mien veurkeuren]]\" invoeren um disse funksie te kunnen gebruken.",
-       "emailuser": "n Bericht sturen",
+       "emailuser": "Gebruker een bericht stüren",
        "emailuser-title-target": "Disse {{GENDER:$1|gebruker}} n bericht sturen",
        "emailuser-title-notarget": "Gebruker n bericht sturen",
        "emailpagetext": "Deur middel van dit formulier ku'j n bericht sturen naor disse {{GENDER:$1|gebruker}}.\nt Adres da'j op-egeven hebben bie [[Special:Preferences|joew veurkeuren]] zal as aofzender gebruukt wörden.\nDe ontvanger kan dus drek beantwoorden.",
        "namespace_association": "Naamruumte die hieran ekoppeld is",
        "tooltip-namespace_association": "Vink dit vakjen an um oek de overlegnaamruumte, of in t ummekeren geval de naamruumte zelf, derbie te doon die bie disse naamruumte heurt.",
        "blanknamespace": "(Heufdnaamruumte)",
-       "contributions": "{{GENDER:$1|Biedragen van disse gebruker}}",
+       "contributions": "{{GENDER:$1|Gebrukersbydragen}}",
        "contributions-title": "Biedragen van $1",
        "mycontris": "Myn bydragen",
        "anoncontribs": "Bydragen",
        "sp-contributions-toponly": "Allinnig de niejste versie laoten zien",
        "sp-contributions-newonly": "Allinnig nieje ziejen laoten zien",
        "sp-contributions-submit": "Zeuk",
-       "whatlinkshere": "Verwiezingen naor disse zied",
+       "whatlinkshere": "Verwysingen når disse syde",
        "whatlinkshere-title": "Ziejen die verwiezen naor \"$1\"",
        "whatlinkshere-page": "Zied:",
        "linkshere": "Disse ziejen verwiezen naor '''[[:$1]]''':",
        "pageinfo-hidden-categories": "Verbörgen {{PLURAL:$1|kategorie|kategorieën}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|Gebruukten mal|Gebruukten mallen}} ($1)",
        "pageinfo-transclusions": "{{PLURAL:$1|Zied|Ziejen}} in-evoegd op ($1)",
-       "pageinfo-toolboxlink": "Ziedgegevens",
+       "pageinfo-toolboxlink": "Sydegegeavens",
        "pageinfo-redirectsto": "Verwis deur naor",
        "pageinfo-redirectsto-info": "informasie",
        "pageinfo-contentpage": "Eteld as zied mit inhoud",
        "fileduplicatesearch-result-1": "Der bin gien bestaanden die gelieke bin an \"$1\".",
        "fileduplicatesearch-result-n": "Der {{PLURAL:$2|is één bestaand|bin $2 bestaanden}} die gelieke bin an \"$1\".",
        "fileduplicatesearch-noresults": "Der is gien bestaand mit de naam \"$1\" evunnen.",
-       "specialpages": "Spesiale ziejen",
+       "specialpages": "Speciale syden",
        "specialpages-note-top": "Legenda",
        "specialpages-group-maintenance": "Onderhoudsliesten",
        "specialpages-group-other": "Aandere spesiale ziejen",
index ab928e6..00f4ee7 100644 (file)
        "stub-threshold-disabled": "Uitgeschakeld",
        "recentchangesdays": "Weer te geven dagen in recente wijzigingen:",
        "recentchangesdays-max": "Maximaal $1 {{PLURAL:$1|dag|dagen}}",
-       "recentchangescount": "Standaard aantal weer te geven bewerkingen:",
+       "recentchangescount": "Standaard aantal weer te geven bewerkingen in de recente wijzigingen, paginageschiedenis en de logboeken:",
        "prefs-help-recentchangescount": "Maximale aantal: 1000",
        "prefs-help-watchlist-token2": "Dit is de geheime sleutel voor de webfeed van uw volglijst.\nIedereen die het token kent, kan uw volglijst bekijken, dus deel dit token niet.\nIndien nodig kunt u [[Special:ResetTokens|tokens opnieuw instellen]].",
        "savedprefs": "Uw voorkeuren zijn opgeslagen.",
        "rollback-success": "Wijzigingen door {{GENDER:$3|$1}} ongedaan gemaakt;\nlaatste versie van {{GENDER:$4|$2}} hersteld.",
        "rollback-success-notify": "De wijzigingen door $1 zijn teruggedraaid;\nde laatste versie van $2 is hersteld. [$3 Wijzigingen weergeven]",
        "sessionfailure-title": "Sessiefout",
-       "sessionfailure": "Er lijkt een probleem te zijn met uw aanmeldsessie.\nUw handeling is gestopt uit voorzorg tegen een beveiligingsrisico (dat bestaat uit mogelijke \"hijacking\" van deze sessie).\nGa een pagina terug, laad die pagina opnieuw en probeer het nog eens.",
+       "sessionfailure": "Er lijkt een probleem te zijn met uw aanmeldsessie.\nUw handeling is gestopt uit voorzorg tegen een beveiligingsrisico (dat bestaat uit mogelijke \"hijacking\" van deze sessie).\nProbeer het formulier opnieuw te versturen.",
        "changecontentmodel": "Inhoudsmodel van pagina bewerken",
        "changecontentmodel-legend": "Inhoudsmodel wijzigen",
        "changecontentmodel-title-label": "Paginanaam",
        "limitreport-templateargumentsize-value": "$1 / $2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Hoogste uitbreidingsdiepte",
        "limitreport-expensivefunctioncount": "Aantal kostbare parserfuncties",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Sjablonen substitueren",
        "expand_templates_intro": "Deze speciale pagina leest de opgegeven wikitekst in en substitueert recursief alle sjablonen in de wikitekst.\nHet substitueert ook alle parserfuncties zoals\n<code><nowiki>{{</nowiki>#language:…}}</code> en\nvariabelen als <code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nVrijwel alles tussen dubbele accolades wordt gesubstitueerd.",
        "expand_templates_title": "Contexttitel, voor {{FULLPAGENAME}}, enzovoort:",
index 115a9e9..0059c11 100644 (file)
        "createaccount-title": "Oppretting av brukarkonto på {{SITENAME}}",
        "createaccount-text": "Nokon oppretta ein brukarkonto for $2 på {{SITENAME}} ($4). Passordet til «$2» er «$3». Du bør logge inn og endre passordet ditt med ein gong.\n\nDu kan sjå bort frå denne meldinga dersom kontoen vart oppretta med eit uhell.",
        "login-throttled": "Du har prøvd å logge inn for mange gonger. Vent $1 vent før du prøver igjen.",
-       "login-abort-generic": "Innlogginga er avbroten.",
+       "login-abort-generic": "Innlogginga di feila - avbroten.",
+       "login-migrated-generic": "Kontoen din er blitt globalisert, og brukarnamnet ditt finst ikkje lenger på denne wikien.",
        "loginlanguagelabel": "Språk: $1",
        "suspicious-userlogout": "Førespurnaden din om å logge ut vart nekta fordi han såg ut til å vere sendt av ein øydelagt nettlesar eller mellomtenar.",
        "pt-login": "Logg inn",
        "permissionserrorstext": "Du har ikkje tilgang til å gjere dette, {{PLURAL:$1|grunnen|grunnane}} til det finn du her:",
        "permissionserrorstext-withaction": "Du har ikkje løyve til å $2 {{PLURAL:$1|av di|av desse grunnane}}:",
        "recreate-moveddeleted-warn": "'''Åtvaring: Du attopprettar ei side som tidlegare har vorte sletta.'''\n\nDu bør tenkje over om det er høveleg å halde fram med å endre denne sida.\nSletteloggen for sida finn du her:",
-       "moveddeleted-notice": "Sida er vorten sletta. Sletteloggen og flytteloggen er viste nedanfor for referanse.",
+       "moveddeleted-notice": "Denne sida er vorten sletta. \n\nSletteloggen og flytteloggen er viste nedanfor for referanse.",
        "log-fulllog": "Sjå full loggføring",
        "edit-hook-aborted": "Endring avbroten av ein funksjon, utan forklaring.",
        "edit-gone-missing": "Kunne ikkje oppdatere sida.\nDet ser ut til at ho er sletta.",
        "recentchangeslinked-feed": "Relaterte endringar",
        "recentchangeslinked-toolbox": "Relaterte endringar",
        "recentchangeslinked-title": "Endringar relaterte til «$1»",
-       "recentchangeslinked-summary": "Dette er ei liste over nylege endringar som er gjorde på sider som vert lenkja til frå ei oppgjeven side (eller på medlemer av ein oppgjeven kategori). Sider på [[Special:Watchlist|overvakingslista di]] er '''utheva'''.",
+       "recentchangeslinked-summary": "Skriv inn eit sidenamn for å sjå endringar på sider som lenkjer til eller vert lenkja til frå den sida. (For å sjå medlemmar av ein kategori skriv inn Kategori:Kategorinamn). Endringar av sider på [[Spesial:Watchlist|overvakingslista di]] er i <strong>feit skrift</strong>.",
        "recentchangeslinked-page": "Sidenamn:",
        "recentchangeslinked-to": "Vis endringar på sider som lenkjar til den gitte sida i staden",
        "recentchanges-page-added-to-category": "[[:$1]] vart lagd til kategorien",
index 2315fdc..86266c6 100644 (file)
@@ -96,7 +96,9 @@
                        "Cholewka",
                        "Ankam",
                        "Anwar2",
-                       "Acamicamacaraca"
+                       "Acamicamacaraca",
+                       "DeRudySoulStorm",
+                       "Railfail536"
                ]
        },
        "tog-underline": "Podkreślenie linków:",
        "stub-threshold-disabled": "Wyłączone",
        "recentchangesdays": "Liczba dni prezentowanych w ostatnich zmianach:",
        "recentchangesdays-max": "(maksymalnie $1 {{PLURAL:$1|dzień|dni}})",
-       "recentchangescount": "Domyślna liczba wyświetlanych edycji:",
-       "prefs-help-recentchangescount": "Uwzględnia ostatnie zmiany, historię stron i rejestry.",
+       "recentchangescount": "Domyślna liczba wyświetlanych edycji w ostatnich zmianach, historii i rejestrach:",
+       "prefs-help-recentchangescount": "Maksymalna liczba: 1000",
        "prefs-help-watchlist-token2": "To jest tajny klucz umożliwiający dostęp do kanału internetowego zmian w obserwowanych przez ciebie stronach.\nKażdy, kto go zna, będzie mógł je zobaczyć, więc zachowaj go dla siebie.\n[[Special:ResetTokens|Kliknij tu, jeśli chcesz go zresetować]].",
        "savedprefs": "Twoje preferencje zostały zapisane.",
        "savedrights": "Zapisano grupy {{GENDER:$1|użytkownika $1|użytkowniczki $1}}.",
        "expand_templates_preview": "Podgląd",
        "expand_templates_preview_fail_html": "<em>Ponieważ {{SITENAME}} ma włączony surowy kod HTML i zaistniała strata danych z sesji, podgląd jest ukryty jako zabezpieczenie przed atakiem JavaScript.</em>\n\n<strong>Jeśli to jest próba słusznego podglądu, proszę spróbować ponownie.</strong>\nJeśli to nie pomoże – spróbuj [[Special:UserLogout|wylogować się]] i zalogować ponownie, a także upewnij się, że twoja przeglądarka akceptuje ciasteczka z tej witryny.",
        "expand_templates_preview_fail_html_anon": "<em>Ponieważ {{SITENAME}} ma włączoną możliwość korzystania z surowego HTML a jesteś niezalogowany, podgląd został ukryty - jest to środek zapobiegawczy przeciwko atakom JavaScript.</em>\n\n<strong>Jeżeli jest to spodziewana próba podglądu, [[Special:UserLogin|zaloguj się]] i spróbuj ponownie.</strong>",
-       "expand_templates_input_missing": "Trzeba wpisać jakiś tekst.",
+       "expand_templates_input_missing": "Musisz podać jakiś wikitekst.",
        "pagelanguage": "Zmiana języka strony",
        "pagelang-name": "Strona",
        "pagelang-language": "Język",
index 4cd4ffa..2d92059 100644 (file)
                        "MaksimPinigin",
                        "Smigles",
                        "OlegCinema",
-                       "Movses"
+                       "Movses",
+                       "Patrick Star"
                ]
        },
        "tog-underline": "Подчёркивание ссылок:",
        "versionrequiredtext": "Для работы с этой страницей требуется MediaWiki версии $1. См. [[Special:Version|информацию об программном обеспечении]].",
        "ok": "OK",
        "pagetitle": "$1 — {{SITENAME}}",
+       "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
        "retrievedfrom": "Источник — «$1»",
        "youhavenewmessages": "Вы получили $1 ($2).",
        "page-rss-feed": "«$1» — RSS-лента",
        "page-atom-feed": "«$1» — Atom-лента",
        "feed-atom": "Atom",
+       "feed-rss": "Каналы RSS",
        "red-link-title": "$1 (страница не существует)",
        "sort-descending": "Упорядочить по убыванию",
        "sort-ascending": "Упорядочить по возрастанию",
        "nocookiesnew": "Участник зарегистрирован, но не представлен. {{SITENAME}} использует «cookies» для представления участников. У вас «cookies» запрещены. Пожалуйста, разрешите их, а затем представьтесь со своиим новым именем участника и паролем.",
        "nocookieslogin": "{{SITENAME}} использует «cookies» для представления участников. Вы их отключили. Пожалуйста, включите их и попробуйте снова.",
        "nocookiesfornew": "Учётная запись участника не была создана из-за невозможности проверить её источник. \nУбедитесь, что включены «cookies», обновите страницу и попробуйте ещё раз.",
+       "nocookiesforlogin": "{{int:nocookieslogin}}",
        "createacct-loginerror": "Учётная запись была успешно создана, но вы не смогли войти в систему автоматически. Пожалуйста, [[Special:UserLogin|авторизуйтесь вручную]].",
        "noname": "Вы не указали допустимого имени участника.",
        "loginsuccesstitle": "Вход произведён",
        "expansion-depth-exceeded-warning": "На странице превышен предел вложенности",
        "parser-unstrip-loop-warning": "Обнаружен незакрытый pre",
        "unstrip-depth-warning": "Превышен предел рекурсии ($1)",
+       "unstrip-depth-category": "Страницы где незаметная глубина превышена",
+       "unstrip-size-warning": "Unstrip превышен предел рекурсии ($1)",
+       "unstrip-size-category": "Страницы где незаметная разметка превышена",
        "converter-manual-rule-error": "Ошибка в ручном правиле преобразования языка",
        "undo-success": "Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.",
        "undo-failure": "Правка не может быть отменена из-за несовместимости промежуточных изменений.",
        "mergehistory-comment": "Перенос [[:$1]] в [[:$2]]: $3",
        "mergehistory-same-destination": "Исходная и целевая страницы должны различаться",
        "mergehistory-reason": "Причина:",
+       "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
        "mergelog": "Журнал объединений",
        "revertmerge": "Разделить",
        "mergelogpagetext": "Ниже приведён список последних объединений историй страниц.",
        "stub-threshold-disabled": "Отключён",
        "recentchangesdays": "Количество дней, за которые показывать свежие правки:",
        "recentchangesdays-max": "(не более $1 {{PLURAL:$1|дня|дней}})",
-       "recentchangescount": "Ð\9aолиÑ\87еÑ\81Ñ\82во Ð¿Ñ\80авок, Ð¾Ñ\82обÑ\80ажаемое Ð¿Ð¾ Ñ\83молÑ\87аниÑ\8e:",
-       "prefs-help-recentchangescount": "Ð\92клÑ\8eÑ\87аеÑ\82 Ñ\81вежие Ð¿Ñ\80авки, Ð¸Ñ\81Ñ\82оÑ\80ии Ñ\81Ñ\82Ñ\80аниÑ\86, Ð¶Ñ\83Ñ\80налÑ\8b.",
+       "recentchangescount": "Ð\9aолиÑ\87еÑ\81Ñ\82во Ð¿Ñ\80авок, Ð¿Ð¾ Ñ\83молÑ\87аниÑ\8e Ð¾Ñ\82обÑ\80ажаемое Ð² Ñ\81пиÑ\81ке Ñ\81вежиÑ\85 Ð¿Ñ\80авок, Ð¸Ñ\81Ñ\82оÑ\80ии Ñ\81Ñ\82Ñ\80аниÑ\86 Ð¸ Ð² Ð¶Ñ\83Ñ\80налаÑ\85:",
+       "prefs-help-recentchangescount": "Ð\9dаиболÑ\8cÑ\88ее Ð·Ð½Ð°Ñ\87ение: 1000",
        "prefs-help-watchlist-token2": "Это секретный ключ для веб-канала вашего списка наблюдений.\nЛюбой, кто знает его, сможет читать ваш список наблюдения, поэтому не сообщайте его другим.\nЕсли необходимо, [[Special:ResetTokens|вы можете сбросить его]].",
        "savedprefs": "Настройки сохранены.",
        "savedrights": "Группы {{GENDER:$1|участника|участницы}} $1 были сохранены.",
        "youremail": "Электронная почта:",
        "username": "{{GENDER:$1|Имя участника|Имя участницы}}:",
        "prefs-memberingroups": "{{GENDER:$2|Член|Член}} {{PLURAL:$1|1=группы|групп}}:",
+       "prefs-memberingroups-type": "$1",
        "group-membership-link-with-expiry": "$1 (до $2)",
        "prefs-registration": "Время регистрации:",
+       "prefs-registration-date-time": "$1",
        "yourrealname": "Настоящее имя:",
        "yourlanguage": "Язык интерфейса:",
        "yourvariant": "Вариант языка содержания:",
        "saveusergroups": "Сохранить группы {{GENDER:$1|участника|участницы}}",
        "userrights-groupsmember": "Состоит в группах:",
        "userrights-groupsmember-auto": "Неявно состоит в группах:",
+       "userrights-groupsmember-type": "$1",
        "userrights-groups-help": "Вы можете изменить группы, в которые входит {{GENDER:$1|этот участник|эта участница}}.\n* Если около названия группы стоит отметка — {{GENDER:$1|участник|участница}} входит в эту группу.\n* Если отметка не стоит — {{GENDER:$1|участник|участница}} не входит в эту группу.\n* Символ * указывает на то, что вы не сможете удалить {{GENDER:$1|участника|участницу}} из группы, если добавите {{GENDER:$1|его|её}} в неё (или наоборот).\n* Символ # указывает на то, что вы можете только отложить время истечения членства в этой группы, вы не можете перенести его на более ранний срок.",
        "userrights-reason": "Причина:",
        "userrights-no-interwiki": "У вас нет разрешения изменять права участников в других вики.",
        "userrights-nodatabase": "База данных $1 не существует или расположена не локально.",
        "userrights-changeable-col": "Группы, которые вы можете изменять",
        "userrights-unchangeable-col": "Группы, которые вы не можете изменять",
+       "userrights-irreversible-marker": "$1*",
+       "userrights-no-shorten-expiry-marker": "$1#",
        "userrights-expiry-current": "Истекает $1",
        "userrights-expiry-none": "Никогда",
        "userrights-expiry": "Права истекают:",
        "action-deletechangetags": "удаление меток из базы данных",
        "action-purge": "очистку кэша этой страницы",
        "nchanges": "$1 {{PLURAL:$1|изменение|изменения|изменений}}",
+       "ntimes": "$1×",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|с последнего посещения}}",
        "enhancedrc-history": "история",
        "recentchanges": "Свежие правки",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:not</strong> $1",
        "rcfilters-exclude-button-off": "Исключить выбранное",
        "rcfilters-exclude-button-on": "Исключение выбранного",
-       "rcfilters-view-tags": "ТегиÑ\80ованнÑ\8bе Ð¿Ñ\80авки",
+       "rcfilters-view-tags": "Ð\9fÑ\80авки Ñ\81 Ð¼ÐµÑ\82ками",
        "rcfilters-view-namespaces-tooltip": "Результаты фильтра по пространствам имён",
        "rcfilters-view-tags-tooltip": "Фильтровать результаты, используя метки правок",
        "rcfilters-view-return-to-default-tooltip": "Вернуться в главное меню фильтров",
-       "rcfilters-view-tags-help-icon-tooltip": "",
+       "rcfilters-view-tags-help-icon-tooltip": "Узнать больше о редакторе тегов",
        "rcfilters-liveupdates-button": "Обновлять автоматически",
        "rcfilters-liveupdates-button-title-on": "Отключить автоматические обновления",
        "rcfilters-liveupdates-button-title-off": "Показывать новые изменения сразу после их появления",
        "boteditletter": "б",
        "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|наблюдающий участник|наблюдающих участника|наблюдающих участников}}]",
+       "rc-change-size": "$1",
        "rc-change-size-new": "Размер после изменения: $1 {{PLURAL:$1|байт|байта|байт}}",
        "newsectionsummary": "/* $1 */ новая тема",
        "rc-enhanced-expand": "Показать подробности",
        "apisandbox-request-selectformat-label": "Показать данные запроса, как:",
        "apisandbox-request-format-url-label": "Строка URL-запроса",
        "apisandbox-request-url-label": "URL-адрес запроса:",
+       "apisandbox-request-format-json-label": "JSON",
        "apisandbox-request-json-label": "Запросить JSON:",
        "apisandbox-request-time": "Время запроса: {{PLURAL:$1|$1 мс}}",
        "apisandbox-results-fixtoken": "Исправьте токен и повторите отправку",
        "listgrants-summary": "Ниже приведён список разрешений с указанием на то, к каким связанным пользовательским правам они дают доступ. Участники могут разрешить приложениям использовать свою учётную запись, но с ограниченными правами на основе разрешений, которые участник предоставляет приложению. Однако, приложение, действующее  от имени участника, на самом деле не сможет воспользоваться правами, отсутствующими у учётной записи.\nОб отдельных правах можно получить [[{{MediaWiki:Listgrouprights-helppage}}|дополнительную  информацию]].",
        "listgrants-grant": "Разрешение",
        "listgrants-rights": "Права",
+       "listgrants-grant-display": "$1 <code>($2)</code>",
        "trackingcategories": "Отслеживающие категории",
        "trackingcategories-summary": "На этой странице перечислены категории, заполняемые автоматически. Их можно переименовать, изменив соответствующие системные сообщения в пространстве имён {{ns:8}}.",
        "trackingcategories-msg": "Отслеживаемая категория",
        "emailuserfooter": "Это письмо было отправлено {{GENDER:$2|участнику|участнице}} $2 от {{GENDER:$1|участника|участницы}} $1 с помощью функции «{{int:emailuser}}» проекта {{SITENAME}}. Если {{GENDER:$2|вы}} ответите на это письмо, оно будет отослано напрямую {{GENDER:$1|отправителю}}, так что {{GENDER:$2|ваш}} адрес электронной почты станет известен {{GENDER:$1|ему|ей}}.",
        "usermessage-summary": "Оставить системное сообщение.",
        "usermessage-editor": "Системная доставка",
+       "usermessage-template": "MediaWiki:UserMessage",
        "watchlist": "Список наблюдения",
        "mywatchlist": "Список наблюдения",
        "watchlistfor2": "Для $1 $2",
        "editcomment": "Было дано описание изменения: <em>$1</em>.",
        "revertpage": "Откат правок [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]]) к версии [[User:$1|$1]]",
        "revertpage-nouser": "Откат правок (имя участника скрыто) к версии {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Ð\9eÑ\82каÑ\87енÑ\8b Ð¿Ñ\80авки {{GENDER:$3|$1}}; возврат к версии {{GENDER:$4|$2}}.",
-       "rollback-success-notify": "Ð\9eÑ\82каÑ\87енÑ\8b Ð¿Ñ\80авки $1; Ð²Ð¾Ð·Ð²Ñ\80аÑ\82 Ðº Ð¿Ð¾Ñ\81ледней версии $2. [$3 Показать изменения]",
+       "rollback-success": "Ð\9eÑ\82каÑ\82 Ð¿Ñ\80авок {{GENDER:$3|$1}}; возврат к версии {{GENDER:$4|$2}}.",
+       "rollback-success-notify": "Ð\9eÑ\82каÑ\82 Ð¿Ñ\80авок $1; Ð²Ð¾Ð·Ð²Ñ\80аÑ\82 Ðº версии $2. [$3 Показать изменения]",
        "sessionfailure-title": "Ошибка сеанса",
        "sessionfailure": "Похоже, возникли проблемы с текущим сеансом работы;\nэто действие было отменено в целях предотвращения «захвата сеанса».\nПожалуйста, переотправьте форму.",
        "changecontentmodel": "Редактирование контентной модели страницы",
        "protect-fallback": "Разрешено только участникам с правами «$1»",
        "protect-level-autoconfirmed": "Разрешено только автоподтверждённым участникам",
        "protect-level-sysop": "Разрешено только администраторам",
+       "protect-summary-desc": "[$1=$2] ($3)",
        "protect-summary-cascade": "каскадная",
        "protect-expiring": "истекает $1 (UTC)",
        "protect-expiring-local": "истекает $1",
        "undelete-error-long": "Во время восстановления файла возникли ошибки:\n\n$1",
        "undelete-show-file-confirm": "Вы уверены, что желаете просмотреть удалённую версию файла <nowiki>$1</nowiki> от $2 $3?",
        "undelete-show-file-submit": "Да",
+       "undelete-revision-row2": "$1 ($2) $3 . . $4 $5 $6 $7 $8",
        "namespace": "Пространство имён:",
        "invert": "Обратить выбранное",
        "tooltip-invert": "Установите эту отметку, чтобы скрыть изменения на страницах, в пределах выбранного пространства имён (и связанных пространств имён, если указано)",
        "ip_range_invalid": "Недопустимый диапазон IP-адресов.",
        "ip_range_toolarge": "Блокировки диапазонов свыше /$1 запрещены.",
        "ip_range_exceeded": "IP-диапазон превышает максимальный диапазон. Допустимый диапазон: /$1.",
-       "ip_range_toolow": "",
+       "ip_range_toolow": "Диапазоны IP не разрешены.",
        "proxyblocker": "Блокировка прокси",
        "proxyblockreason": "Ваш IP-адрес заблокирован потому, что это открытый прокси-сервер. Пожалуйста, свяжитесь со своиим интернет-провайдером или службой поддержки, и сообщите им об этой серьёзной проблеме безопасности.",
+       "sorbs": "DNSBL",
        "sorbsreason": "Ваш IP-адрес числится как открытый прокси в DNSBL.",
        "sorbs_create_account_reason": "Ваш IP-адрес числится как открытый прокси в DNSBL. Вы не можете создать учётную запись.",
        "softblockrangesreason": "Анонимные правки не разрешены с вашего IP-адреса ($1). Пожалуйста, войдите в систему.",
        "tooltip-preferences-save": "Сохранить настройки",
        "tooltip-summary": "Введите краткое описание",
        "interlanguage-link-title": "$1 — $2",
+       "interlanguage-link-title-nonlang": "$1 – $2",
        "common.css": "/* Размещённый здесь CSS будет применяться ко всем темам оформления */",
        "print.css": "/* Размещённый здесь CSS будет применяться к версии для печати */",
        "noscript.css": "/* Размещённый здесь CSS будет применяться для участников с отключенным JavaScript  */",
        "yesterday-at": "Вчера в $1",
        "bad_image_list": "Формат должен быть следующим:\n\nБудут учитываться только элементы списка (строки, начинающиеся на символ *).\nПервая ссылка строки должна быть ссылкой на запрещённое для вставки изображение.\nПоследующие ссылки в той же строке будут рассматриваться как исключения, то есть статьи, куда изображение может быть включено.",
        "variantname-zh-hans": "hans",
+       "variantname-zh-hant": "hant",
+       "variantname-zh-cn": "cn",
+       "variantname-zh-tw": "tw",
+       "variantname-zh-hk": "hk",
+       "variantname-zh-mo": "mo",
+       "variantname-zh-sg": "sg",
+       "variantname-zh-my": "my",
+       "variantname-zh": "zh",
+       "variantname-gan-hans": "hans",
+       "variantname-gan-hant": "hant",
+       "variantname-gan": "gan",
+       "variantname-sr-ec": "sr-ec",
+       "variantname-sr-el": "sr-el",
+       "variantname-sr": "sr",
+       "variantname-kk-kz": "kk-kz",
+       "variantname-kk-tr": "kk-tr",
+       "variantname-kk-cn": "kk-cn",
+       "variantname-kk-cyrl": "kk-cyrl",
+       "variantname-kk-latn": "kk-latn",
+       "variantname-kk-arab": "kk-arab",
+       "variantname-kk": "kk",
+       "variantname-ku-arab": "ku-Arab",
+       "variantname-ku-latn": "ku-Latn",
+       "variantname-ku": "ku",
+       "variantname-tg-cyrl": "tg-Cyrl",
+       "variantname-tg-latn": "tg-Latn",
+       "variantname-tg": "tg",
+       "variantname-ike-cans": "ike-Cans",
+       "variantname-ike-latn": "ike-Latn",
+       "variantname-iu": "iu",
+       "variantname-shi-tfng": "shi-Tfng",
+       "variantname-shi-latn": "shi-Latn",
+       "variantname-shi": "shi",
+       "variantname-uz": "uz",
+       "variantname-uz-latn": "uz-Latn",
+       "variantname-uz-cyrl": "uz-Cyrl",
+       "variantname-crh": "crh",
+       "variantname-crh-latn": "crh-Latn",
+       "variantname-crh-cyrl": "crh-Cyrl",
        "metadata": "Метаданные",
        "metadata-help": "Файл содержит дополнительные данные, обычно добавляемые цифровыми камерами или сканерами. Если файл после создания редактировался, то некоторые параметры могут не соответствовать текущему изображению.",
        "metadata-expand": "Показать дополнительные данные",
        "metadata-collapse": "Скрыть дополнительные данные",
        "metadata-fields": "Поля метаданных изображения, перечисленные в этом списке, будут показаны на странице изображения при свёрнутой таблице метаданных. Остальные поля будут по умолчанию скрыты.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "metadata-langitem": "<strong>$2:</strong> $1",
+       "metadata-langitem-default": "$1",
        "exif-imagewidth": "Ширина",
        "exif-imagelength": "Высота",
        "exif-bitspersample": "Глубина цвета",
        "exif-exposuretime": "Время экспозиции",
        "exif-exposuretime-format": "$1 с ($2)",
        "exif-fnumber": "Число диафрагмы",
+       "exif-fnumber-format": "f/$1",
        "exif-exposureprogram": "Программа экспозиции",
        "exif-spectralsensitivity": "Спектральная чувствительность",
        "exif-isospeedratings": "Светочувствительность ISO",
        "exif-gpsareainformation": "Название области GPS",
        "exif-gpsdatestamp": "Дата",
        "exif-gpsdifferential": "Дифференциальная поправка",
+       "exif-coordinate-format": "$1° $2′ $3″ $4",
        "exif-jpegfilecomment": "Примечание JPEG-файла",
        "exif-keywords": "Ключевые слова",
        "exif-worldregioncreated": "Регион мира, где была сделана фотография",
        "exif-personinimage": "Изображённый человек",
        "exif-originalimageheight": "Высота изображения до кадрирования",
        "exif-originalimagewidth": "Ширина изображения до кадрирования",
+       "exif-contact-value": "$1\n\n$2\n<div class=\"adr\">\n$3\n\n$4, $5, $6 $7\n</div>\n$8",
+       "exif-subjectnewscode-value": "$2 ($1)",
        "exif-compression-1": "Несжатый",
        "exif-compression-2": "CCITT Group 3, 1-мерная модификация кодирования длин серий Хаффмана",
        "exif-compression-3": "CCITT Group 3, факсовое кодирование",
        "exif-compression-5": "LZW",
        "exif-compression-6": "JPEG (старый)",
        "exif-compression-7": "JPEG",
+       "exif-compression-8": "Deflate (Adobe)",
+       "exif-compression-32773": "PackBits (Macintosh RLE)",
+       "exif-compression-32946": "Deflate (PKZIP)",
+       "exif-compression-34712": "JPEG2000",
        "exif-copyrighted-true": "Охраняется авторским правом",
        "exif-copyrighted-false": "Авторско-правовой статус не задан",
        "exif-photometricinterpretation-0": "Чёрный и белый (белый — 0)",
        "exif-photometricinterpretation-1": "Чёрный и белый (чёрный — 0)",
+       "exif-photometricinterpretation-2": "RGB",
+       "exif-photometricinterpretation-3": "Palette",
        "exif-photometricinterpretation-4": "Маска прозрачности",
        "exif-photometricinterpretation-5": "Разделены (вероятно CMYK)",
+       "exif-photometricinterpretation-6": "YCbCr",
+       "exif-photometricinterpretation-8": "CIE L*a*b*",
+       "exif-photometricinterpretation-9": "CIE L*a*b* (ICC encoding)",
+       "exif-photometricinterpretation-10": "CIE L*a*b* (ITU encoding)",
+       "exif-photometricinterpretation-32803": "Color Filter Array",
+       "exif-photometricinterpretation-34892": "Linear raw",
        "exif-unknowndate": "Неизвестная дата",
        "exif-orientation-1": "Нормальная",
        "exif-orientation-2": "Отражено по горизонтали",
        "exif-planarconfiguration-2": "формат «planar»",
        "exif-xyresolution-i": "$1 точек на дюйм",
        "exif-xyresolution-c": "$1 точек на сантиметр",
+       "exif-colorspace-1": "sRGB",
        "exif-colorspace-65535": "Некалиброванное",
        "exif-componentsconfiguration-0": "не существует",
+       "exif-componentsconfiguration-1": "Y",
+       "exif-componentsconfiguration-2": "Cb",
+       "exif-componentsconfiguration-3": "Cr",
+       "exif-componentsconfiguration-4": "R",
+       "exif-componentsconfiguration-5": "G",
+       "exif-componentsconfiguration-6": "B",
        "exif-exposureprogram-0": "Неизвестно",
        "exif-exposureprogram-1": "Ручной режим",
        "exif-exposureprogram-2": "Программный режим (нормальный)",
        "exif-lightsource-17": "Стандартный источник света типа A",
        "exif-lightsource-18": "Стандартный источник света типа B",
        "exif-lightsource-19": "Стандартный источник света типа C",
+       "exif-lightsource-20": "D55",
+       "exif-lightsource-21": "D65",
+       "exif-lightsource-22": "D75",
+       "exif-lightsource-23": "D50",
        "exif-lightsource-24": "Студийная лампа стандарта ISO",
        "exif-lightsource-255": "Другой источник света",
        "exif-flash-fired-0": "Вспышка не срабатывала",
        "exif-dc-type": "Тип медиафайла",
        "exif-rating-rejected": "Отклонено",
        "exif-isospeedratings-overflow": "Более 65535",
+       "exif-maxaperturevalue-value": "$1 APEX (f/$2)",
        "exif-iimcategory-ace": "Искусство, культура и развлечения",
        "exif-iimcategory-clj": "Преступность и закон",
        "exif-iimcategory-dis": "Катастрофы и аварии",
        "confirm-unwatch-top": "Удалить эту страницу из вашего списка наблюдения?",
        "confirm-rollback-button": "ОК",
        "confirm-rollback-top": "Откатить правки на этой странице?",
+       "semicolon-separator": ";&#32;",
+       "comma-separator": ",&#32;",
+       "colon-separator": ":&#32;",
        "pipe-separator": "&#32;|&#32;",
        "word-separator": "&#32;",
        "ellipsis": "…",
+       "percent": "$1%",
        "parentheses": "($1)",
+       "brackets": "[$1]",
        "quotation-marks": "«$1»",
        "imgmultipageprev": "← предыдущая страница",
        "imgmultipagenext": "следующая страница →",
        "imgmultigo": "Перейти!",
        "imgmultigoto": "Перейти на страницу $1",
+       "img-lang-opt": "$2 ($1)",
        "img-lang-default": "(язык по умолчанию)",
        "img-lang-info": "Показать это изображение на языке $1 $2",
        "img-lang-go": "Применить",
        "size-zetabytes": "$1 ЗБ",
        "size-yottabytes": "$1 ИБ",
        "size-pixel": "$1 {{PLURAL:$1|пиксель|пикселя|пикселей}}",
+       "size-kilopixel": "$1 KP",
+       "size-megapixel": "$1 MP",
+       "size-gigapixel": "$1 GP",
+       "size-terapixel": "$1 TP",
+       "size-petapixel": "$1 PP",
+       "size-exapixel": "$1 EP",
+       "size-zetapixel": "$1 ZP",
+       "size-yottapixel": "$1 YP",
        "bitrate-bits": "$1 б/с",
        "bitrate-kilobits": "$1 Кб/с",
        "bitrate-megabits": "$1 Мб/с",
        "limitreport-expansiondepth-value": "$1/$2",
        "limitreport-expensivefunctioncount": "Количество «дорогих» функций анализатора",
        "limitreport-expensivefunctioncount-value": "$1/$2",
+       "limitreport-unstrip-depth": "Глубинная рекурсия Unstrip",
+       "limitreport-unstrip-depth-value": "$1/$2",
+       "limitreport-unstrip-size": "После расширения размер Unstrip",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|байт|байта|байт}}",
        "expandtemplates": "Развёртка шаблонов",
        "expand_templates_intro": "Эта служебная страница преобразует текст, рекурсивно разворачивая все шаблоны в нём.\nТакже развёртке подвергаются функции парсера\n<code><nowiki>{{#language:…}}</nowiki></code> и переменные вида\n<code><nowiki>{{CURRENTDAY}}</nowiki></code> — в общем, всё внутри двойных фигурных скобок.",
        "mediastatistics-header-text": "Текстовые",
        "mediastatistics-header-executable": "Исполняемые",
        "mediastatistics-header-archive": "Сжатые форматы",
+       "mediastatistics-header-3d": "3D",
        "mediastatistics-header-total": "Все файлы",
        "json-warn-trailing-comma": "$1 {{PLURAL:$1|лишняя запятая в конце была удалена|лишние запятые в конце были удалены|лишних запятых в конце были удалены}} из JSON",
        "json-error-unknown": "Имеется проблема с JSON. Ошибка: $1",
index 0e60c0f..5c74690 100644 (file)
@@ -14,7 +14,8 @@
                        "לערי ריינהארט",
                        "아라",
                        "Pippinu",
-                       "Macofe"
+                       "Macofe",
+                       "S4b1nuz E.656"
                ]
        },
        "tog-underline": "Suttalìnia li lijami:",
        "sig_tip": "La tò firma cu data e ura",
        "hr_tip": "Lìnia urizzuntali (usari cu giudizziu)",
        "summary": "Riassuntu:",
-       "subject": "Oggettu/ntistazzioni:",
+       "subject": "Oggettu:",
        "minoredit": "Chistu è nu canciamentu nicu",
        "watchthis": "Talìa sta pàggina",
        "savearticle": "Sarva la pàggina",
        "contributions": "Cuntribbuti di l'{{GENDER:$1|utenti}}",
        "contributions-title": "Cuntribbuti di l'utenti $1",
        "mycontris": "Li mè cuntribbuti",
+       "anoncontribs": "cuntribbuti",
        "contribsub2": "Di {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Lu cuntu utenti \"$1\" nun è riggistratu.",
        "nocontribs": "Nuddu canciamentu fu attruvatu chi currispunni a sti criterî.",
        "javascripttest": "Virìfichi JavaScript",
        "javascripttest-pagetext-unknownaction": "Azzioni scanusciuta \"$1\".",
        "javascripttest-qunit-intro": "Talìa [$1 la ducumintazzioni a prupositu dî virìfichi] supra a mediawiki.org.",
-       "tooltip-pt-userpage": "La  pàggina utenti",
+       "tooltip-pt-userpage": "La {{GENDER:|tò}} pàggina utenti",
        "tooltip-pt-anonuserpage": "La pàggina utenti di stu ndirizzu IP",
-       "tooltip-pt-mytalk": "La to' pàggina di discussioni",
+       "tooltip-pt-mytalk": "La {{GENDER:|tò}} pàggina di discussioni",
        "tooltip-pt-anontalk": "Discussioni supra li canciamenti fatti di stu ndirizzu IP",
-       "tooltip-pt-preferences": "Li  prifirenzi",
+       "tooltip-pt-preferences": "Li {{GENDER:|mè}} prifirenzi",
        "tooltip-pt-watchlist": "La lista dî pàggini ca stai tinennu sutta ossirvazzioni",
-       "tooltip-pt-mycontris": "La lista dî  cuntribbuti",
+       "tooltip-pt-mycontris": "La lista dî {{GENDER:|tò}} cuntribbuti",
        "tooltip-pt-login": "La riggistrazzioni è cunzigghiata, puru siddu nun obbrigatoria.",
        "tooltip-pt-logout": "Nisciuta",
        "tooltip-pt-createaccount": "Sî nvitatu a criari nu cuntu e tràsiri; pirò nun è obbligatoriu",
        "feedback-thanks": "Grazzî! Lu tò cummentu fu affissu ntâ pàggina \"[$2 $1]\".",
        "feedback-thanks-title": "Ti ringrazziamu!",
        "feedback-useragent": "Aggenti di l'utenti:",
-       "searchsuggest-search": "Arricerca",
+       "searchsuggest-search": "Arricerca nta {{SITENAME}}",
        "searchsuggest-containing": "chi cunteni...",
        "api-error-badtoken": "Erruri nternu: Token sbagghiatu",
        "api-error-emptypage": "Criari pàggini novi e vacanti nun è cunzintutu.",
index b1c9b12..3fbb53f 100644 (file)
@@ -36,7 +36,8 @@
                        "Obsuser",
                        "Prevodim",
                        "Acamicamacaraca",
-                       "BokicaK"
+                       "BokicaK",
+                       "BadDog"
                ]
        },
        "tog-underline": "Подвлачење веза:",
        "tog-norollbackdiff": "Не приказуј разлику након извршеног враћања",
        "tog-useeditwarning": "Упозори ме када напуштам страницу са несачуваним изменама",
        "tog-prefershttps": "Увек користи сигурну везу док сам пријављен.",
-       "underline-always": "Увек",
-       "underline-never": "Ð\9dикад",
-       "underline-default": "Ð\9fрема теми или прегледачу",
+       "underline-always": "увек",
+       "underline-never": "никад",
+       "underline-default": "према теми или прегледачу",
        "editfont-style": "Стил фонта у оквиру за уређивање:",
-       "editfont-monospace": "Сразмерно широк фонт",
-       "editfont-sansserif": "Ð\91есерифни фонт",
-       "editfont-serif": "Серифни фонт",
+       "editfont-monospace": "сразмерно широк фонт",
+       "editfont-sansserif": "бесерифни фонт",
+       "editfont-serif": "серифни фонт",
        "sunday": "недеља",
        "monday": "понедељак",
        "tuesday": "уторак",
        "july-date": "$1. јул",
        "august-date": "$1. август",
        "september-date": "$1. септембар",
-       "october-date": "$1. окотобар",
+       "october-date": "$1. октобар",
        "november-date": "$1. новембар",
        "december-date": "$1. децембар",
        "period-am": "преподне",
        "index-category": "Пописане странице",
        "noindex-category": "Непописане странице",
        "broken-file-category": "Странице с неисправним везама до датотека",
+       "categoryviewer-pagedlinks": "$1 ($2)",
+       "category-header-numerals": "$1–$2",
        "about": "О нама",
        "article": "Чланак",
        "newwindow": "(отвара се у новом прозору)",
        "returnto": "Назад на $1.",
        "tagline": "Извор: {{SITENAME}}",
        "help": "Помоћ",
-       "search": "Ð\9fÑ\80еÑ\82Ñ\80ажи",
+       "search": "Ð\9fÑ\80еÑ\82Ñ\80ага",
        "search-ignored-headings": " #<!-- не мењајте ништа у овом реду --> <pre>\n# Наслови који ће бити занемарени при претрази.\n# Измене су видљиве одмах након што се страница са насловом попише.\n# Можете изнудити поновно пописивање „нултом” изменом.\n# Синтакса је следећа:\n#  * Сваки ред који започиње знаком „#” је коментар.\n#  * Сваки не празни ред је тачан наслов који ће бити занемарен, с тим да се разликују мала и велика слова и све остало\nРеференце\nСпољашње везе\nТакође погледајте\n #</pre> <!-- не мењајте ништа у овом реду -->",
        "searchbutton": "Претражи",
        "go": "Иди",
        "welcomecreation-msg": "Ваш налог је отворен.\nНе заборавите да промените своја [[Special:Preferences|подешавања]].",
        "yourname": "Корисничко име:",
        "userlogin-yourname": "Корисничко име",
-       "userlogin-yourname-ph": "Унесите ваше корисничко име",
+       "userlogin-yourname-ph": "Унесите своје корисничко име",
        "createacct-another-username-ph": "Унесите корисничко име",
        "yourpassword": "Лозинка:",
        "userlogin-yourpassword": "Лозинка",
-       "userlogin-yourpassword-ph": "Унесите вашу лозинку",
+       "userlogin-yourpassword-ph": "Унесите своју лозинку",
        "createacct-yourpassword-ph": "Унесите лозинку",
        "yourpasswordagain": "Поново унеси лозинку:",
        "createacct-yourpasswordagain": "Потврди лозинку",
        "userexists": "Корисничко име је заузето. Изаберите друго.",
        "loginerror": "Грешка при пријављивању",
        "createacct-error": "Дошло је до грешке при отварању налога",
-       "createaccounterror": "Не могу да отворим налог: $1",
+       "createaccounterror": "Не могу да отворим налог: $1.",
        "nocookiesnew": "Кориснички налог је отворен, али нисте пријављени.\n{{SITENAME}} користи колачиће за пријаву. Вама су колачићи онемогућени.\nОмогућите их, па се онда пријавите са својим корисничким именом и лозинком.",
        "nocookieslogin": "{{SITENAME}} користи колачиће за пријављивање корисника.\nВама су колачићи онемогућени. Омогућите их и покушајте поново.",
        "nocookiesfornew": "Кориснички налог није отворен јер његов извор није потврђен.\nОмогућите колачиће на прегледачу и поново учитајте страницу.",
        "resetpass-no-info": "Морате бити пријављени да бисте приступили овој страници.",
        "resetpass-submit-loggedin": "Промени лозинку",
        "resetpass-submit-cancel": "Откажи",
-       "resetpass-wrong-oldpass": "Неисправна привремена или текућа лозинка.\nМожда сте већ променили лозинку или сте затражили нову привремену лозинку.",
+       "resetpass-wrong-oldpass": "Неисправна привремена или тренутна лозинка.\nМожда сте већ променили лозинку или сте затражили нову привремену лозинку.",
        "resetpass-recycled": "Унели сте садашњу лозинку, да бисте ресетовали лозинку морате унети нову.",
        "resetpass-temp-emailed": "Пријавили сте се са привременим кодом из имејла.\nДа бисте завршили пријављивање морате поставити нову лозинку овде:",
        "resetpass-temp-password": "Привремена лозинка:",
        "blockednoreason": "разлог није наведен",
        "whitelistedittext": "За уређивање странице је потребно да будете $1.",
        "confirmedittext": "Морате да потврдите своју имејл адресу пре уређивања страница.\nПоставите и потврдите имејл адресу преко [[Special:Preferences|подешавања]].",
-       "nosuchsectiontitle": "Не могу да пронађем одељак",
+       "nosuchsectiontitle": "Не могу да пронађем одељак.",
        "nosuchsectiontext": "Покушали сте да уредите одељак који не постоји.\nМожда је премештен или обрисан док сте прегледали страницу.",
        "loginreqtitle": "Потребна је пријава",
        "loginreqlink": "пријављени",
        "semiprotectedpagewarning": "<strong>Напомена:</strong> Ова страница је заштићена, тако да само регистровани корисници могу да је уређују.\nПоследњи запис у дневнику је приказан испод:",
        "cascadeprotectedwarning": "<strong>Упозорење:</strong> Ова страница је заштићена тако да је могу уређивати само корисници са [[Special:ListGroupRights|одређеним правима]] (администратори), јер је иста укључена у {{PLURAL:$1|следећу страницу која је заштићена|следеће странице које су заштићене}} „преносивом” заштитом:",
        "titleprotectedwarning": "<strong>Упозорење: ову страницу могу направити само корисници [[Special:ListGroupRights|с одређеним правима]].</strong>\nПоследњи запис у дневнику је приказан испод:",
-       "templatesused": "{{PLURAL:$1|Шаблон|Шаблони}} на овој страници:",
+       "templatesused": "{{PLURAL:$1|Шаблон који се користи|Шаблони који се користе}} на овој страници:",
        "templatesusedpreview": "{{PLURAL:$1|Шаблон|Шаблони}} у овом претпрегледу:",
        "templatesusedsection": "{{PLURAL:$1|Шаблон|Шаблони}} у овом одељку:",
        "template-protected": "(заштићено)",
        "viewpagelogs": "Дневници ове странице",
        "nohistory": "Не постоји историја измена ове странице.",
        "currentrev": "Тренутна измена",
-       "currentrev-asof": "ТÑ\80енÑ\83Ñ\82на Ð¸Ð·Ð¼ÐµÐ½Ð° Ð¾Ð´ $2 у $3",
+       "currentrev-asof": "Ð\9fоÑ\81ледÑ\9aа Ð²ÐµÑ\80зиÑ\98а Ð½Ð° Ð´Ð°Ñ\82Ñ\83м $2 у $3",
        "revisionasof": "Измена од $2 у $3",
        "revision-info": "Измена од $1 коју је {{GENDER:$6|уредио $2|уредила $2}}$7",
        "previousrevision": "← Старија измена",
        "stub-threshold-disabled": "онемогућено",
        "recentchangesdays": "Број дана у скорашњим изменама:",
        "recentchangesdays-max": "Највише $1 {{PLURAL:$1|дан|дана}}",
-       "recentchangescount": "Ð\91Ñ\80оÑ\98 Ð¸Ð·Ð¼ÐµÐ½Ð° Ð·Ð° Ð¿Ñ\80иказ:",
-       "prefs-help-recentchangescount": "Ð\9fодÑ\80азÑ\83мева Ñ\81коÑ\80аÑ\88Ñ\9aе Ð¸Ð·Ð¼ÐµÐ½Ðµ, Ð¸Ñ\81Ñ\82оÑ\80иÑ\98е Ñ\81Ñ\82Ñ\80аниÑ\86а Ð¸ Ð´Ð½ÐµÐ²Ð½Ð¸ÐºÐµ.",
+       "recentchangescount": "Ð\9fодÑ\80азÑ\83мевани Ð±Ñ\80оÑ\98 Ð¸Ð·Ð¼ÐµÐ½Ð° Ð·Ð° Ð¿Ñ\80иказ Ñ\83 Ñ\81коÑ\80аÑ\88Ñ\9aим Ð¸Ð·Ð¼ÐµÐ½Ð°Ð¼Ð°, Ð¸Ñ\81Ñ\82оÑ\80иÑ\98ама Ñ\81Ñ\82Ñ\80аниÑ\86а Ð¸ Ð´Ð½ÐµÐ²Ð½Ð¸Ñ\86има:",
+       "prefs-help-recentchangescount": "Ð\9dаÑ\98веÑ\9bа Ð²Ñ\80едноÑ\81Ñ\82: 1000",
        "prefs-help-watchlist-token2": "Ово је тајни кључ за веб-довод Вашег списка надгледања. \nСвако ко зна овај кључ биће у могућности да види Ваш списак надгледања, зато кључ немојте одавати никоме. \nАко је потребно, кључ [[Special:ResetTokens|можете ресетовати]].",
        "savedprefs": "Ваша подешавања су сачувана.",
        "savedrights": "Корисничке групе за {{GENDER:$1|$1}} су сачуване.",
        "recentchanges-legend": "Опције скорашњих измена",
        "recentchanges-summary": "Пратите скорашње измене на овој страници.",
        "recentchanges-noresult": "Нема измена у задатом периоду који одговарају овим критеријумима.",
+       "recentchanges-timeout": "Ова претрага је истекла. Можда желите да покушате другачије параметре претраге.",
+       "recentchanges-network": "Због техничког проблема не могу да учитам резултате. Покушајте поновно да учитате страницу.",
        "recentchanges-notargetpage": "Унесите назив странице како бисте видели сродне измене.",
        "recentchanges-feed-description": "Пратите скорашње измене уз помоћ овог довода.",
        "recentchanges-label-newpage": "Нова страница",
        "recentchanges-label-unpatrolled": "Непатролирана измена",
        "recentchanges-label-plusminus": "Промена величине странице у бајтовима",
        "recentchanges-legend-heading": "<strong>Легенда:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|списак нових страница]])",
+       "recentchanges-legend-newpage": "[[w:sr:Посебно:НовеСтране|<u>Н</u>ова страница]]",
        "recentchanges-submit": "Прикажи",
-       "rcfilters-tag-remove": "Ð\9eбÑ\80иÑ\88и $1",
-       "rcfilters-legend-heading": "<strong>Списак скраћеница:</strong>",
+       "rcfilters-tag-remove": "УклониÑ\82е Ñ\84илÑ\82еÑ\80 â\80\9e$1â\80\9d",
+       "rcfilters-legend-heading": "\n<strong>Списак скраћеница ([[w:sr:Помоћ:Надгледање страница|помоћ]]):<strong>",
        "rcfilters-other-review-tools": "Остале алатке за преглед",
        "rcfilters-group-results-by-page": "Групиши резултате по страницама",
        "rcfilters-activefilters": "Активни филтери",
        "rcfilters-advancedfilters": "Напредни филтери",
-       "rcfilters-limit-title": "Ð\98змена за приказ",
+       "rcfilters-limit-title": "Ð\91Ñ\80оÑ\98 Ð¸змена за приказ",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|измена|измене|измена}}, $2",
        "rcfilters-date-popup-title": "Временски период",
        "rcfilters-days-title": "Скорашњи дани",
-       "rcfilters-hours-title": "СкоÑ\80аÑ\88Ñ\9aе сати",
+       "rcfilters-hours-title": "СкоÑ\80аÑ\88Ñ\9aи сати",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|дан|дана}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|сат|сата}}",
        "rcfilters-highlighted-filters-list": "Истакнуто: $1",
        "rcfilters-savedqueries-unsetdefault": "Уклони као подразумевано",
        "rcfilters-savedqueries-remove": "Уклони",
        "rcfilters-savedqueries-new-name-label": "Име",
-       "rcfilters-savedqueries-new-name-placeholder": "Опиши сврху филтера",
+       "rcfilters-savedqueries-new-name-placeholder": "Опишите сврху филтера",
        "rcfilters-savedqueries-apply-label": "Направи филтер",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Направи подразумевани филтер",
        "rcfilters-savedqueries-cancel-label": "Откажи",
-       "rcfilters-savedqueries-add-new-title": "Сачувај тренутна подешавања филтера",
+       "rcfilters-savedqueries-add-new-title": "Сачувајте тренутна подешавања филтера",
        "rcfilters-savedqueries-already-saved": "Ови филтери су већ сачувани. Измените Ваша подешавања како бисте направили нове сачуване филтере.",
        "rcfilters-restore-default-filters": "Враћање подразумеваних филтера",
-       "rcfilters-clear-all-filters": "Уклони све филтере",
+       "rcfilters-clear-all-filters": "Уклоните све филтере",
        "rcfilters-show-new-changes": "Погледај најновије измене",
-       "rcfilters-search-placeholder": "Филтрирај измене (користите мени или претрагу за име филтера)",
+       "rcfilters-search-placeholder": "Филтрирајте измене (користите мени или претрагу за име филтера)",
        "rcfilters-invalid-filter": "Неисправан филтер",
        "rcfilters-empty-filter": "Нема активних филтера. Сви доприноси су приказани.",
        "rcfilters-filterlist-title": "Филтери",
        "rcfilters-filterlist-whatsthis": "Како ово функционише?",
-       "rcfilters-filterlist-feedbacklink": "Ð\9fоделиÑ\82е Ð²Ð°Ñ\88е Ð¼Ð¸Ñ\88Ñ\99еÑ\9aе Ð¾ (новим) Ð°Ð»Ð°Ñ\82има за филтрирање",
+       "rcfilters-filterlist-feedbacklink": "РеÑ\86иÑ\82е Ð½Ð°Ð¼ Ñ\88Ñ\82а Ð¼Ð¸Ñ\81лиÑ\82е Ð¾ Ð¾Ð²Ð¸Ð¼ (новим) Ð°Ð»Ð°Ñ\82кама за филтрирање",
        "rcfilters-highlightbutton-title": "Истакни резултате",
        "rcfilters-highlightmenu-title": "Одабери боју",
        "rcfilters-highlightmenu-help": "Изаберите боју да бисте истакнули ово својство",
        "rcfilters-filtergroup-authorship": "Ауторство доприноса",
        "rcfilters-filter-editsbyself-label": "Ваше измене",
        "rcfilters-filter-editsbyself-description": "Ваши доприноси.",
-       "rcfilters-filter-editsbyother-label": "Измјене других",
+       "rcfilters-filter-editsbyother-label": "Измене других",
        "rcfilters-filter-editsbyother-description": "Све измене осим Ваших.",
        "rcfilters-filtergroup-userExpLevel": "Корисничка регистрација и искуство",
        "rcfilters-filter-user-experience-level-registered-label": "Регистровани",
        "rcfilters-filter-user-experience-level-experienced-description": "Регистровани уредници са више од 500 измена и 30 дана активности.",
        "rcfilters-filtergroup-automated": "Аутоматизовани доприноси",
        "rcfilters-filter-bots-label": "Бот",
-       "rcfilters-filter-bots-description": "Измјене направљене аутоматизованим алатима.",
+       "rcfilters-filter-bots-description": "Измене направљене аутоматизованим алатима.",
        "rcfilters-filter-humans-label": "Човек (није бот)",
-       "rcfilters-filter-humans-description": "Измјене које су направили људи-уредници.",
+       "rcfilters-filter-humans-description": "Измене које су направили људи-уредници.",
        "rcfilters-filtergroup-reviewstatus": "Патролираност",
        "rcfilters-filter-patrolled-label": "Патролирано",
-       "rcfilters-filter-patrolled-description": "Измјене означене као патролиране.",
+       "rcfilters-filter-patrolled-description": "Измене означене као патролиране.",
        "rcfilters-filter-unpatrolled-label": "Непатролирано",
-       "rcfilters-filter-unpatrolled-description": "Измјене које нису означене као патролиране.",
+       "rcfilters-filter-unpatrolled-description": "Измене које нису означене као патролиране.",
        "rcfilters-filtergroup-significance": "Значај",
        "rcfilters-filter-minor-label": "Мање измене",
-       "rcfilters-filter-minor-description": "Измјене које је аутор означио као мање.",
+       "rcfilters-filter-minor-description": "Измене које је аутор означио као мање.",
        "rcfilters-filter-major-label": "Не-мање измене",
-       "rcfilters-filter-major-description": "Измјене које нису означене као мање.",
+       "rcfilters-filter-major-description": "Измене које нису означене као мање.",
        "rcfilters-filtergroup-watchlist": "Странице на списку надгледања",
        "rcfilters-filter-watchlist-watched-label": "На списку надгледања",
-       "rcfilters-filter-watchlist-watched-description": "Измјене страница на Вашем списку надгледања.",
+       "rcfilters-filter-watchlist-watched-description": "Измене страница на Вашем списку надгледања.",
        "rcfilters-filter-watchlist-watchednew-label": "Нове измене на списку надгледања",
-       "rcfilters-filter-watchlist-watchednew-description": "Измјене страница на списку надгледања које нисте посјетили од када су направљене измене.",
+       "rcfilters-filter-watchlist-watchednew-description": "Измене страница на списку надгледања које нисте посетили од када су направљене измене.",
        "rcfilters-filter-watchlist-notwatched-label": "Није на списку надгледања",
        "rcfilters-filter-watchlist-notwatched-description": "Све осим измена страница на Вашем списку надгледања.",
        "rcfilters-filtergroup-watchlistactivity": "Стање на списку надгледања",
        "rcfilters-filter-watchlistactivity-seen-description": "Измене страница које сте посетили од када су направљене измене.",
        "rcfilters-filtergroup-changetype": "Тип измене",
        "rcfilters-filter-pageedits-label": "Измене страница",
-       "rcfilters-filter-pageedits-description": "Измјене вики садржаја, расправа, описа категорија…",
+       "rcfilters-filter-pageedits-description": "Измене вики садржаја, расправа, описа категорија…",
        "rcfilters-filter-newpages-label": "Стварање страница",
        "rcfilters-filter-newpages-description": "Измене којима се стварају нове странице.",
-       "rcfilters-filter-categorization-label": "Измјене категорија",
+       "rcfilters-filter-categorization-label": "Измене категорија",
        "rcfilters-filter-categorization-description": "Записи о страницама додатим или уклоњеним из категорија.",
        "rcfilters-filter-logactions-label": "Радње забележене у дневницима",
        "rcfilters-filter-logactions-description": "Административне радње, стварање налога, брисање страница, отпремања…",
        "rcfilters-hideminor-conflicts-typeofchange-global": "Филтер за „мање” измене је у сукобу са једним или више филтера типа измена, зато што одређени типови измена не могу да се означе као „мање”. Сукобљени филтери су означени у подручју Активни филтери, изнад.",
        "rcfilters-hideminor-conflicts-typeofchange": "Одређени типови измена не могу да се означе као „мање”, тако да је овај филтер у сукобу са следећим филтерима типа измена: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "Овај филтер типа измене је у сукобу са филтером за „мање” измене. Одређени типови измена не могу да се означе као „мање”.",
-       "rcfilters-filtergroup-lastRevision": "Посљедње измене",
-       "rcfilters-filter-lastrevision-label": "Посљедња измена",
+       "rcfilters-filtergroup-lastRevision": "Последње измене",
+       "rcfilters-filter-lastrevision-label": "Последња измена",
        "rcfilters-filter-lastrevision-description": "Само најновија измена на страници.",
        "rcfilters-filter-previousrevision-label": "Није последња измена",
        "rcfilters-filter-previousrevision-description": "Све измене које нису „последње измене”.",
        "rcfilters-exclude-button-off": "Изостави означено",
        "rcfilters-exclude-button-on": "Изостави одабрано",
        "rcfilters-view-tags": "Означене измене",
-       "rcfilters-view-namespaces-tooltip": "Филтрирај резултате према именском простору",
-       "rcfilters-view-tags-tooltip": "ФилÑ\82Ñ\80иÑ\80аÑ\9aе Ñ\80езÑ\83лÑ\82аÑ\82а према ознаци измене",
+       "rcfilters-view-namespaces-tooltip": "Филтрирајте резултате према именском простору",
+       "rcfilters-view-tags-tooltip": "ФилÑ\82Ñ\80иÑ\80аÑ\98Ñ\82е Ñ\80езÑ\83лÑ\82аÑ\82е према ознаци измене",
        "rcfilters-view-return-to-default-tooltip": "Повратак на главни мени",
        "rcfilters-view-tags-help-icon-tooltip": "Сазнајте више о означеним изменама",
        "rcfilters-liveupdates-button": "Ажурирај уживо",
-       "rcfilters-liveupdates-button-title-on": "Искључи ажурирања уживо",
+       "rcfilters-liveupdates-button-title-on": "Искључите ажурирања уживо",
        "rcfilters-liveupdates-button-title-off": "Прикажи нове измене уживо",
-       "rcfilters-watchlist-markseen-button": "Ð\9eзнаÑ\87и Ñ\81ве Ð¸Ð·Ð¼ÐµÐ½Ðµ ÐºÐ°Ð¾ Ð²Ð¸Ñ\92ене",
+       "rcfilters-watchlist-markseen-button": "Ð\9eзнаÑ\87и Ñ\81ве Ð¸Ð·Ð¼ÐµÐ½Ðµ ÐºÐ°Ð¾ Ð¿Ð¾Ð³Ð»ÐµÐ´Ð°не",
        "rcfilters-watchlist-edit-watchlist-button": "Промените Ваш списак надгледаних страница",
        "rcfilters-watchlist-showupdated": "Измене на страницама које нисте посетили од када је измена извршена су <strong>подебљане</strong>, са испуњеним ознакама.",
        "rcfilters-preference-label": "Сакриј побољшану верзију скорашњих измена",
        "uploadbtn": "Отпреми датотеку",
        "reuploaddesc": "Назад на образац за отпремање",
        "upload-tryagain": "Пошаљи измењени опис датотеке",
+       "upload-tryagain-nostash": "Пошаљите ре-отпремљену датотеку и измењен опис",
        "uploadnologin": "Нисте пријављени",
        "uploadnologintext": "Морате бити $1 да бисте отпремали датотеке.",
        "upload_directory_missing": "Фасцикла за слање ($1) недостаје и сервер је не може направити.",
        "file-deleted-duplicate-notitle": "Датотека идентична овој претходно је обрисана и име јој је сакривено.\nТребали бисте питати некога ко може видети податке скривених датотека да прегледа ситуацију пре него што поново отпремите датотеку.",
        "uploadwarning": "Упозорење при отпремању",
        "uploadwarning-text": "Измените опис датотеке и покушајте поново.",
+       "uploadwarning-text-nostash": "Ре-отпремите датотеку, измените опис испод и покушајте поново.",
        "savefile": "Сачувај датотеку",
        "uploaddisabled": "Отпремање је онемогућено.",
        "copyuploaddisabled": "Отпремање путем веб-адресе је онемогућено.",
        "lockmanager-fail-closelock": "Не могу да затворим катанац за „$1“.",
        "lockmanager-fail-deletelock": "Не могу да обришем катанац за „$1“.",
        "lockmanager-fail-acquirelock": "Не могу да се закључам за „$1“.",
-       "lockmanager-fail-openlock": "Не могу да отворим катанац за „$1“.",
+       "lockmanager-fail-openlock": "Не могу да отворим катанац за „$1“. Уверите се да је Ваш директоријум за отпремање исправно конфигурисан и да Ваш веб-сервер има дозволу да пише у том директоријуму. Погледајте https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory за више информација.",
        "lockmanager-fail-releaselock": "Не могу да ослободим катанац за „$1“.",
        "lockmanager-fail-db-bucket": "Не могу да контактирам с довољно катанаца у канти $1.",
        "lockmanager-fail-db-release": "Не могу да ослободим катанце у бази $1.",
        "uploadstash-summary": "Ова страница пружа приступ датотекама које су отпремљене или се отпремају, али још нису објављене. Ове датотеке нису видљиве никоме, осим кориснику који их је отпремио.",
        "uploadstash-clear": "Очисти сакривене датотеке",
        "uploadstash-nofiles": "Немате сакривене датотеке.",
-       "uploadstash-badtoken": "Ð\98звÑ\80Ñ\88аваÑ\9aе Ð´Ð°Ñ\82е радње није успело, разлог томе може бити истек времена за уређивање. Покушајте поново.",
+       "uploadstash-badtoken": "Ð\98звÑ\80Ñ\88аваÑ\9aе Ð¾Ð²е радње није успело, разлог томе може бити истек времена за уређивање. Покушајте поново.",
        "uploadstash-errclear": "Чишћење датотека није успело.",
        "uploadstash-refresh": "Освежи списак датотека",
        "uploadstash-thumbnail": "погледај минијатуру",
        "apisandbox-results-error": "Дошло је до грешке приликом учитавања резултата API упита: $1.",
        "apisandbox-request-selectformat-label": "Прикажи сахтеване податке као:",
        "apisandbox-request-url-label": "Адреса захтева:",
+       "apisandbox-request-format-json-label": "JSON",
+       "apisandbox-request-json-label": "Затражите JSON:",
        "apisandbox-request-time": "Време за извршавање захтјева: {{PLURAL:$1|$1 милисекунда|$1 милисекунде|$1 милисекунди}}",
        "apisandbox-results-fixtoken": "Исправи жетон и пошаљи поново",
-       "apisandbox-results-fixtoken-fail": "Ð\9dиÑ\81ам Ñ\83Ñ\81пео Ð´Ð¾Ð±Ð¸Ñ\82и жетон „$1“.",
+       "apisandbox-results-fixtoken-fail": "Ð\9dиÑ\81ам Ñ\83Ñ\81пео Ð´Ð° Ð´Ð¾Ð±Ð¸Ñ\98ем жетон „$1“.",
        "apisandbox-alert-page": "Поља на страници су неисправна.",
        "apisandbox-alert-field": "Вредност овог поља је неисправна.",
        "apisandbox-continue": "Настави",
        "apisandbox-continue-clear": "Очисти",
+       "apisandbox-param-limit": "Унесите <kbd>max</kbd> да би сте користили највеће ограничење.",
        "apisandbox-multivalue-all-namespaces": "$1 (сви именски простори)",
        "apisandbox-multivalue-all-values": "$1 (све вредности)",
        "booksources": "Штампани извори",
        "rollbacklinkcount": "врати $1 {{PLURAL:$1|измену|измене|измена}}",
        "rollbacklinkcount-morethan": "врати више од $1 {{PLURAL:$1|измене|измене|измена}}",
        "rollbackfailed": "Неуспешно враћање",
+       "rollback-missingparam": "Недостаје потребан параметар на захтеву.",
        "rollback-missingrevision": "Не могу учитати податке о измени.",
        "cantrollback": "Не могу да вратим измену.\nПоследњи аутор је уједно и једини.",
        "alreadyrolled": "Враћање последње измене странице [[:$1]] од стране {{GENDER:$2|корисника|кориснице|корисника}} [[User:$2|$2]] ([[User talk:$2|разговор]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) није успело; неко други је у међувремену изменио или вратио страницу.\n\nПоследњу измену је {{GENDER:$3|направио|направила|направио}} [[User:$3|$3]] ([[User talk:$3|разговор]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "thumbnail-more": "Повећај",
        "filemissing": "Недостаје датотека",
        "thumbnail_error": "Грешка при стварању минијатуре: $1",
+       "thumbnail_error_remote": "Порука о грешци из $1:\n$2",
        "djvu_page_error": "DjVu страница је недоступна",
        "djvu_no_xml": "Не могу да преузмем XML за DjVu датотеку.",
        "thumbnail-temp-create": "Не могу да направим привремену датотеку минијатуре",
        "thumbnail-dest-create": "Не могу да сачувам минијатуру у одредишту",
        "thumbnail_invalid_params": "Неисправни параметри за минијатуру",
+       "thumbnail_toobigimagearea": "Датотека са величинама већим од $1",
        "thumbnail_dest_directory": "Не могу да направим одредишну фасциклу",
        "thumbnail_image-type": "Врста слике није подржана",
        "thumbnail_gd-library": "Недовршена подешавања графичке библиотеке: недостаје функција $1",
+       "thumbnail_image-size-zero": "Изгледа да је величина датотеке нула.",
        "thumbnail_image-missing": "Датотека недостаје: $1",
+       "thumbnail_image-failure-limit": "Било је превише скорашњих неуспешних покушаја ($1 или више) рендеровања ове минијатуре. Покушајте поново касније.",
        "import": "Увоз страница",
        "importinterwiki": "Увоз са другог викија",
        "import-interwiki-text": "Изаберите вики и наслов странице за увоз.\nДатуми и имена уредника ће бити сачувани.\nСве радње при увозу с других викија су забележене у [[Special:Log/import|дневнику увоза]].",
        "importfailed": "Неуспешан увоз: <nowiki>$1</nowiki>",
        "importunknownsource": "Непозната врста за увоз",
        "importnoprefix": "Није наведен међувики префикс",
-       "importcantopen": "Не могу да отворим датотеку за увоз",
+       "importcantopen": "Не могу да отворим датотеку за увоз.",
        "importbadinterwiki": "Неисправна међувики веза",
        "importsuccess": "Увожење је завршено!",
        "importnosources": "Није одређен ниједан извор за увоз, тако да је отпремање историје онемогућено.",
        "tooltip-pt-anontalk": "Разговор о изменама с ове ИП адресе",
        "tooltip-pt-preferences": "{{GENDER:|Ваша}} подешавања",
        "tooltip-pt-watchlist": "Списак страница које надгледате",
-       "tooltip-pt-mycontris": "СпиÑ\81ак {{GENDER:|ваших}} доприноса",
+       "tooltip-pt-mycontris": "СпиÑ\81ак {{GENDER:|Ð\92аших}} доприноса",
        "tooltip-pt-anoncontribs": "Списак измена направљених са ове IP адресе",
        "tooltip-pt-login": "Препоручујемо вам да се пријавите, иако то није обавезно.",
        "tooltip-pt-login-private": "Морате да се пријавите да бисте користили овај Вики",
        "tooltip-pt-logout": "Одјавите се",
        "tooltip-pt-createaccount": "Охрабрујемо вас да отворите налог и пријавите се али то није обавезно",
        "tooltip-ca-talk": "Разговор о страници са садржајем",
-       "tooltip-ca-edit": "Уреди ову страницу",
+       "tooltip-ca-edit": "Уредите ову страницу",
        "tooltip-ca-addsection": "Започните нови одељак",
        "tooltip-ca-viewsource": "Ова страница је закључана. \nМожете погледати изворни текст.",
-       "tooltip-ca-history": "Ð\9fÑ\80еÑ\82Ñ\85одне Ð²ÐµÑ\80зиÑ\98е ове странице",
+       "tooltip-ca-history": "Ð\9fÑ\80еÑ\82Ñ\85одне Ð¸Ð·Ð¼ÐµÐ½е ове странице",
        "tooltip-ca-protect": "Заштитите ову страницу",
        "tooltip-ca-unprotect": "Промени заштиту ове странице",
        "tooltip-ca-delete": "Обришите ову страницу",
        "tooltip-ca-undelete": "Врати измене направљене на овој страници пре него што буде обрисана",
        "tooltip-ca-move": "Премести ову страницу",
-       "tooltip-ca-watch": "Додај ову страницу на списак надгледања",
+       "tooltip-ca-watch": "Додајте ову страницу на списак надгледања",
        "tooltip-ca-unwatch": "Уклони ову страницу са списка надгледања",
        "tooltip-search": "Претражи",
        "tooltip-search-go": "Идите на страницу с овим именом, ако постоји",
        "tooltip-search-fulltext": "Претражите странице с овим текстом",
-       "tooltip-p-logo": "Посети главну страницу",
-       "tooltip-n-mainpage": "Посети главну страницу",
-       "tooltip-n-mainpage-description": "Посети главну страницу",
+       "tooltip-p-logo": "Посетите главну страну",
+       "tooltip-n-mainpage": "Посетите главну страну",
+       "tooltip-n-mainpage-description": "Посетите главну страну",
        "tooltip-n-portal": "О пројекту, шта можете да радите и где да пронађете ствари",
-       "tooltip-n-currentevents": "Сазнај више о тренутним догађајима",
+       "tooltip-n-currentevents": "Сазнајте више о тренутним догађајима",
        "tooltip-n-recentchanges": "Списак скорашњих измена на викију",
        "tooltip-n-randompage": "Учитајте случајну страницу",
-       "tooltip-n-help": "Ð\9cеÑ\81Ñ\82о Ð³Ð´Ðµ Ð¼Ð¾Ð¶ÐµÑ\88 Ð´Ð° Ñ\81е Ð¸Ð½Ñ\84оÑ\80миÑ\88еÑ\88",
+       "tooltip-n-help": "Ð\9cеÑ\81Ñ\82о Ð³Ð´Ðµ Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ñ\81е Ð¸Ð½Ñ\84оÑ\80миÑ\88еÑ\82е",
        "tooltip-t-whatlinkshere": "Списак свих страница које воде овде",
        "tooltip-t-recentchangeslinked": "Скорашње измене на страницама које су повезане с овом страницом",
        "tooltip-feed-rss": "RSS довод ове странице",
        "tooltip-t-contributions": "Списак доприноса {{GENDER:$1|овог корисника|ове кориснице|овог корисника}}",
        "tooltip-t-emailuser": "Пошаљите имејл {{GENDER:$1|овом кориснику|овој корисници}}",
        "tooltip-t-info": "Више информација о овој страници",
-       "tooltip-t-upload": "Отпреми датотеке",
+       "tooltip-t-upload": "Отпремите датотеке",
        "tooltip-t-specialpages": "Списак свих посебних страница",
        "tooltip-t-print": "Верзија ове странице за штампање",
-       "tooltip-t-permalink": "СÑ\82ална веза ка овој измени странице",
+       "tooltip-t-permalink": "ТÑ\80аÑ\98на веза ка овој измени странице",
        "tooltip-ca-nstab-main": "Погледајте страницу са садржајем",
        "tooltip-ca-nstab-user": "Погледајте корисничку страницу",
        "tooltip-ca-nstab-media": "Погледајте мултимедијалну датотеку",
        "tooltip-ca-nstab-category": "Погледајте страницу категорија",
        "tooltip-minoredit": "Означите ову измену као мању",
        "tooltip-save": "Сачувајте своје измене",
-       "tooltip-publish": "Објави своје измене",
+       "tooltip-publish": "Објавите Ваше измене",
        "tooltip-preview": "Прегледајте своје измене. Користите ово дугме пре чувања.",
        "tooltip-diff": "Погледајте које измене сте направили на тексту",
        "tooltip-compareselectedversions": "Погледаjте разлике између две изабране измене ове странице.",
        "pageinfo-visiting-watchers": "Број надгледача странице који су посетили скорашње измене",
        "pageinfo-few-watchers": "Мање од $1 {{PLURAL:$1|пратиоца|пратиоца|пратилаца}}",
        "pageinfo-redirects-name": "Број преусмерења на ову страницу",
+       "pageinfo-redirects-value": "$1",
        "pageinfo-subpages-name": "Подстранице ове странице",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|преусмерење|преусмерења|преусмерења}}; $3 {{PLURAL:$3|непреусмерење|непреусмерења|непреусмерења}})",
        "pageinfo-firstuser": "Аутор странице",
        "markedaspatrolledtext": "Изабрана измена странице [[:$1]] означена је као патролирана.",
        "rcpatroldisabled": "Патролирање скорашњих измена је онемогућено",
        "rcpatroldisabledtext": "Патролирање скорашњих измена је онемогућено.",
-       "markedaspatrollederror": "Не могу да означим као патролирано",
+       "markedaspatrollederror": "Не могу да означим као патролирано.",
        "markedaspatrollederrortext": "Морате изабрати измену да бисте је означили као патролирану.",
        "markedaspatrollederror-noautopatrol": "Не можете да означите своје измене као патролиране.",
        "markedaspatrollednotify": "Ова измена на страници „$1” означена је као патролирана.",
        "exif-compression-34712": "JPEG2000",
        "exif-copyrighted-true": "Заштићено ауторским правом",
        "exif-copyrighted-false": "Није дефинисан",
+       "exif-photometricinterpretation-0": "Црно-бело (бела је 0)",
        "exif-photometricinterpretation-1": "Црно-бело (црна је 0)",
        "exif-photometricinterpretation-2": "RGB",
+       "exif-photometricinterpretation-3": "Палета",
        "exif-photometricinterpretation-6": "YCbCr",
        "exif-unknowndate": "Непознат датум",
        "exif-orientation-1": "Нормално",
        "unit-pixel": "п",
        "confirm-purge-title": "Освежи ову страницу",
        "confirm_purge_button": "У реду",
-       "confirm-purge-top": "Очистити привремену меморију ове стране?",
+       "confirm-purge-top": "Ð\9eÑ\87иÑ\81Ñ\82иÑ\82и Ð¿Ñ\80ивÑ\80еменÑ\83 Ð¼ÐµÐ¼Ð¾Ñ\80иÑ\98Ñ\83 Ð¾Ð²Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е?",
        "confirm-purge-bottom": "Ова радња чисти привремену меморију и приказује најновију измену.",
        "confirm-watch-button": "У реду",
        "confirm-watch-top": "Додати ову страницу у списак надгледања?",
        "version-license-title": "Лиценца за $1",
        "version-license-not-found": "За ову екстензију није нађена информација о лиценци.",
        "version-credits-title": "Заслуге за $1",
+       "version-credits-not-found": "За ову екстензију није нађена информација о заслугама.",
        "version-poweredby-credits": "Овај вики покреће '''[https://www.mediawiki.org/ Медијавики]''', ауторска права © 2001-$1 $2.",
        "version-poweredby-others": "остали",
        "version-poweredby-translators": "translatewiki.net преводиоци",
        "tags-delete-reason": "Разлог:",
        "tags-delete-submit": "Неповратно обриши ову ознаку",
        "tags-delete-not-found": "Ознака „$1“ не постоји.",
+       "tags-delete-no-permission": "Немате дозволу да бришете ознаке за измену.",
        "tags-activate-title": "Активирање ознака",
        "tags-activate-question": "Активирате ознаку „$1“.",
        "tags-activate-reason": "Разлог:",
        "tags-edit-chosen-no-results": "Одговарајуће ознаке нису пронађене",
        "tags-edit-reason": "Разлог:",
        "tags-edit-success": "Измене су примењене.",
+       "tags-edit-failure": "Не могу да применим измене:\n$1",
        "tags-edit-nooldid-title": "Неисправна одредишна измена",
        "tags-edit-none-selected": "Изаберите бар једну ознаку коју треба додати или уклонити.",
        "comparepages": "Упоређивање страница",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|бајт|бајта|бајтова}}",
        "limitreport-expansiondepth": "Највећа дубина проширења",
        "limitreport-expensivefunctioncount": "Број „скупих” функција анализатора",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|бајт|бајта|бајтова}}",
        "expandtemplates": "Замена шаблона",
        "expand_templates_intro": "Ова посебна страница узима викитекст и мења све шаблоне у њему рекурзивно.\nТакође мења функције парсера као што је <code><nowiki>{{</nowiki>#language:…}}</code> и променљиве као што је <code><nowiki>{{</nowiki>CURRENTDAY}}</code>. \nЗаправо практично све што се налази између витичастих заграда.",
        "expand_templates_title": "Назив контекста; за {{СТРАНИЦА}} итд.:",
        "right-pagelang": "мењање језика странице",
        "action-pagelang": "промену језика странице",
        "log-name-pagelang": "Дневник промене језика",
+       "log-description-pagelang": "Ово је дневник измена у језицима страница.",
        "logentry-pagelang-pagelang": "$1 је {{GENDER:$2|променио|променила}} језик странице $3 из $4 у $5.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (омогућена)",
        "mediastatistics": "Статистика датотека",
        "mediastatistics-header-executable": "Извршне",
        "mediastatistics-header-archive": "Компресоване",
        "mediastatistics-header-total": "Све датотеке",
+       "json-warn-trailing-comma": "$1 {{PLURAL:$1|пратећа тачка је уклоњена|пратеће тачке су уклоњене|пратећих тачки је уклоњено}} из JSON-a",
+       "json-error-unknown": "Догодио се проблем с JSON-ом. Грешка: $1",
+       "json-error-depth": "Прекорачена је највећа дубина",
+       "json-error-state-mismatch": "Невалидан или покварени JSON",
+       "json-error-ctrl-char": "Грешка контролног симбола, могуће је да је неисправно енкодиран",
        "json-error-syntax": "Грешка у синтакси",
+       "json-error-unsupported-type": "Дата је вреднос врсте која се не може енкодирати",
        "headline-anchor-title": "Веза до овог одељка",
        "special-characters-group-latin": "Латиница",
        "special-characters-group-latinextended": "Проширена латиница",
        "date-range-from": "Од датума:",
        "date-range-to": "До датума:",
        "sessionprovider-generic": "$1 сесије",
+       "sessionprovider-mediawiki-session-cookiesessionprovider": "сесије са колачићима",
        "randomrootpage": "Случајна коренска страница",
        "log-action-filter-block": "Тип блокирања:",
        "log-action-filter-contentmodel": "Тип промене модела садржаја:",
        "log-action-filter-delete-event": "брисање уноса у дневницима",
        "log-action-filter-delete-revision": "брисање измене",
        "log-action-filter-import-interwiki": "Међувики увоз",
+       "log-action-filter-import-upload": "Увоз постављањем XML-а",
        "log-action-filter-managetags-create": "нова ознака",
        "log-action-filter-managetags-delete": "брисање ознаке",
        "log-action-filter-managetags-activate": "активирање ознаке",
        "log-action-filter-suppress-reblock": "Скривање корисника поновним блокирањем",
        "log-action-filter-upload-upload": "ново отпремање",
        "log-action-filter-upload-overwrite": "промена постојећег",
-       "authmanager-authn-no-primary": "Пружени акредитиви не могу се проверити.",
+       "authmanager-authn-not-in-progress": "Аутентификација није у току или је дошло до губитка података о сесији. Почните испочетка.",
+       "authmanager-authn-no-primary": "Не могу да проверим пружене акредитиве.",
+       "authmanager-authn-no-local-user": "Пружени акредитиви нису повезани ни са једним корисником на овом викију.",
+       "authmanager-authn-no-local-user-link": "Пружени су исправни акредитиви, али нису повезани ни с једним корисником на овом викију. Пријавите се на неки други начин или направите нови кориснички налог, што ће Вам дати могућност да повежете претходне акредитиве на нови налог.",
+       "authmanager-authn-autocreate-failed": "Не могу да аутоматски направим локални налог: $1",
+       "authmanager-change-not-supported": "Не могу да променим пружене акредитиве јер их ништа не би користило.",
        "authmanager-create-disabled": "Онемогућено прављење налога.",
        "authmanager-create-from-login": "Попуните поља да бисте направили налог.",
+       "authmanager-create-not-in-progress": "Прављење налога није у току или су подаци о сесији изгубљени. Почните испочетка.",
+       "authmanager-create-no-primary": "Не могу да искористим пружене акредитиве за прављење налога.",
+       "authmanager-link-no-primary": "Не могу да искористим пружене акредитиве за спајање налога.",
+       "authmanager-link-not-in-progress": "Спајање налога није у току или је дошло до губитка података о сесији. Почните испочетка.",
        "authmanager-authplugin-setpass-failed-title": "Неуспешна промена лозинке",
+       "authmanager-authplugin-setpass-failed-message": "Додатак за аутентификацију је одбио промену лозинке.",
+       "authmanager-authplugin-create-fail": "Додатак за аутентификацију је одбио прављење налога.",
+       "authmanager-authplugin-setpass-denied": "Додатак за аутентификацију не дозвољава мењање лозику.",
        "authmanager-authplugin-setpass-bad-domain": "Неисправан домен.",
        "authmanager-autocreate-noperm": "Аутоматско прављење налога није дозвољено.",
        "authmanager-userdoesnotexist": "Кориснички налог „$1“ није отворен.",
+       "authmanager-username-help": "Корисничко име за аутентификацију.",
+       "authmanager-password-help": "Лозинка за аутентификацију.",
+       "authmanager-domain-help": "Домен за спољашњу аутентификацију.",
+       "authmanager-retype-help": "Поновите лозинку да би сте потврдили.",
        "authmanager-email-label": "Имејл",
        "authmanager-email-help": "Имејл адреса",
        "authmanager-realname-label": "Право име",
        "authmanager-realname-help": "Право име корисника",
+       "authmanager-provider-password": "Аутентификација лозинком",
+       "authmanager-provider-password-domain": "Аутентификација лозинком и доменом",
        "authmanager-provider-temporarypassword": "Привремена лозинка",
        "authprovider-confirmlink-option": "$1 ($2)",
        "authprovider-confirmlink-request-label": "Рачуни који се требају повезати",
        "authprovider-confirmlink-success-line": "$1: Успешно повезано.",
+       "authprovider-confirmlink-failed": "Не могу да повежем налог у потпуности: $1",
+       "authprovider-confirmlink-ok-help": "Наставите након приказивања порука за неуспешно повезивање.",
        "authprovider-resetpass-skip-label": "Прескочи",
+       "authprovider-resetpass-skip-help": "Прескочите ресетовање лозинке.",
+       "authform-nosession-login": "Аутентификација је успела, али Ваш прегледач не може да „запамти” да сте пријављени.\n\n$1",
+       "authform-nosession-signup": "Налог је направљен, али Ваш прегледач не може да „запамти” да сте пријављени.\n\n$1",
        "authform-newtoken": "Недостаје жетон. $1",
        "authform-notoken": "Недостаје жетон",
        "authform-wrongtoken": "Погрешан жетон",
        "specialpage-securitylevel-not-allowed-title": "Није дозвољено",
+       "specialpage-securitylevel-not-allowed": "Жао нам је, није Вам дозвољено да користите ову страницу јер не могу да потврдим Ваш идентитет.",
        "authpage-cannot-login": "Не могу започети пријаву.",
+       "authpage-cannot-login-continue": "Не могу да наставим пријављивање. Ваша сесија је највероватније истекла.",
        "authpage-cannot-create": "Не могу започети стварање налога.",
        "authpage-cannot-link": "Не могу започети спајање налога.",
        "cannotauth-not-allowed-title": "Приступ је одбијен",
        "cannotauth-not-allowed": "Није Вам дозвољено да користите ову страницу",
        "changecredentials": "Промена акредитива",
        "changecredentials-submit": "Промени",
+       "changecredentials-invalidsubpage": "„$1“ није исправна врста акредитива.",
+       "changecredentials-success": "Ваши акредитиви су промењени.",
        "removecredentials": "Уклањање акредитива",
+       "removecredentials-submit": "Уклањање акредитива",
+       "removecredentials-invalidsubpage": "„$1“ није исправна врста акредитива.",
+       "removecredentials-success": "Ваши акредитиви су уклоњени.",
        "credentialsform-provider": "Врста акредитива:",
        "credentialsform-account": "Назив налога:",
        "cannotlink-no-provider-title": "Нема налога за повезивање",
        "unlinkaccounts-success": "Налог је обједињен.",
        "userjsispublic": "Напомена: JavaScript подстранице не би требале садржавати поверљиве информације будући да су видљиве другим корисницима.",
        "usercssispublic": "Напомена: CSS подстранице не би требале садржавати поверљиве информације будући да су видљиве другим корисницима.",
+       "restrictionsfield-badip": "Неисправна ИП адреса или опсег: $1",
+       "restrictionsfield-label": "Дозвољени ИП-опсези:",
        "edit-error-short": "Грешка: $1",
        "edit-error-long": "Грешке:\n\n$1",
        "revid": "измена $1",
        "undelete-cantedit": "Не можете повратити ову страницу јер немате дозволу да је уређујете.",
        "undelete-cantcreate": "Не можете повратити ову страницу јер нема постојеће странице са овим именом и немате дозволу да направите ову страницу.",
        "pagedata-title": "Подаци странице",
+       "pagedata-not-acceptable": "Није пронађен одговарајући облик. Подржане MIME-врсте: $1",
        "pagedata-bad-title": "Невалидан наслов: $1."
 }
index d558670..e9aa40a 100644 (file)
        "may-date": "$1. maj",
        "june-date": "$1. jun",
        "july-date": "$1. jul",
-       "august-date": "$1. august",
+       "august-date": "$1. avgust",
        "september-date": "$1. septembar",
        "october-date": "$1. oktobar",
        "november-date": "$1. novembar",
        "welcomecreation-msg": "Vaš nalog je otvoren.\nNe zaboravite da promenite svoja [[Special:Preferences|podešavanja]].",
        "yourname": "Korisničko ime:",
        "userlogin-yourname": "Korisničko ime",
-       "userlogin-yourname-ph": "Unesite vaše korisničko ime",
+       "userlogin-yourname-ph": "Unesite svoje korisničko ime",
        "createacct-another-username-ph": "Unesite korisničko ime",
        "yourpassword": "Lozinka:",
        "userlogin-yourpassword": "Lozinka",
-       "userlogin-yourpassword-ph": "Unesite vašu lozinku",
+       "userlogin-yourpassword-ph": "Unesite svoju lozinku",
        "createacct-yourpassword-ph": "Unesite lozinku",
        "yourpasswordagain": "Potvrda lozinke:",
        "createacct-yourpasswordagain": "Potvrdite lozinku",
        "password-change-forbidden": "Ne možete da promenite lozinku na ovom vikiju.",
        "externaldberror": "Došlo je do greške pri prepoznavanju baze podataka ili nemate ovlašćenja da ažurirate svoj spoljni nalog.",
        "login": "Prijavi me",
+       "login-security": "Verifikacija vašeg identiteta",
        "nav-login-createaccount": "Prijava/registracija",
        "logout": "Odjava",
        "userlogout": "Odjava",
        "createacct-another-realname-tip": "Pravo ime nije obavezno.\nAko izaberete da ga unesete, ono će biti korišćeno za pripisivanje vašeg rada.",
        "pt-login": "Prijavi me",
        "pt-login-button": "Prijavi me",
+       "pt-login-continue-button": "Nastavi prijavljivanje",
        "pt-createaccount": "Otvori nalog",
        "pt-userlogout": "Odjavi me",
        "php-mail-error-unknown": "Nepoznata greška u funkciji PHP mail().",
        "newpassword": "Nova lozinka:",
        "retypenew": "Potvrda lozinke:",
        "resetpass_submit": "Postavi lozinku i prijavi me",
-       "changepassword-success": "Vaša lozinka je uspešno promenjena.",
+       "changepassword-success": "Vaša lozinka je promenjena.",
        "changepassword-throttled": "Previše puta ste pokušali da se prijavite.\nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
        "botpasswords": "Lozinke botova",
+       "botpasswords-label-appid": "Ime bota:",
+       "botpasswords-label-create": "Napravi",
+       "botpasswords-label-update": "Ažuriraj",
        "botpasswords-label-cancel": "Otkaži",
        "botpasswords-label-delete": "Obriši",
+       "botpasswords-label-grants-column": "Odobreno",
        "resetpass_forbidden": "Lozinka ne može biti promenjena",
        "resetpass-no-info": "Morate biti prijavljeni da biste pristupili ovoj stranici.",
        "resetpass-submit-loggedin": "Promeni lozinku",
        "viewpagelogs": "Pogledaj dnevnike ove stranice",
        "nohistory": "Ne postoji istorija izmena ove stranice.",
        "currentrev": "Tekuća izmena",
-       "currentrev-asof": "Tekuća izmena od $2 u $3",
+       "currentrev-asof": "Poslednja verzija na datum $2 u $3",
        "revisionasof": "Izmena od $2 u $3",
        "revision-info": "Izmena od $1 koju je {{GENDER:$6|uredio $2|uredila $2}}$7",
        "previousrevision": "← Starija izmena",
        "rcfilters-other-review-tools": "Ostali alati za pregled:",
        "rcfilters-activefilters": "Aktivni filteri",
        "rcfilters-advancedfilters": "Napredni filteri",
-       "rcfilters-limit-title": "Prikazati izmena",
+       "rcfilters-limit-title": "Broj izmena za prikaz",
+       "rcfilters-hours-title": "Skorašnji sati",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|dana|dana}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|sat|sata}}",
        "rcfilters-quickfilters-placeholder-description": "Da biste sačuvali svoja podešavanja filtera i upotrebljavali ih kasnije, kliknite na ikonu za oznaku u području aktivnih filtera, ispod.",
        "recreate": "Ponovo napravi",
        "unit-pixel": "px",
        "confirm_purge_button": "U redu",
-       "confirm-purge-top": "Očistiti privremenu memoriju ove strane?",
+       "confirm-purge-top": "Očistiti privremenu memoriju ove stranice?",
        "confirm-purge-bottom": "Ova radnja čisti privremenu memoriju i prikazuje najnoviju izmenu.",
        "confirm-watch-button": "U redu",
        "confirm-watch-top": "Dodati ovu stranicu u spisak nadgledanja?",
index 2329a05..ce6b738 100644 (file)
        "hr_tip": "Horisontell linje (använd sparsamt)",
        "summary": "Sammanfattning:",
        "subject": "Ämne:",
-       "minoredit": "Mindre ändring",
+       "minoredit": "Detta är en mindre ändring",
        "watchthis": "Bevaka denna sida",
        "savearticle": "Spara sidan",
        "savechanges": "Spara ändringar",
        "recentchangesdays-max": "Maximalt $1 {{PLURAL:$1|dygn}}",
        "recentchangescount": "Antal redigeringar som visas i senaste ändringar, sidhistoriker och loggar som standard:",
        "prefs-help-recentchangescount": "Maximalt antal: 1 000",
-       "prefs-help-watchlist-token2": "Detta är den hemliga nyckeln till webbflödet i din bevakningslista.\nNågon som vet den kommer att kunna läsa din bevakningslista, så dela inte ut den.\nOm du behöver [[Special:ResetTokens|kan du återställa den]].",
+       "prefs-help-watchlist-token2": "Detta är den hemliga nyckeln till webbflödet i din bevakningslista.\nAlla som har den kommer att kunna läsa din bevakningslista, så dela inte ut den.\nOm du behöver [[Special:ResetTokens|kan du återställa den]].",
        "savedprefs": "Dina inställningar har sparats",
        "savedrights": "Användargrupperna för {{GENDER:$1|$1}} har sparats.",
        "timezonelegend": "Tidszon:",
index 3c276c4..2533454 100644 (file)
        "talkpagelinktext": "คุย",
        "specialpage": "หน้าพิเศษ",
        "personaltools": "เครื่องมือส่วนตัว",
-       "talk": "à¸\84ุย",
+       "talk": "อภิà¸\9bราย",
        "views": "ดู",
        "toolbox": "เครื่องมือ",
        "tool-link-userrights": "เปลี่ยนกลุ่ม{{GENDER:$1|ผู้ใช้}}",
        "blanknamespace": "(หลัก)",
        "contributions": "เรื่องที่{{GENDER:$1|ผู้ใช้}}นี้เขียน",
        "contributions-title": "เรื่องที่เขียนโดย $1",
-       "mycontris": "มีส่วนร่วม",
+       "mycontris": "à¹\80รืà¹\88อà¸\87à¸\97ีà¹\88มีสà¹\88วà¸\99รà¹\88วม",
        "anoncontribs": "เรื่องที่เขียน",
        "contribsub2": "สำหรับ {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "บัญชีผู้ใช้ \"$1\" ยังไม่ได้ลงทะเบียน",
index 1e60cd1..e0819e6 100644 (file)
        "copyuploaddisabled": "Файлъёсыз ватсан URL пыр уг лэзиськы.",
        "uploaddisabledtext": "Файл поныны луонлык ӧвӧл.",
        "upload-dialog-button-cancel": "Берытсконо",
+       "license": "Лицензированиея:",
        "license-header": "Лицензия",
        "nolicense": "Ӧвӧл",
        "imgfile": "файл",
        "filehist-datetime": "Дата/дыр",
        "filehist-thumb": "Миниатюра",
        "filehist-thumbtext": "$1 лэсьтэм версилэн миниатюраез",
+       "filehist-nothumb": "Эскизъёссы",
        "filehist-user": "Викиавтор",
        "filehist-dimensions": "Быдӟала",
        "filehist-comment": "Валэктон",
        "booksources-search": "Утчаны",
        "log": "Журналъёс",
        "logeventslist-submit": "Возьматыны",
+       "all-logs-page": "Вань общественной журнал",
        "showhideselectedlogentries": "Возьматыны/ватыны быръем журналъёсысь гожъямъёсыз",
        "checkbox-select": "Бырйыны: $1",
        "checkbox-all": "Ваньзэ",
        "checkbox-none": "Номыре",
        "checkbox-invert": "Воштыны интыен",
+       "allpages": "Ваньмыз бамъёс",
        "allarticles": "Ваньмыз бамъёс",
        "allpagessubmit": "Быдэстоно",
        "categories": "Категориос",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|вераськон]]) викиавторлэн тупатонъёсыз берыктэмын [[User:$1|$1]] викиавторлэн версиезозь",
        "revertpage-nouser": "Ватэм викиавторлэн тупатонъёсыз берыктэмын {{GENDER:$1|[[User:$1|$1]] викиавторлэн}} версиезозь",
        "protectlogpage": "Утёнъёсын журнал",
+       "protectedarticle": "возьматы \"[[$1]]\"",
+       "protect-default": "ваньзэ лэзе пользователь",
        "restriction-edit": "Тупатон",
        "undeletehistory": "Бамез берен сётоды ке, сое воштонъёслэн историзы берытскоз но.\nБыдтон бере таӵе ик нимен выль бам кылдытэмын вал ке, берен сётэм версиос адӟиськозы воштонъёслэн историязы выль версиослэсь азьло.",
        "undeletehistorynoadmin": "Та бам быдтэмын вал.\nБыдтонлэн мугез но список викиавторъёслы, кинъёс та бамез тупатъязы сое быдтон дырозь, улӥ возьматэмын.\nБыдтэм бамлэсь текстсэ учкыны быгато администраторъёс гинэ.",
        "sp-contributions-newbies": "Юрттэт чотын гинэ вылез возьма",
        "sp-contributions-blocklog": "блокировкаосыз",
        "sp-contributions-deleted": "{{GENDER:$1|викиавторлэн}} быдтэм тупатонъёсыз",
+       "sp-contributions-logs": "журналъёс",
+       "sp-contributions-talk": "вераськон",
        "sp-contributions-userrights": "пыриськисьлэн правоосыныз кивалтон",
        "sp-contributions-blocked-notice": "Али дыре та викиавтор заблокировать каремын.\nВалэктон понна блокировкаосын журналысь берло гожъям улӥ возьматэмын:",
        "sp-contributions-blocked-notice-anon": "Али дыре та IP-адрес заблокировать каремын.\nВалэктон понна блокировкаосын журналысь берло гожъям улӥ возьматэмын:",
        "sp-contributions-search": "- Взносэз утчан",
        "sp-contributions-username": "IP-адрес яке нимысьтыз пользователь:",
        "sp-contributions-toponly": "Воштӥськонъёс гинэ возьматэ, со выль воштӥськонъёс возьмало",
+       "sp-contributions-newonly": "Возьматоно бам шонертон гинэ кылдӥз.",
        "sp-contributions-submit": "Шедьтыны",
        "whatlinkshere": "Татчы чӧлсконъёс",
        "whatlinkshere-title": "«$1» вылэ чӧлскись бамъёс",
        "tooltip-ca-addsection": "Выль люкет кылдытоно",
        "tooltip-ca-viewsource": "Та бам воштонъёслэсь утемын.\nТӥ быгатӥськоды инъет текстсэ учкыны но кӧчырыны",
        "tooltip-ca-history": "Бамлэн воштонъёсыныз журнал",
+       "tooltip-ca-delete": "Та бамез быдтыны",
        "tooltip-ca-move": "Та бамлэсь нимзэ воштыны",
        "tooltip-ca-watch": "Та бамез чаклан списокады пыртоно",
        "tooltip-search": "Утчано {{SITENAME}}",
        "simpleantispam-label": "Анти-спам эскерон.\n<strong>Эн</strong> гожтэ татчы!",
        "pageinfo-header-edits": "Воштонъёслэн историзы",
        "pageinfo-toolboxlink": "Бам сярысь тодэтъёс",
+       "pageinfo-contentpage-yes": "Бен",
        "previousdiff": "← Вужгес тупатон",
        "nextdiff": "Выльгес тупатон →",
        "file-info-size": "$1 × $2 пиксель, файллэн быдӟалаез: $3, MIME-тип: $4",
        "monthsall": "ваньзэ",
        "confirmrecreate-noreason": "Тӥ та бам тупатыны кутскиды бере, [[User:$1|$1]] ([[User talk:$1|вер]]) викиавтор сое {{GENDER:$1|быдтӥз}}. Тауна, юнматэ, та бамез выльысь кылдытэмды зэм но потэ шуыса.",
        "confirm-watch-top": "Та бамез чаклан списокады пыртоно?",
+       "imgmultigo": "Мын!",
+       "imgmultigoto": "Бам вылэ выжоно $1",
        "autosumm-new": "Выль бам: «$1»",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|вераськон]])",
        "version": "Версия",
+       "redirect-submit": "Быдэстоно",
        "specialpages": "Ваньмыз панельёс",
        "specialpages-group-login": "Системае пырон / регистрация",
        "specialpages-group-users": "Викиавторъёс но правооссы",
        "tag-filter": "[[Special:Tags|Тэгъёсыз]] фильтр:",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|1=Метка|Меткаос}}]]: $2)",
        "tags-title": "Меткаос",
+       "tags-active-yes": "Бен",
+       "tags-active-no": "Ӧвӧл",
        "logentry-delete-delete": "$1 {{GENDER:$2|быдтӥз}} $3 бамез",
        "logentry-delete-restore": "$1 {{GENDER:$2|берен сётӥз}} $3 бамез ($4)",
        "logentry-block-block": "$1 {{GENDER:$2|заблокировать кариз}} {{GENDER:$4|$3}} дырлы: $5 $6",
index 5503a3a..634b405 100644 (file)
@@ -6,9 +6,15 @@
                        "Gagnabil",
                        "Mdb897",
                        "YesIn",
-                       "ⵕⴰⵊⵉ"
+                       "ⵕⴰⵊⵉ",
+                       "Brahim-essaidi"
                ]
        },
+       "tog-hideminor": "ⵙⵙⵏⵜⵍ ⵜⵉⵙⵏⴼⵉⵍⵉⵏ ⵜⵉⵎⵥⵥⴰⵏⵉⵏ ⵙⴳ ⵉⵙⵏⴼⵍⵏ ⵉⵏⴳⴳⵓⵔⴰ",
+       "tog-minordefault": "ⵕⵛⵎ ⵎⴰⵕⵕⴰ ⵉⵙⵏⴼⵍⵏ ⵎⵥⵥⵉⵢⵏⵉⵏ ⵙ ⵓⵡⵏⵓⵍ",
+       "tog-ccmeonemails": "ⴰⵣⵏ ⵉⵢⵉ ⴷ ⵜⵓⵏⵖⵉⵍⵉⵏ ⵏ ⵉⵎⴰⵢⵍⵏ ⵏⵏⴰ ⵓⵣⵏⵖ ⵉ ⵉⵎⵙⵙⵎⵔⵙⵏ ⵢⴰⴹⵏ",
+       "tog-diffonly": "ⴰⴷ ⵓⵔ ⵜⵙⵙⴽⴷ ⵜⵓⵎⴰⵢⵜ ⵏ ⵜⴰⵙⵏⴰ ⴷⴷⵓ ⵉⵎⵣⴰⵔⴰⵢⵏ",
+       "tog-showhiddencats": "ⵙⴽⵏ ⵜⴰⴳⴳⴰⵢⵉⵏ ⵉⵜⵜⵓⵃⴹⴰⵏ",
        "sunday": "ⴰⵙⴰⵎⴰⵙ",
        "monday": "ⴰⵢⵏⴰⵙ",
        "tuesday": "ⴰⵙⵉⵏⴰⵙ",
@@ -68,6 +74,7 @@
        "july-date": "$1 ⵢⵓⵍⵢⵓⵣ",
        "august-date": "$1 ⵖⵓⵛⵜ",
        "september-date": "$1 ⵛⵓⵜⴰⵏⴱⵉⵔ",
+       "october-date": "ⴽⵟⵓⴱⵔ $1",
        "november-date": "$1 ⵏⵓⵡⴰⵏⴱⵉⵔ",
        "december-date": "$1 ⴷⵓⵊⴰⵏⴱⵉⵔ",
        "period-am": "ⴼⵡ",
        "category_header": "Tasniwin g usmil \"$1\"",
        "subcategories": "ⵉⴷⵓⵙⵎⵉⵍⵏ",
        "category-media-header": "ⵎⵉⴷⵢⴰ ⴳ ⵓⵙⵎⵉⵍ \"$1\"",
+       "category-empty": "<em>ⵜⴰⴳⴳⴰⵢⵜ ⴰⴷ ⵓⵔ ⴷⵉⴳⵙ ⴰⵡⴷ ⴽⵔⴰ ⵏ ⵎⵉⴷⵢⴰ ⵏⵖ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵖⵉⵍⴰⴷ.</em>",
        "hidden-categories": "{{PLURAL:$1|ⴰⵙⵎⵉⵍ ⵉⵎⵎⵏⵜⵍⵏ|ⵉⵙⵎⵉⵍⵏ ⵎⵎⵏⵜⵍⵏⵉⵏ}}",
+       "hidden-category-category": "ⵜⴰⴳⴳⴰⵢⵉⵏ ⵉⵜⵜⵓⵏⵜⴰⵍⵏ",
+       "category-subcat-count": "{{PLURAL:$2|ⴰⵙⵎⵉⵍ ⴰⴷ ⴷⵉⴳⵙ ⵖⴰⵙ ⵉⴷⵓⵙⵎⵉⵍⵏ ⴰⴷ.|ⴰⵙⵎⵉⵍ ⴰⴷ ⴷⵉⴳⵙ {{PLURAL:$1|ⴰⴷⵓⵙⵎⵉⵍ ⴰⴷ |$1 ⵉⴷⵓⵙⵎⵉⵍⵏ ⴰⴷ}}, ⵙⴳ $2 ⴳ ⵓⵖⵔⵓⴷ.}}",
+       "category-article-count": "{{PLURAL:$2|ⴰⵙⵎⵉⵍ ⴰⴷ ⵢⵓⵎⴰ ⵖⴰⵙ ⵜⴰⵙⵏⴰ ⴰⴷ {{PLURAL:$1|ⵜⴰⵙⵏⴰ ⴰⴷ ⵜⵍⵍⴰ|$1 ⵜⴰⵙⵏⵉⵡⵉⵏ ⴰⴷ ⵍⵍⴰⵏⵜ}} ⴳ ⵓⵙⵎⵉⵍ ⴰⴷ, ⵙⴳ $2 ⴳ ⵓⵖⵔⵓⴷ.}}",
        "about": "ⵅⴼ",
        "article": "ⵜⴰⵙⵏⴰ ⵏ ⵜⵓⵎⴰⵢⵜ",
        "newwindow": "(ⴰⴷ ⵉⵏⵏⵓⵔⵥⵎ ⴳ ⵓⵙⴽⵙⵍ ⴰⵎⴰⵢⵏⵓ)",
        "cancel": "ⵙⵔ",
        "moredotdotdot": "ⵓⴳⴳⴰⵔ...",
+       "morenotlisted": "ⵓⵎⵓⵖ ⴰⴷ ⵉⵔⵡⴰⵙ ⵓⵔ ⵉⵙⵎⴷ.",
        "mypage": "ⵜⴰⵙⵏⴰ",
        "mytalk": "ⵎⵙⴳⴷⴰⵍ",
        "anontalk": "ⵎⵙⴰⵡⴰⵍ",
        "navigation": "ⴰⵙⵜⴰⵔⴰ",
        "and": "&#32;ⴷ",
+       "faq": "FAQ",
        "namespaces": "ⵜⵉⵔⵉⵡⵉⵏ ⵏ ⵉⵙⵎⴰⵡⵏ",
        "variants": "ⵜⵉⵎⵣⴰⵔⴰⵢⵉⵏ",
        "navigation-heading": "ⵓⵎⵓⵖ ⵏ ⵓⵙⵙⴰⵔⴰ",
        "view": "ⵙⴽⵏ",
        "view-foreign": "ⵙⴽⵏ ⴳ $1",
        "edit": "ⵙⵏⴼⵍ",
+       "edit-local": "ⵙⵏⴼⵍ ⴰⴳⵍⴰⵎ ⴰⴷⵖⴰⵔⴰⵏ",
        "create": "ⵙⵏⵓⵍⴼⵓ",
+       "create-local": "ⵔⵏⵓ ⴰⴳⵍⴰⵎ ⴰⴷⵖⴰⵔⴰⵏ",
        "delete": "ⴽⴽⵙ",
+       "protect": "ⴼⵔⴳ",
        "protect_change": "ⵙⵏⴼⵍ",
+       "unprotect": "ⵙⵏⴼⵍ ⴰⴼⵔⴰⴳ",
        "newpage": "ⵜⴰⵙⵏⴰ ⵜⴰⵎⴰⵢⵏⵓⵜ",
        "talkpagelinktext": "ⵎⵙⴰⵡⴰⵍ",
        "specialpage": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵥⵍⵉⵏⵉⵏ",
        "toolbox": "ⵉⵎⴰⵙⵙⵏ",
        "imagepage": "ⵥⵕ ⵜⴰⵙⵏⴰ ⵏ ⵓⴼⴰⵢⵍⵓ",
        "mediawikipage": "ⵥⵕ ⵜⴰⵙⵏⴰ ⵏ ⵜⵓⵣⵓⵏⵜ",
+       "templatepage": "ⵥⵔ ⵜⴰⵙⵏⴰ ⵏ ⵡⴰⵍⴱⵓⴹ",
        "viewhelppage": "ⵥⵕ ⵜⴰⵙⵏⴰ ⵏ ⵜⵡⵉⵙⵉ",
+       "categorypage": "ⵥⵔ ⵜⴰⵙⵏⴰ ⵏ ⵜⴰⴳⴳⴰⵢⵜ",
+       "viewtalkpage": "ⵥⵔ ⴰⵎⵙⴳⴷⴰⵍ",
        "otherlanguages": "ⵙ ⵜⵓⵜⵍⴰⵢⵉⵏ ⵢⴰⴹⵏⵉⵏ",
        "redirectedfrom": "(ⵓⵖⵓⵍ ⵙⴳ $1)",
        "redirectto": "ⵙⵏⵉⵍ ⵖⵔ:",
        "jumpto": "ⵏⴹⵓ ⵖⵔ:",
        "jumptonavigation": "ⴰⵙⵜⴰⵔⴰ",
        "jumptosearch": "ⵔⵣⵓ",
+       "pool-errorunknown": "ⵜⴰⵣⴳⴰⵍⵜ ⵜⴰⵔⵓⵙⵙⵉⵏⵜ",
        "aboutsite": "ⵖⴼ {{SITENAME}}",
        "aboutpage": "Project:ⵅⴼ",
        "copyrightpage": "{{ns:project}}:ⵉⵣⵔⴼⴰⵏ ⵏ ⵓⵙⵏⵖⵍ",
        "privacypage": "Project:ⵜⴰⵙⵔⵜⵉⵜ ⵏ ⵜⵉⵏⵏⵓⵜⵍⴰ",
        "ok": "ⵡⴰⵅⵅⴰ",
        "retrievedfrom": "ⵉⵜⵜⵓⵙⴰⵖⵓⵍ ⵙⴳ $1",
+       "youhavenewmessagesmanyusers": "ⴷⴰⵔⴽ $1 ⵙⴳ ⵎⵏⵏⴰⵡ ⵉⵎⵙⵙⵎⵔⵙⵏ ($2)",
        "newmessageslinkplural": "{{PLURAL:$1|ⵜⵓⵣⵉⵏⵜ ⵜⴰⵎⴰⵢⵏⵓⵜ|999=ⵜⵓⵣⵉⵏⵉⵏ ⵜⵉⵎⴰⵢⵏⵓⵜⵉⵏ}}",
        "youhavenewmessagesmulti": "ⵍⵍⴰⵏ ⵖⵓⵔⴽ ⵜⵓⵣⵉⵏⵉⵏ ⵜⵉⵎⴰⵢⵏⵓⵜⵉⵏ ⴳ $1",
        "editsection": "ⵙⵏⴼⵍ",
        "confirmable-no": "ⵓⵀⵓ",
        "viewdeleted": "ⵥⵕ $1?",
        "site-atom-feed": "ⴰⵏⴳⵉ ⵏ ⴰⵜⵓⵎ ⵏ $1",
+       "page-atom-feed": "ⴰⵏⴳⵉ ⵏ ⴰⵜⵓⵎ ⵏ $1",
        "red-link-title": "$1 (ⵜⴰⵙⵏⴰ ⵓⵔ ⵜⵍⵍⵉ)",
        "nstab-main": "ⵜⴰⵙⵏⴰ",
        "nstab-user": "ⵜⴰⵙⵏⴰ ⵏ ⵓⵙⵎⵔⴰⵙ",
        "mainpage-nstab": "ⵜⴰⵙⵏⴰ ⵏ ⵓⵙⵏⵓⴱⴳ",
        "error": "ⵜⴰⵣⴳⵍⵜ",
        "databaseerror-error": "ⵜⴰⵣⴳⵍⵜ: $1",
+       "badtitle": "ⴳⴰⵔ ⴰⵣⵡⵍ",
        "viewsource": "ⵙⴽⵏ ⴰⵙⴰⴳⵎ",
        "viewsource-title": "ⵥⵕ ⴰⵖⴱⴰⵍⵓ ⵉ $1",
+       "viewsourcetext": "ⵜⵣⵎⵔⴷ ⴰⴷ ⵜⵥⵔⴷ ⴷ ⴰⴷ ⵜⵙⵙⵏⵖⵍⴷ ⴰⵙⴰⴳⵎ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ",
        "userlogin-yourname": "ⵉⵙⵎ ⵏ ⵓⵙⵎⵔⴰⵙ",
        "userlogin-yourname-ph": "ⵙⵙⴽⵛⵎ ⵉⵙⵎ ⵏ ⵓⵏⵙⵙⵎⵔⵙ ⵏⵏⵎ/ⴽ",
        "yourpassword": "ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ",
        "logout": "ⴼⴼⵖ",
        "userlogout": "ⴼⴼⵖ",
        "userlogin-noaccount": "ⵓⵔ ⵖⵓⵔⴽ ⵉⵍⵍⵉ ⵓⵎⵉⴹⴰⵏ?",
+       "userlogin-joinproject": "ⵍⴽⵎ {{SITENAME}}",
        "createaccount": "ⵔⵥⵎ ⴽⵔⴰ ⵏ ⵓⵎⵉⴹⴰⵏ",
        "userlogin-resetpassword-link": "ⵜⴻⵜⵜⵓⴷ ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵏⵏⵎ/ⴽ?",
        "createacct-emailoptional": "ⵉⵎⴰⵢⵍ (ⴰⵔⵓⵛⵛⵉⵍ)",
        "minoredit": "ⵡⴰ ⴷ ⴰⵙⵏⴼⵍ ⵓⵎⵥⵉⵢ",
        "watchthis": "ⵎⵎⴰⵜⵔ ⵜⴰⵙⵏⴰ ⴰⴷ",
        "savearticle": "ⵃⴹⵓ ⵜⴰⵙⵏⴰ",
+       "showpreview": "ⵙⴽⵏ ⴰⴱⵔⵉⴼⵢⵓ",
        "showdiff": "ⵙⵎⴰⵍ ⵉⵙⵏⴼⵍⵏ",
        "loginreqlink": "ⴽⵛⵎ",
        "newarticle": "(ⴰⵎⴰⵢⵏⵓ)",
+       "newarticletext": "ⵜⴹⴼⴰⵔⴷ ⵢⴰⵏ ⵓⵙⵖⵏ ⵖⵔ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵏⵏⴰ ⵓⵔ ⵜⴰ ⵉⵍⵍⵉⵏ. \nⴰⴼⴰⴷ ⴰⴷ ⵜⵙⵏⵓⵍⴼⵓⴷ ⵜⴰⵙⵏⴰ, ⵙⵙⵏⵜⵉ ⵜⵉⵔⵔⴰ ⴳ ⵓⴼⵏⵉⵇ ⴳ ⵉⵣⴷⴷⴰⵔ (ⵥⵔ [$1 ⵜⴰⵙⵏⴰ ⵏ ⵜⵡⵉⵙⵉ] ⵉ ⵡⵓⴳⴳⴰⵔ ⵏ ⵉⵏⵖⵎⵉⵙⵏ). \nⵎⴽ ⵜⵍⵍⵉⴷ ⴷⴰ ⵙ ⵓⵣⴳⴰⵍ, ⴰⴽⵍ ⵖⴼ <strong>ⴰⵖⵓⵍ</strong> ⴳ ⵓⵙⴰⵔⴰ ⵏⵏⴽ.",
+       "noarticletext": "ⵓⵔ ⵉⵍⵍⵉ ⴽⵔⴰ ⵏ ⵓⴹⵔⵉⵙ ⴳ ⵜⴰⵙⵏⴰ ⴰⴷ ⵖⵉⵍⴰ. \nⵜⵣⵎⵔⴷ ⴰⴷ [[Special:Search/{{PAGENAME}}|ⵜⵔⵣⵓⴷ ⵖⴼ ⵓⵣⵡⵍ ⵏⵏⵙ]] ⴳ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵢⴰⴹⵏ, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ⵔⵣⵓ ⵖⴼ logs ⵖⵔⵙ ⵉⵇⵇⵏⴻⵏ],\nⵏⵖ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ⵙⵏⵓⵍⴼⵓ ⵜⴰⵙⵏⴰ]</span>.",
+       "userpage-userdoesnotexist-view": "ⴰⵎⵉⴹⴰⵏ ⵏ ⵓⵎⵙⵙⵎⵔⵙ $1 ⵓⵔ ⵉⵜⵜⵓⵣⵎⵎⴻⵎ.",
        "continue-editing": "ⴷⴷⵓ ⵙ ⴰⵏⵙⴰ ⵏ ⵓⵙⵏⴼⵍ",
        "editing": "ⴰⵙⵏⴼⵍ ⵏ $1",
        "creating": "ⴰⵙⵏⵓⵍⴼⵓ ⵏ $1",
        "editingsection": "ⵙⵏⴼⵍ ⴰⴳⵣⵣⵓⵎ $1",
        "templatesused": "{{PLURAL:$1|ⵜⴰⵙⴽⴽⴰ|ⵜⴰⵙⴽⴽⵉⵡⵉⵏ}} {{PLURAL:$1|ⵉⵜⵜⵓⵙⵎⵔⵙⵏ|ⵜⵜⵓⵙⵎⵔⵙⵏⵉⵏ}} ⴳ ⵜⴰⵙⵏⴰ ⴰⴷ:",
        "template-protected": "(ⵉⵜⵜⵢⴰⵔⴰⵢ)",
+       "template-semiprotected": "(ⵜⵎⵃⴹⴰ ⵙ ⵓⴳⵣⵎⴰⵏ)",
        "hiddencategories": "ⵜⴰⵙⵏⴰ ⴰ ⴷ ⴰⴳⵎⴰⵎ ⵏ {{PLURAL:$1|1 ⵏⵜⵍ ⴰⵙⵎⵉⵍ|$1 ⵏⵜⵍ ⵉⵙⵎⵉⵍⵏ}}:",
        "content-model-wikitext": "wikitext",
+       "currentrev-asof": "ⴰⵣⵣⵔⴰⵢ ⴰⵎⴳⴳⴰⵔⵓ ⴳ $1",
        "revisionasof": "ⵜⵓⵏⵖⵉⵍⵜ ⵏ $1",
        "previousrevision": "ⵜⵓⵏⵖⵉⵍⵜ ⵜⴰⵇⴱⵓⵔⵜ",
+       "nextrevision": "ⴰⵣⵣⵔⴰⵢ ⴰⵎⴰⵢⵏⵓ",
+       "currentrevisionlink": "ⴰⵣⵣⵔⴰⵢ ⴰⵎⴳⴳⴰⵔⵓ",
        "cur": "ⵎⵔⵏ",
+       "last": "ⵓⵣⵡⵔ",
+       "history-fieldset-title": "ⵔⵣⵓ ⵖⴼ ⵉⵣⵣⵔⴰⵢⵏ",
        "histfirst": "ⴰⵇⴱⵓⵔ",
        "histlast": "ⴰⵎⴰⵢⵏⵓ",
+       "history-feed-title": "ⴰⵎⵣⵔⵓⵢ ⵏ ⵓⵣⵣⵔⴰⵢ",
+       "history-feed-description": "ⴰⵎⵣⵔⵓⵢ ⵏ ⵓⵣⵣⵔⴰⵢ ⵉ ⵜⴰⵙⵏⴰ ⴰⴷ ⴳ ⵡⵉⴽⵉ",
        "history-feed-item-nocomment": "$1 ⵖⵔ $2",
        "revdelete-show-file-submit": "ⵢⴰⵀ",
        "revdelete-log": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "mergehistory-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
+       "history-title": "ⴰⵎⵣⵔⵓⵢ ⵏ ⵓⵣⵣⵔⴰⵢ ⵏ \"$1\"",
+       "difference-title": "ⴰⵎⵣⴰⵔⴰⵢ ⴳⵔ ⵉⵣⵣⵔⴰⵢⵏ ⵏ $1",
        "lineno": "ⵉⵣⵔⵉⵔⵉ $1:",
+       "compareselectedversions": "ⵙⵎⵣⴰⵣⴰⵍ ⵉⵣⵣⵔⴰⵢⵏ ⵉⵜⵜⵓⵙⵜⴰⵢⵏ",
        "editundo": "ⵙⵔ",
        "searchresults": "ⵜⵉⵢⴰⴼⵓⵜⵉⵏ ⵏ ⵓⵔⵣⵣⵓ",
        "searchresults-title": "ⵜⵉⵢⴰⴼⵓⵜⵉⵏ ⵏ ⵓⵔⵣⵣⵓ ⵖⴼ \"$1\"",
+       "prevn": "{{PLURAL:$1|$1}} ⵉⵎⵣⵡⵓⵔⴰ",
        "nextn": "{{PLURAL:$1|$1}} ⴰⵎⴹⴼⵉⵔ",
        "shown-title": "ⵙⵎⴰⵍ $1 {{PLURAL:$1|ⵜⵢⴰⴼⵓⵜ|ⵜⵢⴰⴼⵓⵜⵉⵏ}} ⵉ ⵜⴰⵙⵏⴰ",
        "viewprevnext": "ⵥⵕ ($1 {{int:pipe-separator}} $2) ($3)",
        "search-suggest": "ⵉⵙ ⵜⵅⵙⴷ ⴰⴷ ⵜⵉⵏⵉⴷ: $1",
        "search-interwiki-more": "(ⵓⴳⴳⴰⵔ)",
        "searchall": "ⴰⴽⴽ",
+       "search-nonefound": "ⵓⵔ ⵍⵍⵉⵏⵜ ⵜⵢⴰⴼⵓⵜⵉⵏ ⵉⵎⵙⴰⵙⴰⵏ ⴷ ⵓⵙⵓⵜⵔ.",
        "mypreferences": "ⵉⵙⵎⵏⵢⵉⴼⵏ",
        "prefs-files": "ⵉⴼⴰⵢⵍⵓⵜⵏ",
        "youremail": "ⵉⵎⴰⵢⵍ:",
        "recentchanges-label-newpage": "ⵉⵙⵏⴼⵍⵓⵍ ⵓⵙⵏⴼⵍ ⴰ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵜⴰⵎⴰⵢⵏⵓⵜ",
        "recentchanges-label-minor": "ⵡⴰ ⴷ ⴰⵙⵏⴼⵍ ⵓⵎⵥⵉⵢ",
        "recentchanges-label-bot": "ⴰⵙⵏⴼⵍ ⴰⴷ ⵉⵜⵡⴰⵙⴽⴰⵔ ⵙ ⵓⴱⵓⵜ",
+       "recentchanges-label-plusminus": "ⵜⴰⵙⵎⴽⵜⴰ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ ⵜⵙⵙⵏⴼⵍ ⵙ ⵓⵎⴹⴰⵏ ⴰⴷ ⵏ ⵉⴱⴰⵢⵜⵏ",
+       "recentchanges-legend-heading": "<strong>ⴰⵙⵙⴼⵔⵓ:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ⵥⵔ ⴰⵍⵜⵓ [[Special:NewPages|ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵜⵉⵎⴰⵢⵏⵓⵜⵉⵏ]])",
        "rclistfrom": "ⵙⴽⵏ ⵉⵙⵏⴼⵍⵏ ⵉⵎⴰⵢⵏⵓⵜⵏ ⵙⴳ $2,$3",
        "rcshowhideminor": "$1 ⵉⵙⵏⴼⴰⵍ ⵓⵎⵥⵉⵢⵏ",
        "rcshowhideminor-show": "ⵙⴽⵏ",
        "rcshowhidebots": "$1 {{PLURAL:$1|ⴱⵓⵜ|ⵉⴷ ⴱⵓⵜ}}",
        "rcshowhidebots-show": "ⵙⵎⴰⵍ",
        "rcshowhidebots-hide": "ⵙⵙⵏⵜⵍ",
+       "rcshowhideliu": "$1 ⵉⵎⵙⵙⵎⵔⵙⵏ ⵉⵜⵜⵓⵣⵎⴻⵎⵏ",
        "rcshowhideliu-show": "ⵙⴽⵏ",
        "rcshowhideliu-hide": "ⵙⵙⵏⵜⵍ",
        "rcshowhideanons": "$1 ⵉⵏⵙⵙⵎⵔⵙⵏ ⵉⵔⵓⵙⵙⵉⵏⵏ",
        "filehist-comment": "ⴰⵖⴼⴰⵡⴰⵍ",
        "imagelinks": "ⴰⵙⵎⵔⵙ ⵏ ⵓⴼⴰⵢⵍⵓ",
        "linkstoimage": "{{PLURAL:$1|ⵉⵣⴷⴰⵢⵏ ⵏ ⵜⵙⵏⴰ|$1 ⴰⵣⴷⴰⵢ ⵏ ⵜⵙⵏⴰ}} ⵖⵔ ⵓⴼⴰⵢⵍⵓ ⴰⴷ:",
+       "nolinkstoimage": "ⵓⵔ ⵍⵍⵉⵏⵜ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏⵏⴰ ⵉⵇⵇⵏⴻⵏ ⵖⵔ ⵓⴼⴰⵢⵍⵓ ⴰ.",
        "sharedupload-desc-here": "ⴰⵙⴷⴰⵡ ⴰⴷ ⵙⴳ $1 ⵉⵥⴹⴰⵔ ⴰ ⵉⵜⵜⵡⴰⵙⵎⵔⵙ ⴳ ⵉⵙⵏⵜⴰⵢⵏ ⵢⴰⴹⵏ.\nⴰⵙⵏⵓⵎⵎⵍ ⵏⵙ ⴳ [$2 ⵜⴰⵙⵏⴰ ⵏⵙ ⵏ ⵓⵙⵏⵓⵎⵎⵍ] ⵜⵡⴰⵙⵎⴰⵍ ⵙⴰⴷⵓ.",
        "filepage-nofile": "ⵓⵔ ⵓⴼⴰⵢⵍⵓ ⵙ ⵢⵉⵙⵎ ⴰ.",
        "filerevert-comment": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "changecontentmodel-reason-label": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "protectedarticle": "ⵉⵎⵃⴹⵉ \"[[$1]]\"",
        "protectcomment": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
+       "protect-default": "ⴰⵊⵊ ⵉⵎⵙⵙⵎⵔⵙⵏ ⴰⴽⴽⵯ",
        "restriction-edit": "ⵙⵏⴼⵍ",
        "restriction-move": "ⵙⵎⵓⵜⵜⵉ",
        "undeletecomment": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
        "undelete-show-file-submit": "ⵢⴰⵀ",
        "namespace": "ⵜⵉⵔⵉⵡⵉⵏ ⵏ ⵉⵙⵎⴰⵡⵏ:",
        "invert": "ⵙⵏⵅⴰⵍⴼ ⴰⵙⵜⵉ",
+       "tooltip-invert": "ⵙⵎⴰⵜⵔ ⵜⴰⴼⵏⵉⵇⵜ ⴰⴷ ⵃⵎⴰ ⴰⴷ ⵏⵜⵍⵏ ⵉⵙⵏⴼⵍⵏ ⵏ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵍⵍⴰⵏ ⴳ ⵜⵔⵉⵡⵜ ⵏ ⵉⵙⵎ ⵏⵏⴰ ⵜⵙⵜⵉⴷ (ⴷ ⵜⵔⵉⵡⵜ ⵏ ⵉⵙⵎ ⴷⵉⴳⵙ ⵉⵣⴷⵉⵏ ⵉⴳ ⵜⵡⴰⵙⵜⴰⵢ)",
+       "namespace_association": "ⵜⵉⵔⵉⵡⵜ ⵏ ⵢⵉⵙ ⵎⵉⵣⴷⵉⵏ",
+       "tooltip-namespace_association": "ⵙⵎⴰⵜⵔ ⵜⴰⴼⵏⵉⵇⵜ ⴰⴷ ⵃⵎⴰ ⴰⴷ ⵜⵙⵎⵓⵏⴷ ⴰⵍⵜⵓ ⵜⵉⵔⵉⵡⵜ ⵏ ⵉⵙⵎ ⵏ ⵓⵎⵙⴰⵡⴰⵍ ⵏⵖ ⵜⵉⵏ ⵜⵖⴰⵡⵙⴰ ⵉⵣⴷⵉⵏ ⴷ ⵜⵔⵉⵡⵜ ⵏ ⵉⵙⵎ ⵏⵏⴰ ⵜⵙⵜⵉⴷ",
        "blanknamespace": "(ⴰⴷⵙⵍⴰⵏ)",
        "contributions": "ⵜⵓⵎⵓⵜⵉⵏ ⵏ {{GENDER:$1|ⵓⵏⵙⵙⵎⵔⵙ}}",
+       "contributions-title": "ⵜⵓⵎⵓⵜⵉⵏ ⵏ ⵓⵎⵙⵙⵎⵔⵙ $1",
        "mycontris": "ⵜⵓⵎⵓⵜⵉⵏ",
        "anoncontribs": "ⵜⵓⵎⵓⵜⵉⵏ",
        "contribsub2": "ⵉ {{GENDER:$3|$1}} ($2)",
+       "month": "ⵙⴳ ⵡⴰⵢⵢⵓⵔ (and earlier):",
+       "year": "ⵙⴳ ⵓⵙⴳⴳⵯⴰⵙ (and earlier):",
+       "sp-contributions-newbies": "ⵙⴽⵏ ⵜⵓⵎⵓⵜⵉⵏ ⵏ ⵉⵎⵉⴹⴰⵏ ⵉⵎⴰⵢⵏⵓⵜⵏ ⴽⴰⵏ",
+       "sp-contributions-uploads": "ⵉⵙⴽⵜⴰⵔⵏ",
        "sp-contributions-talk": "ⵎⵙⴰⵡⴰⵍ",
+       "sp-contributions-search": "ⵔⵣⵓ ⵖⴼ ⵜⵓⵎⵓⵜⵉⵏ",
+       "sp-contributions-newonly": "ⵙⴽⵏ ⵖⴰⵙ ⵉⵙⵏⵍⵏ ⵏⵏⴰ ⵉⴳⴰⵏ ⵉⵙⵏⵓⵍⴼⵓⵜⵏ ⵏ ⵜⴰⵙⵏⴰ",
        "sp-contributions-submit": "ⵔⵣⵓ",
        "whatlinkshere": "ⵎⴰ ⴰⵢⴷ ⵉⵇⵇⵏⵏ ⵙ ⴷⴰ",
        "whatlinkshere-title": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⵖⵔ $1",
        "whatlinkshere-hideimages": "$1 ⵉⵣⴷⴰⵢⵏ ⵖⵔ ⵓⴼⵉⵍⵢⵓ",
        "whatlinkshere-filters": "ⵜⵉⵙⵜⵜⴰⵢⵉⵏ",
        "ipbreason": "ⵜⴰⵎⵏⵜⵉⵍⵜ:",
+       "ipboptions": "2 ⵏ ⵜⵙⵔⴰⴳⵉⵏ:2 ⵏ ⵜⵙⵔⴰⴳⵉⵏ,1 ⵏ ⵡⴰⵙⵙ:1 ⵏ ⵡⴰⵙⵙ,3 ⵏ ⵡⵓⵙⵙⴰⵏ:3 ⵏ ⵡⵓⵙⵙⴰⵏ,1 ⵏ ⵉⵎⴰⵍⴰⵙⵙ:1 ⵏ ⵉⵎⴰⵍⴰⵙⵙk,2 ⵏ ⵉⵎⴰⵍⴰⵙⵙⵏ:2 ⵏ ⵉⵎⴰⵍⴰⵙⵙⵏ,1 ⵏ ⵡⴰⵢⵢⵓⵔ:1 ⵏ ⵡⴰⵢⵢⵓⵔ,3 ⵏ ⵡⴰⵢⵢⵓⵔⵏ:3 ⵏ ⵡⴰⵢⵢⵓⵔⵏ,6 ⵏ ⵡⴰⵢⵢⵓⵔⵏ:6 ⵏ ⵡⴰⵢⵢⵓⵔⵏ,1 ⵏ ⵓⵙⴳⴳⴰⵙ:1 ⵏ ⵓⵙⴳⴳⴰⵙ,indefinite:infinite",
        "blocklist-reason": "ⵜⴰⵎⵏⵜⵉⵍⵜ",
        "blocklink": "ⴳⴷⵍ",
        "contribslink": "ⵜⵓⵎⵓⵜⵉⵏ",
        "tooltip-n-help": "The place to find out",
        "tooltip-t-whatlinkshere": "ⵓⵎⵓⵖ ⵏ ⵎⴰⵕⵕ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵏ ⵡⵉⴽⵉ ⵉⵣⴷⵉⵏ ⵉ ⴷⴰ",
        "tooltip-t-recentchangeslinked": "ⵉⵙⵏⴼⵍⵏ ⵉⵏⴳⴳⵓⵔⴰ ⴳ ⵜⴰⵙⵏⵉⵡⵉⵏ ⵉⵣⴷⵉⵏ ⵖⵔ ⵜⴰⵙⵏⴰ ⴰ",
+       "tooltip-feed-atom": "ⴰⵏⴳⵉ ⵏ ⴰⵜⵓⵎ ⵏ ⵜⴰⵙⵏⴰ ⴰⴷ",
        "tooltip-t-contributions": "ⵢⴰⵜ ⵜⵍⴳⴰⵎⵜ ⵏ ⵜⵓⵎⵓⵜⵉⵏ ⵏ {{GENDER:$1|ⵓⵙⵎⵔⴰⵙ ⴰ}}",
        "tooltip-t-emailuser": "ⴰⵣⵏ ⵢⴰⵏ ⵉⵎⴰⵢⵍ ⵉ {{GENDER:$1|ⴰⵏⵙⵙⵎⵔⵙ ⴰ|ⵜⴰⵏⵙⵙⵎⵔⵙⵜ ⴰ}}",
        "tooltip-t-upload": "ⵙⴽⵜⵔ ⵉⴼⵓⵢⵍⴰ",
        "tooltip-ca-nstab-special": "ⵜⴰⴷ ⵜⴳⴰ ⵢⴰⵜ ⵜⴰⵙⵏⴰ ⵉⵣⵍⵉⵏ, ⵓⵔ ⵢⴰⵍⵍⴼⵓⵙ ⴰⴷ ⵜⴻⵜⵜⵓⵙⵏⴼⵍ",
        "tooltip-ca-nstab-project": "ⵥⵕ ⵜⴰⵙⵏⴰ ⵏ ⵓⵙⵏⵜⵉ",
        "tooltip-ca-nstab-image": "ⵙⴽⵏ ⵜⴰⵙⵏⴰ ⵏ ⵓⴼⴰⵢⵍⵓ",
+       "tooltip-ca-nstab-mediawiki": "ⵥⵔ ⵜⵓⵣⵉⵏⵜ ⵏ ⵓⵏⴳⵔⴰⵡ",
        "tooltip-ca-nstab-template": "ⵥⵔ ⵜⴰⵙⴽⴽⴰ",
        "tooltip-ca-nstab-category": "ⵙⴽⵏ ⴰⵏⴰⵡ ⵏ ⵜⴰⵙⵏⴰ",
+       "tooltip-minoredit": "ⵕⵛⵎ ⵓⵢⴰ ⴰⵎ ⴰⵙⵏⴼⵍ ⵎⵥⵥⵉⵢⵏ",
        "tooltip-save": "ⵃⴹⵓ ⵉⵙⵏⴼⴰⵍ ⵏⵏⴽ",
        "tooltip-diff": "ⵙⴽⵏ ⵎⴰⵏ ⵉⵙⵏⴼⴰⵍ ⵜⴳⴳⵉⴷ ⵉ ⵓⴹⵔⵉⵙ",
        "tooltip-watch": "ⵔⵏⵓ ⵜⴰⵙⵏⴰ ⴰ ⵉ ⵜⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ {{GENDER:|ⵏⵏⴽ|ⵏⵏⵎ}}",
        "tooltip-rollback": "\"ⵔⴰⵔ\" ⵙⵙⵔ ⴰⵙⵏⴼⵍ ⵏⵖ ⵉⵙⵏⴼⴰⵍⵏ ⵏ ⵓⵎⴰⴷⵔⴰⵡ ⴰⵎⴳⴳⴰⵔⵓ ⴳ ⵜⴰⵙⵏⴰ ⴷ ⵙ ⵢⴰⵏ ⵓⴽⵍⵉⴽ",
+       "tooltip-summary": "ⴰⵔⴰ ⴽⵔⴰ ⵏ ⵓⵙⴳⵣⵍ ⵎⵥⵥⵉⵢⵏ",
+       "pageinfo-title": "ⵉⵏⵖⵎⵉⵙⵏ ⵖⴼ $1",
        "pageinfo-header-edits": "ⵙⵏⴼⵍ ⴰⵎⵣⵔⵓⵢ",
+       "pageinfo-header-restrictions": "ⴰⴼⵔⴰⴳ ⵏ ⵜⴰⵙⵏⴰ",
        "pageinfo-display-title": "ⵙⴽⵏ ⴰⵣⵡⵍ",
+       "pageinfo-article-id": "ID ⵏ ⵜⴰⵙⵏⴰ",
        "pageinfo-language": "ⵜⵓⵜⵍⴰⵢⵜ ⵏ ⵜⵙⵏⴰ",
        "pageinfo-watchers": "ⵓⵟⵟⵓⵏ ⵏ ⵉⵎⵥⵕⴰⵢⵏ ⵏ ⵜⴰⵙⵏⴰ",
+       "pageinfo-firstuser": "ⴰⵎⵙⵏⵓⵍⴼⵓ ⵏ ⵜⴰⵙⵏⴰ",
        "pageinfo-firsttime": "ⴰⵙⴰⴽⵓⴷ ⵏ ⵓⵙⵏⴼⵍⵓⵍ ⵏ ⵜⴰⵙⵏⴰ",
        "pageinfo-lastuser": "ⴰⵎⵙⵏⴼⵍ ⴰⵎⴳⴳⴰⵔⵓ",
        "pageinfo-lasttime": "ⴰⵙⴰⴽⵓⴷ ⵏ ⵓⵙⵏⴼⵍ ⴰⵎⴳⴳⴰⵔⵓ",
        "pageinfo-edits": "ⵎⴰⵕⵕⴰ ⵓⵟⵟⵓⵏ ⵏ ⵉⵙⵏⴼⴰⵍⵏ",
        "pageinfo-hidden-categories": "ⵏⵜⵍ {{PLURAL:$1|ⴰⵙⵎⵉⵍ|ⵉⵙⵎⵉⵍⵏ}}($1)",
        "pageinfo-toolboxlink": "ⴰⵏⵖⵎⵉⵙ ⵖⴼ ⵜⴰⵙⵏⴰ",
+       "pageinfo-contentpage": "ⵉⵜⵜⵓⵙⵉⴹⵏ ⴰⵎ ⵜⴰⵙⵏⴰ ⵏ ⵜⵓⵎⴰⵢⵜ",
        "pageinfo-contentpage-yes": "ⵢⴰⵀ",
        "pageinfo-protect-cascading-yes": "ⵢⴰⵀ",
        "previousdiff": "ⴰⵙⵏⴼⵍ ⴰⵎⴳⴳⴰⵔⵓ",
        "show-big-image-other": "{{PLURAL:$2|ⵜⴰⴼⵙⴰⵢⵜ|ⵜⵉⴼⵙⴰⵢⵉⵏ}}: ⵢⴰⴹⵏ $1.",
        "show-big-image-size": "$1 × $2 ⵉⴷ ⴱⵉⴽⵙⵍ",
        "metadata": "ⵎⵉⵜⴰⴷⴰⵜⴰ",
+       "metadata-help": "ⴰⵙⴷⴰⵡ ⴰ ⵢⵓⵎⴰ ⵉⵏⵖⵎⵉⵙⵏ ⵉⵎⵔⵏⴰⵏⵉⵏ, ⵉⵔⵡⴰⵙ ⵉⵙ ⴰⵙ ⵜⵜⵡⴰⵔⵏⵉⵏ ⵙ ⵍⴽⴰⵎⵉⵔⴰ ⵜⴰⵎⵓⵟⵟⵓⵏⵜ ⵏⵖ ⴰⵙⵏⴼⴰⵍ ⴰⵎⵓⵟⵟⵓⵏ ⵉⵜⵜⴰⵡⵙⵎⵔⵙⵏ ⴳ ⵓⵙⵏⴼⵍⵓⵍ ⵏ ⵓⵙⴷⴰⵡ ⴰ.\nⵉⵖ ⵉⵜⵜⵙⵏⴼⵍ ⵓⵙⴷⴰⵡ ⴰ ⵙⴳ ⵡⴰⴷⴷⴰⴷ ⵏⵙ ⴰⵎⵓⴷⴰⵏ, ⴽⵔⴰ ⵏ ⵉⴼⵔⵓⵔⵉⵜⵏ ⵓⵔ ⵔⴰⵏ ⵙⵓⵍ ⴳⵔⵏ ⴳ ⵓⵙⴷⴰⵡ ⵉⵜⵜⵙⵏⴼⵍⵏ.",
        "metadata-fields": "ⵉⴳⵔⴰⵏ ⵏ ⵎⵉⵜⴰⵉⵙⴼⴽⴰ ⵏ ⵜⵉⵡⵍⴰⴼⵉⵏ ⵏⵏⴰ ⵉⴼⵙⵔⵏ ⴳ ⵜⴱⵔⴰⵜ ⴰⴷ ⵔⴰⴷ ⵉⵍⵉⵏ ⴳ ⵜⴰⵙⵏⴰ ⵏ ⵓⵙⵏⵓⵎⵎⵍ ⵏ ⵜⴰⵡⵍⴰⴼⵜ ⴰⴽⵓⴷ ⵏⵏⴰ ⵉⵎⵓⵏ ⵓⵙⴽⵜⵓⵔ. ⵉⴳⵔⴰⵏ ⵢⴰⴹⵏ ⵔⴰⴷ ⴼⴼⵔⵏ ⵙ ⵓⵎⵕⴰⴹ.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-orientation": "ⴰⵙⵡⴰⵍⴰ",
        "exif-datetime": "ⴰⵙⴰⴽⵓⴷ ⴷ ⵡⴰⴽⵓⴷ ⵏ ⵓⵙⵏⴼⵍ ⵏ ⵓⴼⴰⵢⵍⵓ",
+       "exif-colorspace": "ⵜⵉⵔⵉⵡⵜ ⵏ ⵓⴽⵍⵓ",
        "exif-languagecode": "ⵜⵓⵜⵍⴰⵢⵜ",
        "exif-dc-contributor": "ⵉⵏⴰⵎⵓⵜⵏ",
        "exif-iimcategory-edu": "ⴰⵙⴳⵎⵉ",
        "watchlisttools-clear": "ⵙⴼⴹ ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
        "watchlisttools-edit": "ⵥⵕ ⴷ ⵜⵙⵏⴼⵍⴷ ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⴹⴼⴼⵓⵔ",
        "redirect-submit": "ⴷⴷⵓ",
+       "redirect-user": "ID ⵏ ⵓⵎⵙⵙⵎⵔⵙ",
+       "redirect-page": "ID ⵏ ⵜⴰⵙⵏⴰ",
+       "redirect-revision": "ⴰⵣⵣⵔⴰⵢ ⵏ ⵜⴰⵙⵏⴰ",
        "redirect-file": "ⵉⵙⵎ ⵏ ⵓⴼⴰⵍⵢⵓ",
        "specialpages": "ⵜⴰⵙⵏⵉⵡⵉⵏ ⵥⵍⵉⵏⵉⵏ",
        "specialpages-group-pagetools": "ⵉⵎⴰⵙⵙⵏ ⵏ ⵜⴰⵙⵏⴰ",
        "htmlform-yes": "ⵢⴰⵀ",
        "logentry-delete-delete": "$1 {{GENDER:$2|ⵉⴽⴽⵙ|ⵜⴽⴽⵙ}} ⵜⴰⵙⵏⴰ $3",
        "logentry-move-move": "$1 {{GENDER:$2|ⵉⵙⵎⵓⵜⵜⵉ|ⵜⵙⵎⵓⵜⵜⵉ}} ⵜⴰⵙⵏⴰ ⵙⴳ $3 ⵖⵔ $4",
+       "logentry-move-move-noredirect": "{{GENDER:$2|ⵉⵙⵎⵓⵜⵜⵉ}} $1 ⵜⴰⵙⵏⴰ $3 ⵖⵔ $4 ⵎⵉⵏ ⴰⴷ ⵉⴼⵍ redirect",
        "logentry-newusers-create": "{{GENDER:$2|ⵉⵙⵏⴼⵍ ⵓⵏⵙⵙⵎⵔⵙ|ⵜⵙⵏⴼⵍ ⵜⵏⵙⵙⵎⵔⵙⵜ}} $1 ⴰⵎⵉⴹⴰⵏ ⵏⵙ",
        "logentry-upload-upload": "{{GENDER:$2|ⵉⵙⴽⵜⵔ|ⵜⵙⴽⵜⵔ}} $1 $3",
        "feedback-thanks-title": "ⵜⴰⵏⵎⵎⵉⵔⵜ!",
        "searchsuggest-search": "ⵔⵣⵓ ⴳ {{SITENAME}}",
+       "duration-days": "$1 ⵏ {{PLURAL:$1|ⵡⴰⵙⵙ|ⵡⵓⵙⵙⴰⵏ}}",
        "expand_templates_ok": "ⵡⴰⵅⵅⴰ",
        "pagelanguage": "ⵙⵏⴼⵍ ⵜⵓⵜⵍⴰⵢⵜ ⵏ ⵜⴰⵙⵏⴰ",
        "pagelang-name": "ⵜⴰⵙⵏⴰ",
index f504416..2f7673c 100644 (file)
        "createacct-another-continue-submit": "繼續帳號建立",
        "createacct-benefit-heading": "{{SITENAME}} 是由像您一樣貢獻的人所建立的。",
        "createacct-benefit-body1": "{{PLURAL:$1|次編輯}}",
-       "createacct-benefit-body2": "$1 頁",
-       "createacct-benefit-body3": " 位最近的{{PLURAL:$1|貢獻者}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|個頁面}}",
+       "createacct-benefit-body3": "位最近的{{PLURAL:$1|貢獻者}}",
        "badretype": "兩次輸入的密碼並不相同。",
        "usernameinprogress": "已正在進行此使用者名稱的帳號建立作業。\n請稍候。",
        "userexists": "您所輸入的使用者名稱已存在,請另選一個名稱。",
index 1778a79..0c79bd5 100644 (file)
@@ -678,7 +678,7 @@ abstract class Maintenance {
         * Do some sanity checking and basic setup
         */
        public function setup() {
-               global $IP, $wgCommandLineMode, $wgRequestTime;
+               global $IP, $wgCommandLineMode;
 
                # Abort if called from a web server
                # wfIsCLI() is not available yet
@@ -715,8 +715,6 @@ abstract class Maintenance {
                # But sometimes this doesn't seem to be the case.
                ini_set( 'max_execution_time', 0 );
 
-               $wgRequestTime = microtime( true );
-
                # Define us as being in MediaWiki
                define( 'MEDIAWIKI', true );
 
diff --git a/maintenance/archives/patch-rev_text_id-default.sql b/maintenance/archives/patch-rev_text_id-default.sql
new file mode 100644 (file)
index 0000000..dc6e4c6
--- /dev/null
@@ -0,0 +1,10 @@
+--
+-- Adds a default value to the rev_text_id field in the revision table.
+-- This is to allow the Multi Content Revisions migration to happen where
+-- rows will have to be added to the revision table with no rev_text_id.
+--
+-- 2018-03-12
+--
+
+ALTER TABLE /*$wgDBprefix*/revision
+  ALTER COLUMN rev_text_id SET DEFAULT 0;
\ No newline at end of file
diff --git a/maintenance/archives/patch-slot-origin.sql b/maintenance/archives/patch-slot-origin.sql
new file mode 100644 (file)
index 0000000..ee06923
--- /dev/null
@@ -0,0 +1,15 @@
+--
+-- Replace slot_inherited with slot_origin.
+--
+-- NOTE: There is no release that has slot_inherited. This is only needed to transition between
+-- snapshot versions of 1.30.
+--
+-- NOTE: No code that writes to the slots table was merged yet, the table is assumed to be empty.
+--
+DROP INDEX /*i*/slot_role_inherited ON /*_*/slots;
+
+ALTER TABLE /*_*/slots
+  DROP COLUMN slot_inherited,
+  ADD COLUMN slot_origin bigint unsigned NOT NULL;
+
+CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
index 1a51bb9..5fafe6d 100644 (file)
@@ -14,11 +14,12 @@ CREATE TABLE /*_*/slots (
   -- reference to content_id
   slot_content_id bigint unsigned NOT NULL,
 
-  -- whether the content is inherited (1) or new in this revision (0)
-  slot_inherited tinyint unsigned NOT NULL DEFAULT 0,
+  -- The revision ID of the revision that originated the slot's content.
+  -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
+  slot_origin bigint unsigned NOT NULL,
 
   PRIMARY KEY ( slot_revision_id, slot_role_id )
 ) /*$wgDBTableOptions*/;
 
 -- Index for finding revisions that modified a specific slot
-CREATE INDEX /*i*/slot_role_inherited ON /*_*/slots (slot_revision_id, slot_role_id, slot_inherited);
\ No newline at end of file
+CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
index eb09fb2..a00f52b 100644 (file)
@@ -2,6 +2,6 @@ maintenance/dev/ scripts can help quickly setup a local MediaWiki for developmen
 
 Wikis setup in this way are NOT meant to be publicly available. They use a development database not acceptable for use in production. Place a sqlite database in an unsafe location a real wiki should never place it in. And use predictable default logins for the initial administrator user.
 
-Running maintenance/dev/install.sh will download and install a local copy of php 5.4, install a sqlite powered instance of MW for development, and then start up a local webserver to view the wiki.
+Running maintenance/dev/install.sh will download and install a local copy of php 5.6, install a sqlite powered instance of MW for development, and then start up a local webserver to view the wiki.
 
 After installation you can bring the webserver back up at any time you want with maintenance/dev/start.sh
diff --git a/maintenance/mssql/archives/patch-rev_text_id-default.sql b/maintenance/mssql/archives/patch-rev_text_id-default.sql
new file mode 100644 (file)
index 0000000..0c9d48a
--- /dev/null
@@ -0,0 +1,10 @@
+--
+-- Adds a default value to the rev_text_id field in the revision table.
+-- This is to allow the Multi Content Revisions migration to happen where
+-- rows will have to be added to the revision table with no rev_text_id.
+--
+-- 2018-03-12
+--
+
+ALTER TABLE /*_*/revision
+  ADD CONSTRAINT DF_rev_text_id DEFAULT 0 FOR rev_text_id;
\ No newline at end of file
diff --git a/maintenance/mssql/archives/patch-slot-origin.sql b/maintenance/mssql/archives/patch-slot-origin.sql
new file mode 100644 (file)
index 0000000..bba3be4
--- /dev/null
@@ -0,0 +1,14 @@
+--
+-- Replace slot_inherited with slot_origin.
+--
+-- NOTE: There is no release that has slot_inherited. This is only needed to transition between
+-- snapshot versions of 1.30.
+--
+-- NOTE: No code that writes to the slots table was merge yet, the table is assumed to be empty.
+--
+DROP INDEX /*i*/slot_role_inherited ON /*_*/slots;
+
+ALTER TABLE /*_*/slots DROP CONSTRAINT DF_slot_inherited, COLUMN slot_inherited;
+ALTER TABLE /*_*/slots ADD COLUMN slot_origin bigint NOT NULL;
+
+CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
index 91d3168..e9ec7c3 100644 (file)
@@ -14,11 +14,12 @@ CREATE TABLE /*_*/slots (
   -- reference to content_id
   slot_content_id bigint unsigned NOT NULL CONSTRAINT FK_slots_content_id FOREIGN KEY REFERENCES content(content_id),
 
-  -- whether the content is inherited (1) or new in this revision (0)
-  slot_inherited tinyint unsigned NOT NULL CONSTRAINT DF_slot_inherited DEFAULT 0,
+  -- The revision ID of the revision that originated the slot's content.
+  -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
+  slot_origin bigint unsigned NOT NULL,
 
   CONSTRAINT PK_slots PRIMARY KEY (slot_revision_id, slot_role_id)
 );
 
 -- Index for finding revisions that modified a specific slot
-CREATE INDEX /*i*/slot_role_inherited ON /*_*/slots (slot_revision_id, slot_role_id, slot_inherited);
\ No newline at end of file
+CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
index 5348c47..ddc5517 100644 (file)
@@ -191,7 +191,7 @@ INSERT INTO /*_*/page (page_namespace, page_title, page_restrictions, page_lates
 CREATE TABLE /*_*/revision (
    rev_id INT NOT NULL UNIQUE IDENTITY(0,1),
    rev_page INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
-   rev_text_id INT  NOT NULL, -- FK added later
+   rev_text_id INT NOT NULL CONSTRAINT DF_rev_text_id DEFAULT 0, -- FK added later
    rev_comment NVARCHAR(255) NOT NULL CONSTRAINT DF_rev_comment DEFAULT '',
    rev_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
    rev_user_text NVARCHAR(255) NOT NULL DEFAULT '',
@@ -311,14 +311,15 @@ CREATE TABLE /*_*/slots (
   -- reference to content_id
   slot_content_id bigint unsigned NOT NULL CONSTRAINT FK_slots_content_id FOREIGN KEY REFERENCES content(content_id),
 
-  -- whether the content is inherited (1) or new in this revision (0)
-  slot_inherited tinyint unsigned NOT NULL CONSTRAINT DF_slot_inherited DEFAULT 0,
+  -- The revision ID of the revision that originated the slot's content.
+  -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
+  slot_origin bigint NOT NULL,
 
   CONSTRAINT PK_slots PRIMARY KEY (slot_revision_id, slot_role_id)
 );
 
 -- Index for finding revisions that modified a specific slot
-CREATE INDEX /*i*/slot_role_inherited ON /*_*/slots (slot_revision_id, slot_role_id, slot_inherited);
+CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
 
 --
 -- The content table represents content objects. It's primary purpose is to provide the necessary
diff --git a/maintenance/oracle/archives/patch-slot-origin.sql b/maintenance/oracle/archives/patch-slot-origin.sql
new file mode 100644 (file)
index 0000000..1b398cd
--- /dev/null
@@ -0,0 +1,14 @@
+--
+-- Replace slot_inherited with slot_origin.
+--
+-- NOTE: There is no release that has slot_inherited. This is only needed to transition between
+-- snapshot versions of 1.30.
+--
+-- NOTE: No code that writes to the slots table was merge yet, the table is assumed to be empty.
+--
+DROP INDEX &mw_prefix.slot_role_inherited;
+
+ALTER TABLE &mw_prefix.slots DROP COLUMN slot_inherited;
+ALTER TABLE &mw_prefix.slots ADD ( slot_origin NUMBER NOT NULL );
+
+CREATE INDEX &mw_prefix.slot_revision_origin_role ON &mw_prefix.slots (slot_revision_id, slot_origin, slot_role_id);
index 094ab68..fde35d5 100644 (file)
@@ -2,9 +2,9 @@ CREATE TABLE &mw_prefix.slots (
   slot_revision_id NUMBER NOT NULL,
   slot_role_id NUMBER NOT NULL,
   slot_content_id NUMBER NOT NULL,
-  slot_inherited CHAR(1) DEFAULT '0' NOT NULL
+  slot_origin NUMBER NOT NULL
 );
 
 ALTER TABLE &mw_prefix.slots ADD CONSTRAINT &mw_prefix.slots_pk PRIMARY KEY (slot_revision_id, slot_role_id);
 
-CREATE INDEX &mw_prefix.slot_role_inherited ON &mw_prefix.slots (slot_revision_id, slot_role_id, slot_inherited);
\ No newline at end of file
+CREATE INDEX &mw_prefix.slot_revision_origin_role ON &mw_prefix.slots (slot_revision_id, slot_origin, slot_role_id);
index 110188d..058ef15 100644 (file)
@@ -287,12 +287,12 @@ CREATE TABLE &mw_prefix.slots (
   slot_revision_id NUMBER NOT NULL,
   slot_role_id NUMBER NOT NULL,
   slot_content_id NUMBER NOT NULL,
-  slot_inherited CHAR(1) DEFAULT '0' NOT NULL
+  slot_origin NUMBER NOT NULL
 );
 
 ALTER TABLE &mw_prefix.slots ADD CONSTRAINT &mw_prefix.slots_pk PRIMARY KEY (slot_revision_id, slot_role_id);
 
-CREATE INDEX &mw_prefix.slot_role_inherited ON &mw_prefix.slots (slot_revision_id, slot_role_id, slot_inherited);
+CREATE INDEX &mw_prefix.slot_revision_origin_role ON &mw_prefix.slots (slot_revision_id, slot_origin, slot_role_id);
 
 
 CREATE SEQUENCE content_content_id_seq;
index 9cad0d1..514921f 100644 (file)
@@ -2,8 +2,8 @@ CREATE TABLE slots (
   slot_revision_id INTEGER   NOT NULL,
   slot_role_id     SMALLINT  NOT NULL,
   slot_content_id  INTEGER   NOT NULL,
-  slot_inherited   SMALLINT  NOT NULL  DEFAULT 0,
+  slot_origin INTEGER   NOT NULL,
   PRIMARY KEY (slot_revision_id, slot_role_id)
 );
 
-CREATE INDEX slot_role_inherited ON slots (slot_revision_id, slot_role_id, slot_inherited);
\ No newline at end of file
+CREATE INDEX slot_revision_origin_role ON slots (slot_revision_id, slot_origin, slot_role_id);
index 01177d8..1e1c434 100644 (file)
@@ -264,11 +264,11 @@ CREATE TABLE slots (
   slot_revision_id INTEGER   NOT NULL,
   slot_role_id     SMALLINT  NOT NULL,
   slot_content_id  INTEGER   NOT NULL,
-  slot_inherited   SMALLINT  NOT NULL  DEFAULT 0,
+  slot_origin      INTEGER   NOT NULL,
   PRIMARY KEY (slot_revision_id, slot_role_id)
 );
 
-CREATE INDEX slot_role_inherited ON slots (slot_revision_id, slot_role_id, slot_inherited);
+CREATE INDEX slot_revision_origin_role ON slots (slot_revision_id, slot_origin, slot_role_id);
 
 
 CREATE SEQUENCE content_content_id_seq;
index ecdec29..1f89426 100644 (file)
@@ -57,8 +57,6 @@ class RebuildFileCache extends Maintenance {
        }
 
        public function execute() {
-               global $wgRequestTime;
-
                if ( !$this->enabled ) {
                        $this->fatalError( "Nothing to do -- \$wgUseFileCache is disabled." );
                }
@@ -90,7 +88,8 @@ class RebuildFileCache extends Maintenance {
                        $this->fatalError( "Nothing to do." );
                }
 
-               $_SERVER['HTTP_ACCEPT_ENCODING'] = 'bgzip'; // hack, no real client
+               // Mock request (hack, no real client)
+               $_SERVER['HTTP_ACCEPT_ENCODING'] = 'bgzip';
 
                # Do remaining chunk
                $end += $batchSize - 1;
@@ -141,22 +140,27 @@ class RebuildFileCache extends Maintenance {
                                        }
 
                                        Wikimedia\suppressWarnings(); // header notices
-                                       // Cache ?action=view
-                                       $wgRequestTime = microtime( true ); # T24852
+
+                                       // 1. Cache ?action=view
+                                       // Be sure to reset the mocked request time (T24852)
+                                       $_SERVER['REQUEST_TIME_FLOAT'] = microtime( true );
                                        ob_start();
                                        $article->view();
                                        $context->getOutput()->output();
                                        $context->getOutput()->clearHTML();
                                        $viewHtml = ob_get_clean();
                                        $viewCache->saveToFileCache( $viewHtml );
-                                       // Cache ?action=history
-                                       $wgRequestTime = microtime( true ); # T24852
+
+                                       // 2. Cache ?action=history
+                                       // Be sure to reset the mocked request time (T24852)
+                                       $_SERVER['REQUEST_TIME_FLOAT'] = microtime( true );
                                        ob_start();
                                        Action::factory( 'history', $article, $context )->show();
                                        $context->getOutput()->output();
                                        $context->getOutput()->clearHTML();
                                        $historyHtml = ob_get_clean();
                                        $historyCache->saveToFileCache( $historyHtml );
+
                                        Wikimedia\restoreWarnings();
 
                                        if ( $rebuilt ) {
diff --git a/maintenance/sqlite/archives/patch-rev_text_id-default.sql b/maintenance/sqlite/archives/patch-rev_text_id-default.sql
new file mode 100644 (file)
index 0000000..c8e032b
--- /dev/null
@@ -0,0 +1,53 @@
+--
+-- Adds a default value to the rev_text_id field in the revision table.
+-- This is to allow the Multi Content Revisions migration to happen where
+-- rows will have to be added to the revision table with no rev_text_id.
+--
+-- 2018-03-12
+--
+
+BEGIN TRANSACTION;
+
+DROP TABLE IF EXISTS /*_*/revision_tmp;
+
+CREATE TABLE /*_*/revision_tmp (
+  rev_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  rev_page int unsigned NOT NULL,
+  rev_text_id int unsigned NOT NULL default 0,
+  rev_comment varbinary(767) NOT NULL default '',
+  rev_user int unsigned NOT NULL default 0,
+  rev_user_text varchar(255) binary NOT NULL default '',
+  rev_timestamp binary(14) NOT NULL default '',
+  rev_minor_edit tinyint unsigned NOT NULL default 0,
+  rev_deleted tinyint unsigned NOT NULL default 0,
+  rev_len int unsigned,
+  rev_parent_id int unsigned default NULL,
+  rev_sha1 varbinary(32) NOT NULL default '',
+  rev_content_model varbinary(32) DEFAULT NULL,
+  rev_content_format varbinary(64) DEFAULT NULL
+
+) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
+
+INSERT OR IGNORE INTO /*_*/revision_tmp (
+    rev_id, rev_page, rev_text_id, rev_comment, rev_user, rev_user_text,
+    rev_timestamp, rev_minor_edit, rev_deleted, rev_len, rev_parent_id,
+    rev_sha1, rev_content_model, rev_content_format
+    )
+    SELECT
+    rev_id, rev_page, rev_text_id, rev_comment, rev_user, rev_user_text,
+    rev_timestamp, rev_minor_edit, rev_deleted, rev_len, rev_parent_id,
+    rev_sha1, rev_content_model, rev_content_format
+    FROM /*_*/revision;
+
+DROP TABLE /*_*/revision;
+
+ALTER TABLE /*_*/revision_tmp RENAME TO /*_*/revision;
+
+CREATE INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id);
+CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp);
+CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp);
+CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp);
+CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp);
+CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp);
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-slot-origin.sql b/maintenance/sqlite/archives/patch-slot-origin.sql
new file mode 100644 (file)
index 0000000..f6d8ebf
--- /dev/null
@@ -0,0 +1,34 @@
+--
+-- Replace slot_inherited with slot_origin.
+--
+-- NOTE: There is no release that has slot_inherited. This is only needed to transition between
+-- snapshot versions of 1.30.
+--
+-- NOTE: No code that writes to the slots table was merge yet, the table is assumed to be empty.
+--
+BEGIN TRANSACTION;
+
+DROP TABLE /*_*/slots;
+
+CREATE TABLE /*_*/slots (
+
+  -- reference to rev_id
+  slot_revision_id bigint unsigned NOT NULL,
+
+  -- reference to role_id
+  slot_role_id smallint unsigned NOT NULL,
+
+  -- reference to content_id
+  slot_content_id bigint unsigned NOT NULL,
+
+  -- The revision ID of the revision that originated the slot's content.
+  -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
+  slot_origin bigint unsigned NOT NULL,
+
+  PRIMARY KEY ( slot_revision_id, slot_role_id )
+) /*$wgDBTableOptions*/;
+
+-- Index for finding revisions that modified a specific slot
+CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
+
+COMMIT TRANSACTION;
\ No newline at end of file
index 990ba3d..90c559a 100644 (file)
@@ -365,7 +365,7 @@ CREATE TABLE /*_*/revision (
   -- It's possible for multiple revisions to use the same text,
   -- for instance revisions where only metadata is altered
   -- or a rollback to a previous version.
-  rev_text_id int unsigned NOT NULL,
+  rev_text_id int unsigned NOT NULL default 0,
 
   -- Text comment summarizing the change. Deprecated in favor of
   -- revision_comment_temp.revcomment_comment_id.
@@ -676,14 +676,15 @@ CREATE TABLE /*_*/slots (
   -- reference to content_id
   slot_content_id bigint unsigned NOT NULL,
 
-  -- whether the content is inherited (1) or new in this revision (0)
-  slot_inherited tinyint unsigned NOT NULL DEFAULT 0,
+  -- The revision ID of the revision that originated the slot's content.
+  -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
+  slot_origin bigint unsigned NOT NULL,
 
   PRIMARY KEY ( slot_revision_id, slot_role_id )
 ) /*$wgDBTableOptions*/;
 
 -- Index for finding revisions that modified a specific slot
-CREATE INDEX /*i*/slot_role_inherited ON /*_*/slots (slot_revision_id, slot_role_id, slot_inherited);
+CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
 
 --
 -- The content table represents content objects. It's primary purpose is to provide the necessary
index 73ec1a7..257f153 100644 (file)
@@ -11,7 +11,7 @@
 
 #pagehistory li.selected {
        background-color: #f8f9fa;
-       color: #252525;
+       color: #222;
        border: 1px dashed #a2a9b1;
 }
 
index df5aa0f..64870fd 100644 (file)
@@ -166,7 +166,6 @@ ul {
        margin: 0 !important; /* stylelint-disable-line declaration-no-important */
 }
 
-#toc,
 .toc {
        background-color: #f9f9f9;
        border: 1pt solid #aaa;
index 7b2d711..2572b52 100644 (file)
@@ -166,7 +166,6 @@ img {
        border: 0;
 }
 
-#toc,
 .toc {
        border: 1px solid #bba;
        background-color: #f7f8ff;
@@ -182,18 +181,15 @@ img {
 }
 
 /* CSS for backwards-compatibility with cached page renders and creative uses in wikitext */
-table#toc,
 table.toc {
        border-collapse: collapse;
 }
 
 /* Remove additional paddings inside table-cells that are not present in <div>s */
-table#toc td,
 table.toc td {
        padding: 0;
 }
 
-#toc h2,
 .toc h2 {
        display: inline;
        border: 0;
@@ -202,7 +198,6 @@ table.toc td {
        font-weight: bold;
 }
 
-#toc ul,
 .toc ul {
        list-style-type: none;
        list-style-image: none;
@@ -210,7 +205,6 @@ table.toc td {
        text-align: left;
 }
 
-#toc ul ul,
 .toc ul ul {
        margin: 0 0 0 2em;
 }
@@ -274,7 +268,7 @@ table.small {
        font-size: 100%;
 }
 
-/* use this instead of #toc for page content */
+/* use this instead of .toc for page content */
 .toccolours {
        border: 1px solid #aaa;
        background-color: #f9f9f9;
index e46c758..0f84ff1 100644 (file)
@@ -625,43 +625,31 @@ ol:lang( or ) li {
        list-style-type: oriya;
 }
 
-#toc ul,
 .toc ul {
        margin: 0.3em 0;
 }
 
 /* Correct directionality when page dir is different from site/user dir */
 /* @noflip */ .mw-content-ltr .toc ul,
-.mw-content-ltr #toc ul,
-.mw-content-rtl .mw-content-ltr .toc ul,
-.mw-content-rtl .mw-content-ltr #toc ul {
+.mw-content-rtl .mw-content-ltr .toc ul {
        text-align: left;
 }
 
 /* @noflip */ .mw-content-rtl .toc ul,
-.mw-content-rtl #toc ul,
-.mw-content-ltr .mw-content-rtl .toc ul,
-.mw-content-ltr .mw-content-rtl #toc ul {
+.mw-content-ltr .mw-content-rtl .toc ul {
        text-align: right;
 }
 
 /* @noflip */ .mw-content-ltr .toc ul ul,
-.mw-content-ltr #toc ul ul,
-.mw-content-rtl .mw-content-ltr .toc ul ul,
-.mw-content-rtl .mw-content-ltr #toc ul ul {
+.mw-content-rtl .mw-content-ltr .toc ul ul {
        margin: 0 0 0 2em;
 }
 
 /* @noflip */ .mw-content-rtl .toc ul ul,
-.mw-content-rtl #toc ul ul,
-.mw-content-ltr .mw-content-rtl .toc ul ul,
-.mw-content-ltr .mw-content-rtl #toc ul ul {
+.mw-content-ltr .mw-content-rtl .toc ul ul {
        margin: 0 2em 0 0;
 }
 
-#toc #toctitle,
-.toc #toctitle,
-#toc .toctitle,
 .toc .toctitle {
        direction: ltr;
 }
index 1218644..c64c761 100644 (file)
@@ -21,7 +21,6 @@
 
 .vertical-gradient( @startColor: gray, @endColor: white, @startPos: 0, @endPos: 100% ) {
        background-color: @endColor;
-       background-image: -webkit-gradient( linear, left top, left bottom, color-stop( @startPos, @startColor ), color-stop( @endPos, @endColor ) ); // Safari 4+, Chrome 2+
        background-image: -webkit-linear-gradient( top, @startColor @startPos, @endColor @endPos ); // Safari 5.1+, Chrome 10+
        background-image: -moz-linear-gradient( top, @startColor @startPos, @endColor @endPos ); // Firefox 3.6+
        background-image: linear-gradient( @startColor @startPos, @endColor @endPos ); // Standard
index 5ded184..890856a 100644 (file)
@@ -6,7 +6,6 @@
  */
 
 /* Table of Contents */
-#toc,
 .toc,
 .mw-warning,
 .toccolours {
@@ -28,7 +27,6 @@
  * inline elements. In practice inline elements surrounding the TOC are uncommon enough that
  * this is an acceptable sacrifice.
  */
-#toc,
 .toc {
        display: inline-block;
        display: table;
 }
 
 /* CSS for backwards-compatibility with cached page renders and creative uses in wikitext */
-table#toc,
 table.toc {
        border-collapse: collapse;
 }
 
 /* Remove additional paddings inside table-cells that are not present in <div>s */
-table#toc td,
 table.toc td {
        padding: 0;
 }
 
-#toc h2,
 .toc h2 {
        display: inline;
        border: 0;
@@ -61,14 +56,10 @@ table.toc td {
        font-weight: bold;
 }
 
-#toc #toctitle,
-.toc #toctitle,
-#toc .toctitle,
 .toc .toctitle {
        text-align: center;
 }
 
-#toc ul,
 .toc ul {
        list-style-type: none;
        list-style-image: none;
@@ -77,7 +68,6 @@ table.toc td {
        text-align: left;
 }
 
-#toc ul ul,
 .toc ul ul {
        margin: 0 0 0 2em;
 }
index e2aeffd..f62cb97 100644 (file)
@@ -23,7 +23,7 @@ textarea {
 
 .editOptions {
        background-color: #eaecf0;
-       color: #252525;
+       color: #222;
        border: 1px solid #c8ccd1;
        border-top: 0;
        padding: 1em 1em 1.5em 1em;
index a2e071e..3fe276b 100644 (file)
                        }
 
                        /**
-                        * Converts a module map of the form { foo: [ 'bar', 'baz' ], bar: [ 'baz, 'quux' ] }
-                        * to a query string of the form foo.bar,baz|bar.baz,quux
+                        * Converts a module map of the form `{ foo: [ 'bar', 'baz' ], bar: [ 'baz, 'quux' ] }`
+                        * to a query string of the form `foo.bar,baz|bar.baz,quux`.
+                        *
+                        * See `ResourceLoader::makePackedModulesString()` in PHP, of which this is a port.
+                        * On the server, unpacking is done by `ResourceLoaderContext::expandModuleNames()`.
+                        *
+                        * Note: This is only half of the logic, the other half has to be in #batchRequest(),
+                        * because its implementation needs to keep track of potential string size in order
+                        * to decide when to split the requests due to url size.
                         *
                         * @private
                         * @param {Object} moduleMap Module map
-                        * @return {string} Module query string
+                        * @return {Object}
+                        * @return {string} return.str Module query string
+                        * @return {Array} return.list List of module names in matching order
                         */
                        function buildModulesString( moduleMap ) {
                                var p, prefix,
-                                       arr = [];
+                                       str = [],
+                                       list = [];
+
+                               function restore( suffix ) {
+                                       return p + suffix;
+                               }
 
                                for ( prefix in moduleMap ) {
                                        p = prefix === '' ? '' : prefix + '.';
-                                       arr.push( p + moduleMap[ prefix ].join( ',' ) );
+                                       str.push( p + moduleMap[ prefix ].join( ',' ) );
+                                       list.push.apply( list, moduleMap[ prefix ].map( restore ) );
                                }
-                               return arr.join( '|' );
-                       }
-
-                       /**
-                        * Make a network request to load modules from the server.
-                        *
-                        * @private
-                        * @param {Object} moduleMap Module map, see #buildModulesString
-                        * @param {Object} currReqBase Object with other parameters (other than 'modules') to use in the request
-                        * @param {string} sourceLoadScript URL of load.php
-                        */
-                       function doRequest( moduleMap, currReqBase, sourceLoadScript ) {
-                               // Optimisation: Inherit (Object.create), not copy ($.extend)
-                               var query = Object.create( currReqBase );
-                               query.modules = buildModulesString( moduleMap );
-                               query = sortQuery( query );
-                               addScript( sourceLoadScript + '?' + $.param( query ) );
+                               return {
+                                       str: str.join( '|' ),
+                                       list: list
+                               };
                        }
 
                        /**
                        function batchRequest( batch ) {
                                var reqBase, splits, maxQueryLength, b, bSource, bGroup, bSourceGroup,
                                        source, group, i, modules, sourceLoadScript,
-                                       currReqBase, currReqBaseLength, moduleMap, l,
+                                       currReqBase, currReqBaseLength, moduleMap, currReqModules, l,
                                        lastDotIndex, prefix, suffix, bytesAdded;
 
+                               /**
+                                * Start the currently drafted request to the server.
+                                *
+                                * @ignore
+                                */
+                               function doRequest() {
+                                       // Optimisation: Inherit (Object.create), not copy ($.extend)
+                                       var query = Object.create( currReqBase ),
+                                               packed = buildModulesString( moduleMap );
+                                       query.modules = packed.str;
+                                       // The packing logic can change the effective order, even if the input was
+                                       // sorted. As such, the call to getCombinedVersion() must use this
+                                       // effective order, instead of currReqModules, as otherwise the combined
+                                       // version will not match the hash expected by the server based on
+                                       // combining versions from the module query string in-order. (T188076)
+                                       query.version = getCombinedVersion( packed.list );
+                                       query = sortQuery( query );
+                                       addScript( sourceLoadScript + '?' + $.param( query ) );
+                               }
+
                                if ( !batch.length ) {
                                        return;
                                }
                                // misses for otherwise identical content.
                                batch.sort();
 
-                               // Build a list of query parameters common to all requests
+                               // Query parameters common to all requests
                                reqBase = {
                                        skin: mw.config.get( 'skin' ),
                                        lang: mw.config.get( 'wgUserLanguage' ),
                                                // modules for this group from this source.
                                                modules = splits[ source ][ group ];
 
+                                               // Query parameters common to requests for this module group
                                                // Optimisation: Inherit (Object.create), not copy ($.extend)
                                                currReqBase = Object.create( reqBase );
-                                               currReqBase.version = getCombinedVersion( modules );
-
-                                               // For user modules append a user name to the query string.
+                                               // User modules require a user name in the query string.
                                                if ( group === 'user' && mw.config.get( 'wgUserName' ) !== null ) {
                                                        currReqBase.user = mw.config.get( 'wgUserName' );
                                                }
-                                               currReqBaseLength = $.param( currReqBase ).length;
+
+                                               // In addition to currReqBase, doRequest() will also add 'modules' and 'version'.
+                                               // > '&modules='.length === 9
+                                               // > '&version=1234567'.length === 16
+                                               // > 9 + 16 = 25
+                                               currReqBaseLength = $.param( currReqBase ).length + 25;
+
                                                // We may need to split up the request to honor the query string length limit,
                                                // so build it piece by piece.
-                                               l = currReqBaseLength + 9; // '&modules='.length == 9
-
+                                               l = currReqBaseLength;
                                                moduleMap = {}; // { prefix: [ suffixes ] }
+                                               currReqModules = [];
 
                                                for ( i = 0; i < modules.length; i++ ) {
                                                        // Determine how many bytes this module would add to the query string
                                                        lastDotIndex = modules[ i ].lastIndexOf( '.' );
-
                                                        // If lastDotIndex is -1, substr() returns an empty string
                                                        prefix = modules[ i ].substr( 0, lastDotIndex );
                                                        suffix = modules[ i ].slice( lastDotIndex + 1 );
-
                                                        bytesAdded = hasOwn.call( moduleMap, prefix ) ?
                                                                suffix.length + 3 : // '%2C'.length == 3
                                                                modules[ i ].length + 3; // '%7C'.length == 3
 
-                                                       // If the url would become too long, create a new one,
-                                                       // but don't create empty requests
-                                                       if ( maxQueryLength > 0 && !$.isEmptyObject( moduleMap ) && l + bytesAdded > maxQueryLength ) {
-                                                               // This url would become too long, create a new one, and start the old one
-                                                               doRequest( moduleMap, currReqBase, sourceLoadScript );
+                                                       // If the url would become too long, create a new one, but don't create empty requests
+                                                       if ( maxQueryLength > 0 && currReqModules.length && l + bytesAdded > maxQueryLength ) {
+                                                               // Dispatch what we've got...
+                                                               doRequest();
+                                                               // .. and start again.
+                                                               l = currReqBaseLength;
                                                                moduleMap = {};
-                                                               l = currReqBaseLength + 9;
+                                                               currReqModules = [];
+
                                                                mw.track( 'resourceloader.splitRequest', { maxQueryLength: maxQueryLength } );
                                                        }
                                                        if ( !hasOwn.call( moduleMap, prefix ) ) {
                                                                moduleMap[ prefix ] = [];
                                                        }
-                                                       moduleMap[ prefix ].push( suffix );
                                                        l += bytesAdded;
+                                                       moduleMap[ prefix ].push( suffix );
+                                                       currReqModules.push( modules[ i ] );
                                                }
                                                // If there's anything left in moduleMap, request that too
-                                               if ( !$.isEmptyObject( moduleMap ) ) {
-                                                       doRequest( moduleMap, currReqBase, sourceLoadScript );
+                                               if ( currReqModules.length ) {
+                                                       doRequest();
                                                }
                                        }
                                }
index fb34a89..d7b3f35 100644 (file)
                 * Note: borrows from IP::isIPv4
                 *
                 * @param {string} address
-                * @param {boolean} allowBlock
+                * @param {boolean} [allowBlock=false]
                 * @return {boolean}
                 */
                isIPv4Address: function ( address, allowBlock ) {
                 * Note: borrows from IP::isIPv6
                 *
                 * @param {string} address
-                * @param {boolean} allowBlock
+                * @param {boolean} [allowBlock=false]
                 * @return {boolean}
                 */
                isIPv6Address: function ( address, allowBlock ) {
                 *
                 * @since 1.25
                 * @param {string} address String to check
-                * @param {boolean} allowBlock True if a block of IPs should be allowed
+                * @param {boolean} [allowBlock=false] If a block of IPs should be allowed
                 * @return {boolean}
                 */
                isIPAddress: function ( address, allowBlock ) {
index a777153..b994f8a 100644 (file)
@@ -77,6 +77,7 @@ $wgAutoloadClasses += [
        'ApiTestCase' => "$testDir/phpunit/includes/api/ApiTestCase.php",
        'ApiTestCaseUpload' => "$testDir/phpunit/includes/api/ApiTestCaseUpload.php",
        'ApiTestContext' => "$testDir/phpunit/includes/api/ApiTestContext.php",
+       'ApiUploadTestCase' => "$testDir/phpunit/includes/api/ApiUploadTestCase.php",
        'MockApi' => "$testDir/phpunit/includes/api/MockApi.php",
        'MockApiQueryBase' => "$testDir/phpunit/includes/api/MockApiQueryBase.php",
        'UserWrapper' => "$testDir/phpunit/includes/api/UserWrapper.php",
index a03f969..f0c815f 100644 (file)
@@ -636,7 +636,6 @@ class ParserTestRunner {
 
        /**
         * Remove last character if it is a newline
-        * @group utility
         * @param string $s
         * @return string
         */
index bcd196f..9b902ae 100644 (file)
@@ -9,7 +9,7 @@
                        "homepage": "https://www.mediawiki.org/wiki/Special:Version/Credits"
                }
        ],
-       "license": "GPL-2.0",
+       "license": "GPL-2.0-only",
        "support": {
                "issues": "https://bugzilla.wikimedia.org/",
                "irc": "irc://irc.freenode.net/mediawiki",
index cae6a47..5c030db 100644 (file)
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT",
-                "GPL-3.0"
+                "GPL-3.0-only"
             ],
             "authors": [
                 {
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "GPL-2.0+"
+                "GPL-2.0-or-later"
             ],
             "authors": [
                 {
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "GPL-2.0+",
+                "GPL-2.0-or-later",
                 "MIT"
             ],
             "description": "The primary aim is to allow users to select a language and configure its support in an easy way. Main features are language selection, input methods and web fonts.",
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "GPL-2.0"
+                "GPL-2.0-only"
             ],
             "authors": [
                 {
index ddac980..88a6bae 100644 (file)
@@ -30,7 +30,7 @@
         "notification-url": "https://packagist.org/downloads/",
         "license": [
             "MIT",
-            "GPL-3.0"
+            "GPL-3.0-only"
         ],
         "authors": [
             {
index 0634c2d..3a88676 100644 (file)
@@ -9,7 +9,7 @@
                        "homepage": "https://www.mediawiki.org/wiki/Special:Version/Credits"
                }
        ],
-       "license": "GPL-2.0",
+       "license": "GPL-2.0-only",
        "support": {
                "issues": "https://bugzilla.wikimedia.org/",
                "irc": "irc://irc.freenode.net/mediawiki",
index 807099f..675201e 100644 (file)
@@ -68,8 +68,8 @@ class MutableRevisionRecordTest extends MediaWikiTestCase {
 
        public function testSimpleSetGetSlot() {
                $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
-               $slot = new SlotRecord(
-                       (object)[ 'role_name' => 'main' ],
+               $slot = SlotRecord::newUnsaved(
+                       'main',
                        new WikitextContent( 'x' )
                );
                $record->setSlot( $slot );
index e81f0af..719a3bf 100644 (file)
@@ -167,8 +167,8 @@ class RevisionStoreDbTest extends MediaWikiTestCase {
                $this->assertEquals( $r1->getWikiId(), $r2->getWikiId() );
                $this->assertEquals( $r1->isMinor(), $r2->isMinor() );
                foreach ( $r1->getSlotRoles() as $role ) {
-                       $this->assertEquals( $r1->getSlot( $role ), $r2->getSlot( $role ) );
-                       $this->assertEquals( $r1->getContent( $role ), $r2->getContent( $role ) );
+                       $this->assertSlotRecordsEqual( $r1->getSlot( $role ), $r2->getSlot( $role ) );
+                       $this->assertTrue( $r1->getContent( $role )->equals( $r2->getContent( $role ) ) );
                }
                foreach ( [
                        RevisionRecord::DELETED_TEXT,
@@ -180,6 +180,29 @@ class RevisionStoreDbTest extends MediaWikiTestCase {
                }
        }
 
+       private function assertSlotRecordsEqual( SlotRecord $s1, SlotRecord $s2 ) {
+               $this->assertSame( $s1->getRole(), $s2->getRole() );
+               $this->assertSame( $s1->getModel(), $s2->getModel() );
+               $this->assertSame( $s1->getFormat(), $s2->getFormat() );
+               $this->assertSame( $s1->getSha1(), $s2->getSha1() );
+               $this->assertSame( $s1->getSize(), $s2->getSize() );
+               $this->assertTrue( $s1->getContent()->equals( $s2->getContent() ) );
+
+               $s1->hasRevision() ? $this->assertSame( $s1->getRevision(), $s2->getRevision() ) : null;
+               $s1->hasAddress() ? $this->assertSame( $s1->hasAddress(), $s2->hasAddress() ) : null;
+       }
+
+       private function assertRevisionCompleteness( RevisionRecord $r ) {
+               foreach ( $r->getSlotRoles() as $role ) {
+                       $this->assertSlotCompleteness( $r, $r->getSlot( $role ) );
+               }
+       }
+
+       private function assertSlotCompleteness( RevisionRecord $r, SlotRecord $slot ) {
+               $this->assertTrue( $slot->hasAddress() );
+               $this->assertSame( $r->getId(), $slot->getRevision() );
+       }
+
        /**
         * @param mixed[] $details
         *
@@ -257,6 +280,7 @@ class RevisionStoreDbTest extends MediaWikiTestCase {
 
                $this->assertLinkTargetsEqual( $title, $return->getPageAsLinkTarget() );
                $this->assertRevisionRecordsEqual( $rev, $return );
+               $this->assertRevisionCompleteness( $return );
        }
 
        /**
@@ -388,6 +412,8 @@ class RevisionStoreDbTest extends MediaWikiTestCase {
        public function testNewNullRevision( Title $title, $comment, $minor ) {
                $store = MediaWikiServices::getInstance()->getRevisionStore();
                $user = TestUserRegistry::getMutableTestUser( __METHOD__ )->getUser();
+
+               $parent = $store->getRevisionByTitle( $title );
                $record = $store->newNullRevision(
                        wfGetDB( DB_MASTER ),
                        $title,
@@ -401,6 +427,14 @@ class RevisionStoreDbTest extends MediaWikiTestCase {
                $this->assertEquals( $comment, $record->getComment() );
                $this->assertEquals( $minor, $record->isMinor() );
                $this->assertEquals( $user->getName(), $record->getUser()->getName() );
+               $this->assertEquals( $parent->getId(), $record->getParentId() );
+
+               $parentSlot = $parent->getSlot( 'main' );
+               $slot = $record->getSlot( 'main' );
+
+               $this->assertTrue( $slot->isInherited(), 'isInherited' );
+               $this->assertSame( $parentSlot->getOrigin(), $slot->getOrigin(), 'getOrigin' );
+               $this->assertSame( $parentSlot->getAddress(), $slot->getAddress(), 'getAddress' );
        }
 
        /**
index 27fcd0c..8f26494 100644 (file)
@@ -2,10 +2,12 @@
 
 namespace MediaWiki\Tests\Storage;
 
+use InvalidArgumentException;
+use LogicException;
+use MediaWiki\Storage\IncompleteRevisionException;
 use MediaWiki\Storage\SlotRecord;
+use MediaWiki\Storage\SuppressedDataException;
 use MediaWikiTestCase;
-use RuntimeException;
-use Wikimedia\Assert\ParameterTypeException;
 use WikitextContent;
 
 /**
@@ -13,52 +15,91 @@ use WikitextContent;
  */
 class SlotRecordTest extends MediaWikiTestCase {
 
-       public function provideAContent() {
-               yield [ new WikitextContent( 'A' ) ];
-               yield [
-                       function ( SlotRecord $slotRecord ) {
-                               if ( $slotRecord->getAddress() === 'tt:456' ) {
-                                       return new WikitextContent( 'A' );
-                               }
-                               throw new RuntimeException( 'Got Wrong SlotRecord for callback' );
-                       },
-               ];
-       }
-
-       /**
-        * @dataProvider provideAContent
-        */
-       public function testValidConstruction( $content ) {
-               $row = (object)[
-                       'cont_size' => '1',
-                       'cont_sha1' => 'someHash',
-                       'cont_address' => 'tt:456',
-                       'model_name' => 'aModelname',
-                       'slot_revision' => '2',
-                       'format_name' => 'someFormatName',
+       private function makeRow( $data = [] ) {
+               $data = $data + [
+                       'slot_id' => 1234,
+                       'slot_content_id' => 33,
+                       'content_size' => '5',
+                       'content_sha1' => 'someHash',
+                       'content_address' => 'tt:456',
+                       'model_name' => CONTENT_MODEL_WIKITEXT,
+                       'format_name' => CONTENT_FORMAT_WIKITEXT,
+                       'slot_revision_id' => '2',
+                       'slot_origin' => '1',
                        'role_name' => 'myRole',
-                       'slot_inherited' => '99'
                ];
+               return (object)$data;
+       }
 
-               $record = new SlotRecord( $row, $content );
+       public function testCompleteConstruction() {
+               $row = $this->makeRow();
+               $record = new SlotRecord( $row, new WikitextContent( 'A' ) );
 
+               $this->assertTrue( $record->hasAddress() );
+               $this->assertTrue( $record->hasRevision() );
+               $this->assertTrue( $record->isInherited() );
                $this->assertSame( 'A', $record->getContent()->getNativeData() );
-               $this->assertSame( 1, $record->getSize() );
+               $this->assertSame( 5, $record->getSize() );
                $this->assertSame( 'someHash', $record->getSha1() );
-               $this->assertSame( 'aModelname', $record->getModel() );
+               $this->assertSame( CONTENT_MODEL_WIKITEXT, $record->getModel() );
                $this->assertSame( 2, $record->getRevision() );
+               $this->assertSame( 1, $record->getOrigin() );
                $this->assertSame( 'tt:456', $record->getAddress() );
-               $this->assertSame( 'someFormatName', $record->getFormat() );
+               $this->assertSame( 33, $record->getContentId() );
+               $this->assertSame( CONTENT_FORMAT_WIKITEXT, $record->getFormat() );
                $this->assertSame( 'myRole', $record->getRole() );
+       }
+
+       public function testConstructionDeferred() {
+               $row = $this->makeRow( [
+                       'content_size' => null, // to be computed
+                       'content_sha1' => null, // to be computed
+                       'format_name' => function () {
+                               return CONTENT_FORMAT_WIKITEXT;
+                       },
+                       'slot_revision_id' => '2',
+                       'slot_origin' => '2',
+               ] );
+
+               $content = function () {
+                       return new WikitextContent( 'A' );
+               };
+
+               $record = new SlotRecord( $row, $content );
+
                $this->assertTrue( $record->hasAddress() );
                $this->assertTrue( $record->hasRevision() );
-               $this->assertTrue( $record->isInherited() );
+               $this->assertFalse( $record->isInherited() );
+               $this->assertSame( 'A', $record->getContent()->getNativeData() );
+               $this->assertSame( 1, $record->getSize() );
+               $this->assertNotNull( $record->getSha1() );
+               $this->assertSame( CONTENT_MODEL_WIKITEXT, $record->getModel() );
+               $this->assertSame( 2, $record->getRevision() );
+               $this->assertSame( 2, $record->getRevision() );
+               $this->assertSame( 'tt:456', $record->getAddress() );
+               $this->assertSame( 33, $record->getContentId() );
+               $this->assertSame( CONTENT_FORMAT_WIKITEXT, $record->getFormat() );
+               $this->assertSame( 'myRole', $record->getRole() );
+       }
+
+       public function testNewUnsaved() {
+               $record = SlotRecord::newUnsaved( 'myRole', new WikitextContent( 'A' ) );
+
+               $this->assertFalse( $record->hasAddress() );
+               $this->assertFalse( $record->hasRevision() );
+               $this->assertFalse( $record->isInherited() );
+               $this->assertSame( 'A', $record->getContent()->getNativeData() );
+               $this->assertSame( 1, $record->getSize() );
+               $this->assertNotNull( $record->getSha1() );
+               $this->assertSame( CONTENT_MODEL_WIKITEXT, $record->getModel() );
+               $this->assertSame( 'myRole', $record->getRole() );
        }
 
        public function provideInvalidConstruction() {
                yield 'both null' => [ null, null ];
                yield 'null row' => [ null, new WikitextContent( 'A' ) ];
-               yield 'array row' => [ null, new WikitextContent( 'A' ) ];
+               yield 'array row' => [ [], new WikitextContent( 'A' ) ];
+               yield 'empty row' => [ (object)[], new WikitextContent( 'A' ) ];
                yield 'null content' => [ (object)[], null ];
        }
 
@@ -66,25 +107,192 @@ class SlotRecordTest extends MediaWikiTestCase {
         * @dataProvider provideInvalidConstruction
         */
        public function testInvalidConstruction( $row, $content ) {
-               $this->setExpectedException( ParameterTypeException::class );
+               $this->setExpectedException( InvalidArgumentException::class );
                new SlotRecord( $row, $content );
        }
 
-       public function testHasAddress_false() {
-               $record = new SlotRecord( (object)[], new WikitextContent( 'A' ) );
-               $this->assertFalse( $record->hasAddress() );
+       public function testGetContentId_fails() {
+               $record = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
+               $this->setExpectedException( IncompleteRevisionException::class );
+
+               $record->getContentId();
        }
 
-       public function testHasRevision_false() {
-               $record = new SlotRecord( (object)[], new WikitextContent( 'A' ) );
-               $this->assertFalse( $record->hasRevision() );
+       public function testGetAddress_fails() {
+               $record = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
+               $this->setExpectedException( IncompleteRevisionException::class );
+
+               $record->getAddress();
        }
 
-       public function testInInherited_false() {
-               // TODO unskip me once fixed.
-               $this->markTestSkipped( 'Should probably return false, needs fixing?' );
-               $record = new SlotRecord( (object)[], new WikitextContent( 'A' ) );
-               $this->assertFalse( $record->isInherited() );
+       public function provideIncomplete() {
+               $unsaved = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
+               yield 'unsaved' => [ $unsaved ];
+
+               $parent = new SlotRecord( $this->makeRow(), new WikitextContent( 'A' ) );
+               $inherited = SlotRecord::newInherited( $parent );
+               yield 'inherited' => [ $inherited ];
+       }
+
+       /**
+        * @dataProvider provideIncomplete
+        */
+       public function testGetRevision_fails( SlotRecord $record ) {
+               $record = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
+               $this->setExpectedException( IncompleteRevisionException::class );
+
+               $record->getRevision();
+       }
+
+       /**
+        * @dataProvider provideIncomplete
+        */
+       public function testGetOrigin_fails( SlotRecord $record ) {
+               $record = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
+               $this->setExpectedException( IncompleteRevisionException::class );
+
+               $record->getOrigin();
+       }
+
+       public function provideHashStability() {
+               yield [ '', 'phoiac9h4m842xq45sp7s6u21eteeq1' ];
+               yield [ 'Lorem ipsum', 'hcr5u40uxr81d3nx89nvwzclfz6r9c5' ];
+       }
+
+       /**
+        * @dataProvider provideHashStability
+        */
+       public function testHashStability( $text, $hash ) {
+               // Changing the output of the hash function will break things horribly!
+
+               $this->assertSame( $hash, SlotRecord::base36Sha1( $text ) );
+
+               $record = SlotRecord::newUnsaved( 'main', new WikitextContent( $text ) );
+               $this->assertSame( $hash, $record->getSha1() );
+       }
+
+       public function testNewWithSuppressedContent() {
+               $input = new SlotRecord( $this->makeRow(), new WikitextContent( 'A' ) );
+               $output = SlotRecord::newWithSuppressedContent( $input );
+
+               $this->setExpectedException( SuppressedDataException::class );
+               $output->getContent();
+       }
+
+       public function testNewInherited() {
+               $row = $this->makeRow( [ 'slot_revision_id' => 7, 'slot_origin' => 7 ] );
+               $parent = new SlotRecord( $row, new WikitextContent( 'A' ) );
+
+               // This would happen while doing an edit, before saving revision meta-data.
+               $inherited = SlotRecord::newInherited( $parent );
+
+               $this->assertSame( $parent->getContentId(), $inherited->getContentId() );
+               $this->assertSame( $parent->getAddress(), $inherited->getAddress() );
+               $this->assertSame( $parent->getContent(), $inherited->getContent() );
+               $this->assertTrue( $inherited->isInherited() );
+               $this->assertFalse( $inherited->hasRevision() );
+
+               // make sure we didn't mess with the internal state of $parent
+               $this->assertFalse( $parent->isInherited() );
+               $this->assertSame( 7, $parent->getRevision() );
+
+               // This would happen while doing an edit, after saving the revision meta-data
+               // and content meta-data.
+               $saved = SlotRecord::newSaved(
+                       10,
+                       $inherited->getContentId(),
+                       $inherited->getAddress(),
+                       $inherited
+               );
+               $this->assertSame( $parent->getContentId(), $saved->getContentId() );
+               $this->assertSame( $parent->getAddress(), $saved->getAddress() );
+               $this->assertSame( $parent->getContent(), $saved->getContent() );
+               $this->assertTrue( $saved->isInherited() );
+               $this->assertTrue( $saved->hasRevision() );
+               $this->assertSame( 10, $saved->getRevision() );
+
+               // make sure we didn't mess with the internal state of $parent or $inherited
+               $this->assertSame( 7, $parent->getRevision() );
+               $this->assertFalse( $inherited->hasRevision() );
+       }
+
+       public function testNewSaved() {
+               // This would happen while doing an edit, before saving revision meta-data.
+               $unsaved = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
+
+               // This would happen while doing an edit, after saving the revision meta-data
+               // and content meta-data.
+               $saved = SlotRecord::newSaved( 10, 20, 'theNewAddress', $unsaved );
+               $this->assertFalse( $saved->isInherited() );
+               $this->assertTrue( $saved->hasRevision() );
+               $this->assertTrue( $saved->hasAddress() );
+               $this->assertSame( 'theNewAddress', $saved->getAddress() );
+               $this->assertSame( 20, $saved->getContentId() );
+               $this->assertSame( 'A', $saved->getContent()->getNativeData() );
+               $this->assertSame( 10, $saved->getRevision() );
+               $this->assertSame( 10, $saved->getOrigin() );
+
+               // make sure we didn't mess with the internal state of $unsaved
+               $this->assertFalse( $unsaved->hasAddress() );
+               $this->assertFalse( $unsaved->hasRevision() );
+       }
+
+       public function provideNewSaved_LogicException() {
+               $freshRow = $this->makeRow( [
+                       'content_id' => 10,
+                       'content_address' => 'address:1',
+                       'slot_origin' => 1,
+                       'slot_revision_id' => 1,
+               ] );
+
+               $freshSlot = new SlotRecord( $freshRow, new WikitextContent( 'A' ) );
+               yield 'mismatching address' => [ 1, 10, 'address:BAD', $freshSlot ];
+               yield 'mismatching revision' => [ 5, 10, 'address:1', $freshSlot ];
+               yield 'mismatching content ID' => [ 1, 17, 'address:1', $freshSlot ];
+
+               $inheritedRow = $this->makeRow( [
+                       'content_id' => null,
+                       'content_address' => null,
+                       'slot_origin' => 0,
+                       'slot_revision_id' => 1,
+               ] );
+
+               $inheritedSlot = new SlotRecord( $inheritedRow, new WikitextContent( 'A' ) );
+               yield 'inherited, but no address' => [ 1, 10, 'address:2', $inheritedSlot ];
+       }
+
+       /**
+        * @dataProvider provideNewSaved_LogicException
+        */
+       public function testNewSaved_LogicException(
+               $revisionId,
+               $contentId,
+               $contentAddress,
+               SlotRecord $protoSlot
+       ) {
+               $this->setExpectedException( LogicException::class );
+               SlotRecord::newSaved( $revisionId, $contentId, $contentAddress, $protoSlot );
+       }
+
+       public function provideNewSaved_InvalidArgumentException() {
+               $unsaved = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
+
+               yield 'bad revision id' => [ 'xyzzy', 5, 'address', $unsaved ];
+               yield 'bad content id' => [ 7, 'xyzzy', 'address', $unsaved ];
+               yield 'bad content address' => [ 7, 5, 77, $unsaved ];
+       }
+
+       /**
+        * @dataProvider provideNewSaved_InvalidArgumentException
+        */
+       public function testNewSaved_InvalidArgumentException(
+               $revisionId,
+               $contentId,
+               $contentAddress,
+               SlotRecord $protoSlot
+       ) {
+               $this->setExpectedException( InvalidArgumentException::class );
+               SlotRecord::newSaved( $revisionId, $contentId, $contentAddress, $protoSlot );
        }
 
 }
index 936f4f5..9583921 100644 (file)
@@ -26,7 +26,7 @@ class WebRequestTest extends MediaWikiTestCase {
        public function testDetectServer( $expected, $input, $description ) {
                $this->setMwGlobals( 'wgAssumeProxiesUseDefaultProtocolPorts', true );
 
-               $_SERVER = $input;
+               $this->setServerVars( $input );
                $result = WebRequest::detectServer();
                $this->assertEquals( $expected, $result, $description );
        }
@@ -363,7 +363,7 @@ class WebRequestTest extends MediaWikiTestCase {
         * @covers WebRequest::getIP
         */
        public function testGetIP( $expected, $input, $squid, $xffList, $private, $description ) {
-               $_SERVER = $input;
+               $this->setServerVars( $input );
                $this->setMwGlobals( [
                        'wgUsePrivateIPs' => $private,
                        'wgHooks' => [
@@ -608,8 +608,19 @@ class WebRequestTest extends MediaWikiTestCase {
         * @covers WebRequest::getAcceptLang
         */
        public function testAcceptLang( $acceptLanguageHeader, $expectedLanguages, $description ) {
-               $_SERVER = [ 'HTTP_ACCEPT_LANGUAGE' => $acceptLanguageHeader ];
+               $this->setServerVars( [ 'HTTP_ACCEPT_LANGUAGE' => $acceptLanguageHeader ] );
                $request = new WebRequest();
                $this->assertSame( $request->getAcceptLang(), $expectedLanguages, $description );
        }
+
+       protected function setServerVars( $vars ) {
+               // Don't remove vars which should be available in all SAPI.
+               if ( !isset( $vars['REQUEST_TIME_FLOAT'] ) ) {
+                       $vars['REQUEST_TIME_FLOAT'] = $_SERVER['REQUEST_TIME_FLOAT'];
+               }
+               if ( !isset( $vars['REQUEST_TIME'] ) ) {
+                       $vars['REQUEST_TIME'] = $_SERVER['REQUEST_TIME'];
+               }
+               $_SERVER = $vars;
+       }
 }
index f15da2e..3670fad 100644 (file)
@@ -1,153 +1,8 @@
 <?php
 
 /**
- * Abstract class to support upload tests
+ * For backward compatibility since 1.31
  */
-abstract class ApiTestCaseUpload extends ApiTestCase {
-       /**
-        * Fixture -- run before every test
-        */
-       protected function setUp() {
-               parent::setUp();
+abstract class ApiTestCaseUpload extends ApiUploadTestCase {
 
-               $this->setMwGlobals( [
-                       'wgEnableUploads' => true,
-                       'wgEnableAPI' => true,
-               ] );
-
-               $this->clearFakeUploads();
-       }
-
-       /**
-        * Helper function -- remove files and associated articles by Title
-        *
-        * @param Title $title Title to be removed
-        *
-        * @return bool
-        */
-       public function deleteFileByTitle( $title ) {
-               if ( $title->exists() ) {
-                       $file = wfFindFile( $title, [ 'ignoreRedirect' => true ] );
-                       $noOldArchive = ""; // yes this really needs to be set this way
-                       $comment = "removing for test";
-                       $restrictDeletedVersions = false;
-                       $status = FileDeleteForm::doDelete(
-                               $title,
-                               $file,
-                               $noOldArchive,
-                               $comment,
-                               $restrictDeletedVersions
-                       );
-
-                       if ( !$status->isGood() ) {
-                               return false;
-                       }
-
-                       $page = WikiPage::factory( $title );
-                       $page->doDeleteArticle( "removing for test" );
-
-                       // see if it now doesn't exist; reload
-                       $title = Title::newFromText( $title->getText(), NS_FILE );
-               }
-
-               return !( $title && $title instanceof Title && $title->exists() );
-       }
-
-       /**
-        * Helper function -- remove files and associated articles with a particular filename
-        *
-        * @param string $fileName Filename to be removed
-        *
-        * @return bool
-        */
-       public function deleteFileByFileName( $fileName ) {
-               return $this->deleteFileByTitle( Title::newFromText( $fileName, NS_FILE ) );
-       }
-
-       /**
-        * Helper function -- given a file on the filesystem, find matching
-        * content in the db (and associated articles) and remove them.
-        *
-        * @param string $filePath Path to file on the filesystem
-        *
-        * @return bool
-        */
-       public function deleteFileByContent( $filePath ) {
-               $hash = FSFile::getSha1Base36FromPath( $filePath );
-               $dupes = RepoGroup::singleton()->findBySha1( $hash );
-               $success = true;
-               foreach ( $dupes as $dupe ) {
-                       $success &= $this->deleteFileByTitle( $dupe->getTitle() );
-               }
-
-               return $success;
-       }
-
-       /**
-        * Fake an upload by dumping the file into temp space, and adding info to $_FILES.
-        * (This is what PHP would normally do).
-        *
-        * @param string $fieldName Name this would have in the upload form
-        * @param string $fileName Name to title this
-        * @param string $type MIME type
-        * @param string $filePath Path where to find file contents
-        *
-        * @throws Exception
-        * @return bool
-        */
-       function fakeUploadFile( $fieldName, $fileName, $type, $filePath ) {
-               $tmpName = $this->getNewTempFile();
-               if ( !file_exists( $filePath ) ) {
-                       throw new Exception( "$filePath doesn't exist!" );
-               }
-
-               if ( !copy( $filePath, $tmpName ) ) {
-                       throw new Exception( "couldn't copy $filePath to $tmpName" );
-               }
-
-               clearstatcache();
-               $size = filesize( $tmpName );
-               if ( $size === false ) {
-                       throw new Exception( "couldn't stat $tmpName" );
-               }
-
-               $_FILES[$fieldName] = [
-                       'name' => $fileName,
-                       'type' => $type,
-                       'tmp_name' => $tmpName,
-                       'size' => $size,
-                       'error' => null
-               ];
-
-               return true;
-       }
-
-       function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ) {
-               $tmpName = $this->getNewTempFile();
-               // copy the chunk data to temp location:
-               if ( !file_put_contents( $tmpName, $chunkData ) ) {
-                       throw new Exception( "couldn't copy chunk data to $tmpName" );
-               }
-
-               clearstatcache();
-               $size = filesize( $tmpName );
-               if ( $size === false ) {
-                       throw new Exception( "couldn't stat $tmpName" );
-               }
-
-               $_FILES[$fieldName] = [
-                       'name' => $fileName,
-                       'type' => $type,
-                       'tmp_name' => $tmpName,
-                       'size' => $size,
-                       'error' => null
-               ];
-       }
-
-       /**
-        * Remove traces of previous fake uploads
-        */
-       function clearFakeUploads() {
-               $_FILES = [];
-       }
 }
index 345f196..41c9aed 100644 (file)
@@ -22,7 +22,7 @@
  *
  * @covers ApiUpload
  */
-class ApiUploadTest extends ApiTestCaseUpload {
+class ApiUploadTest extends ApiUploadTestCase {
        /**
         * Testing login
         * XXX this is a funny way of getting session context
diff --git a/tests/phpunit/includes/api/ApiUploadTestCase.php b/tests/phpunit/includes/api/ApiUploadTestCase.php
new file mode 100644 (file)
index 0000000..3c7efd5
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+
+/**
+ * Abstract class to support upload tests
+ */
+abstract class ApiUploadTestCase extends ApiTestCase {
+       /**
+        * Fixture -- run before every test
+        */
+       protected function setUp() {
+               parent::setUp();
+
+               $this->setMwGlobals( [
+                       'wgEnableUploads' => true,
+                       'wgEnableAPI' => true,
+               ] );
+
+               $this->clearFakeUploads();
+       }
+
+       /**
+        * Helper function -- remove files and associated articles by Title
+        *
+        * @param Title $title Title to be removed
+        *
+        * @return bool
+        */
+       public function deleteFileByTitle( $title ) {
+               if ( $title->exists() ) {
+                       $file = wfFindFile( $title, [ 'ignoreRedirect' => true ] );
+                       $noOldArchive = ""; // yes this really needs to be set this way
+                       $comment = "removing for test";
+                       $restrictDeletedVersions = false;
+                       $status = FileDeleteForm::doDelete(
+                               $title,
+                               $file,
+                               $noOldArchive,
+                               $comment,
+                               $restrictDeletedVersions
+                       );
+
+                       if ( !$status->isGood() ) {
+                               return false;
+                       }
+
+                       $page = WikiPage::factory( $title );
+                       $page->doDeleteArticle( "removing for test" );
+
+                       // see if it now doesn't exist; reload
+                       $title = Title::newFromText( $title->getText(), NS_FILE );
+               }
+
+               return !( $title && $title instanceof Title && $title->exists() );
+       }
+
+       /**
+        * Helper function -- remove files and associated articles with a particular filename
+        *
+        * @param string $fileName Filename to be removed
+        *
+        * @return bool
+        */
+       public function deleteFileByFileName( $fileName ) {
+               return $this->deleteFileByTitle( Title::newFromText( $fileName, NS_FILE ) );
+       }
+
+       /**
+        * Helper function -- given a file on the filesystem, find matching
+        * content in the db (and associated articles) and remove them.
+        *
+        * @param string $filePath Path to file on the filesystem
+        *
+        * @return bool
+        */
+       public function deleteFileByContent( $filePath ) {
+               $hash = FSFile::getSha1Base36FromPath( $filePath );
+               $dupes = RepoGroup::singleton()->findBySha1( $hash );
+               $success = true;
+               foreach ( $dupes as $dupe ) {
+                       $success &= $this->deleteFileByTitle( $dupe->getTitle() );
+               }
+
+               return $success;
+       }
+
+       /**
+        * Fake an upload by dumping the file into temp space, and adding info to $_FILES.
+        * (This is what PHP would normally do).
+        *
+        * @param string $fieldName Name this would have in the upload form
+        * @param string $fileName Name to title this
+        * @param string $type MIME type
+        * @param string $filePath Path where to find file contents
+        *
+        * @throws Exception
+        * @return bool
+        */
+       function fakeUploadFile( $fieldName, $fileName, $type, $filePath ) {
+               $tmpName = $this->getNewTempFile();
+               if ( !file_exists( $filePath ) ) {
+                       throw new Exception( "$filePath doesn't exist!" );
+               }
+
+               if ( !copy( $filePath, $tmpName ) ) {
+                       throw new Exception( "couldn't copy $filePath to $tmpName" );
+               }
+
+               clearstatcache();
+               $size = filesize( $tmpName );
+               if ( $size === false ) {
+                       throw new Exception( "couldn't stat $tmpName" );
+               }
+
+               $_FILES[$fieldName] = [
+                       'name' => $fileName,
+                       'type' => $type,
+                       'tmp_name' => $tmpName,
+                       'size' => $size,
+                       'error' => null
+               ];
+
+               return true;
+       }
+
+       function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ) {
+               $tmpName = $this->getNewTempFile();
+               // copy the chunk data to temp location:
+               if ( !file_put_contents( $tmpName, $chunkData ) ) {
+                       throw new Exception( "couldn't copy chunk data to $tmpName" );
+               }
+
+               clearstatcache();
+               $size = filesize( $tmpName );
+               if ( $size === false ) {
+                       throw new Exception( "couldn't stat $tmpName" );
+               }
+
+               $_FILES[$fieldName] = [
+                       'name' => $fileName,
+                       'type' => $type,
+                       'tmp_name' => $tmpName,
+                       'size' => $size,
+                       'error' => null
+               ];
+       }
+
+       /**
+        * Remove traces of previous fake uploads
+        */
+       function clearFakeUploads() {
+               $_FILES = [];
+       }
+}
index 2355f76..b627178 100644 (file)
@@ -179,8 +179,6 @@ class ChangesListStringOptionsFilterGroupTest extends MediaWikiTestCase {
        /**
         * @param array $groupDefinition Group definition
         * @param string $input Value in URL
-        *
-        * @dataProvider provideModifyQuery
         */
        protected function modifyQueryHelper( $groupDefinition, $input ) {
                $ctx = $this->createMock( IContextSource::class );
index a7cf755..3be2b06 100644 (file)
@@ -173,8 +173,6 @@ abstract class GenericArrayObjectTest extends PHPUnit\Framework\TestCase {
         * @since 1.20
         *
         * @param callable $function
-        *
-        * @covers GenericArrayObject::getObjectType
         */
        protected function checkTypeChecks( $function ) {
                $excption = null;
@@ -206,7 +204,7 @@ abstract class GenericArrayObjectTest extends PHPUnit\Framework\TestCase {
         * @since 1.20
         *
         * @param array $elements
-        *
+        * @covers GenericArrayObject::getObjectType
         * @covers GenericArrayObject::offsetSet
         */
        public function testOffsetSet( array $elements ) {
index 6a75181..9702c82 100644 (file)
@@ -16,7 +16,7 @@ class IPTest extends PHPUnit\Framework\TestCase {
         * @covers IP::isIPAddress
         * @dataProvider provideInvalidIPs
         */
-       public function isNotIPAddress( $val, $desc ) {
+       public function testIsNotIPAddress( $val, $desc ) {
                $this->assertFalse( IP::isIPAddress( $val ), $desc );
        }
 
index 23225b6..05ae2a3 100644 (file)
@@ -20,7 +20,7 @@ class ComposerInstalledTest extends MediaWikiTestCase {
                'leafo/lessphp' => [
                        'version' => '0.5.0',
                        'type' => 'library',
-                       'licenses' => [ 'MIT', 'GPL-3.0' ],
+                       'licenses' => [ 'MIT', 'GPL-3.0-only' ],
                        'authors' => [
                                [
                                        'name' => 'Leaf Corcoran',
index eef7e27..dc81e1d 100644 (file)
@@ -20,7 +20,7 @@ class ComposerLockTest extends MediaWikiTestCase {
                        'wikimedia/cdb' => [
                                'version' => '1.0.1',
                                'type' => 'library',
-                               'licenses' => [ 'GPL-2.0' ],
+                               'licenses' => [ 'GPL-2.0-only' ],
                                'authors' => [
                                        [
                                                'name' => 'Tim Starling',
@@ -44,7 +44,7 @@ class ComposerLockTest extends MediaWikiTestCase {
                        'leafo/lessphp' => [
                                'version' => '0.5.0',
                                'type' => 'library',
-                               'licenses' => [ 'MIT', 'GPL-3.0' ],
+                               'licenses' => [ 'MIT', 'GPL-3.0-only' ],
                                'authors' => [
                                        [
                                                'name' => 'Leaf Corcoran',
@@ -89,7 +89,7 @@ class ComposerLockTest extends MediaWikiTestCase {
                        'mediawiki/translate' => [
                                'version' => '2014.12',
                                'type' => 'mediawiki-extension',
-                               'licenses' => [ 'GPL-2.0+' ],
+                               'licenses' => [ 'GPL-2.0-or-later' ],
                                'authors' => [
                                        [
                                                'name' => 'Niklas Laxström',
@@ -109,7 +109,7 @@ class ComposerLockTest extends MediaWikiTestCase {
                        'mediawiki/universal-language-selector' => [
                                'version' => '2014.12',
                                'type' => 'mediawiki-extension',
-                               'licenses' => [ 'GPL-2.0+', 'MIT' ],
+                               'licenses' => [ 'GPL-2.0-or-later', 'MIT' ],
                                'authors' => [],
                                'description' => 'The primary aim is to allow users to select a language ' .
                                        'and configure its support in an easy way. ' .
index bf3689b..1eca89b 100644 (file)
@@ -517,4 +517,69 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
                $this->assertSame( 'CAST( fieldName AS SIGNED )', $output );
        }
 
+       /*
+        * @covers Wikimedia\Rdbms\Database::setIndexAliases
+        */
+       public function testIndexAliases() {
+               $db = $this->getMockBuilder( DatabaseMysqli::class )
+                       ->disableOriginalConstructor()
+                       ->setMethods( [ 'mysqlRealEscapeString' ] )
+                       ->getMock();
+               $db->method( 'mysqlRealEscapeString' )->willReturnCallback(
+                       function ( $s ) {
+                               return str_replace( "'", "\\'", $s );
+                       }
+               );
+
+               $db->setIndexAliases( [ 'a_b_idx' => 'a_c_idx' ] );
+               $sql = $db->selectSQLText(
+                       'zend', 'field', [ 'a' => 'x' ], __METHOD__, [ 'USE INDEX' => 'a_b_idx' ] );
+
+               $this->assertEquals(
+                       "SELECT  field  FROM `zend`  FORCE INDEX (a_c_idx)  WHERE a = 'x'  ",
+                       $sql
+               );
+
+               $db->setIndexAliases( [] );
+               $sql = $db->selectSQLText(
+                       'zend', 'field', [ 'a' => 'x' ], __METHOD__, [ 'USE INDEX' => 'a_b_idx' ] );
+
+               $this->assertEquals(
+                       "SELECT  field  FROM `zend`  FORCE INDEX (a_b_idx)  WHERE a = 'x'  ",
+                       $sql
+               );
+       }
+
+       /**
+        * @covers Wikimedia\Rdbms\Database::setTableAliases
+        */
+       public function testTableAliases() {
+               $db = $this->getMockBuilder( DatabaseMysqli::class )
+                       ->disableOriginalConstructor()
+                       ->setMethods( [ 'mysqlRealEscapeString' ] )
+                       ->getMock();
+               $db->method( 'mysqlRealEscapeString' )->willReturnCallback(
+                       function ( $s ) {
+                               return str_replace( "'", "\\'", $s );
+                       }
+               );
+
+               $db->setTableAliases( [
+                       'meow' => [ 'dbname' => 'feline', 'schema' => null, 'prefix' => 'cat_' ]
+               ] );
+               $sql = $db->selectSQLText( 'meow', 'field', [ 'a' => 'x' ], __METHOD__ );
+
+               $this->assertEquals(
+                       "SELECT  field  FROM `feline`.`cat_meow`    WHERE a = 'x'  ",
+                       $sql
+               );
+
+               $db->setTableAliases( [] );
+               $sql = $db->selectSQLText( 'meow', 'field', [ 'a' => 'x' ], __METHOD__ );
+
+               $this->assertEquals(
+                       "SELECT  field  FROM `meow`    WHERE a = 'x'  ",
+                       $sql
+               );
+       }
 }
index 6adbc75..85574b7 100644 (file)
@@ -1,11 +1,14 @@
 <?php
 
-use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\Database;
+use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\DatabaseMysqli;
 use Wikimedia\Rdbms\LBFactorySingle;
 use Wikimedia\Rdbms\TransactionProfiler;
 use Wikimedia\TestingAccessWrapper;
+use Wikimedia\Rdbms\DatabaseSqlite;
+use Wikimedia\Rdbms\DatabasePostgres;
+use Wikimedia\Rdbms\DatabaseMssql;
 
 class DatabaseTest extends PHPUnit\Framework\TestCase {
 
@@ -15,6 +18,29 @@ class DatabaseTest extends PHPUnit\Framework\TestCase {
                $this->db = new DatabaseTestHelper( __CLASS__ . '::' . $this->getName() );
        }
 
+       /**
+        * @dataProvider provideAddQuotes
+        * @covers Wikimedia\Rdbms\Database::factory
+        */
+       public function testFactory() {
+               $m = Database::NEW_UNCONNECTED; // no-connect mode
+               $p = [ 'host' => 'localhost', 'user' => 'me', 'password' => 'myself', 'dbname' => 'i' ];
+
+               $this->assertInstanceOf( DatabaseMysqli::class, Database::factory( 'mysqli', $p, $m ) );
+               $this->assertInstanceOf( DatabaseMysqli::class, Database::factory( 'MySqli', $p, $m ) );
+               $this->assertInstanceOf( DatabaseMysqli::class, Database::factory( 'MySQLi', $p, $m ) );
+               $this->assertInstanceOf( DatabasePostgres::class, Database::factory( 'postgres', $p, $m ) );
+               $this->assertInstanceOf( DatabasePostgres::class, Database::factory( 'Postgres', $p, $m ) );
+
+               $x = $p + [ 'port' => 10000, 'UseWindowsAuth' => false ];
+               $this->assertInstanceOf( DatabaseMssql::class, Database::factory( 'mssql', $x, $m ) );
+
+               $x = $p + [ 'dbFilePath' => 'some/file.sqlite' ];
+               $this->assertInstanceOf( DatabaseSqlite::class, Database::factory( 'sqlite', $x, $m ) );
+               $x = $p + [ 'dbDirectory' => 'some/file' ];
+               $this->assertInstanceOf( DatabaseSqlite::class, Database::factory( 'sqlite', $x, $m ) );
+       }
+
        public static function provideAddQuotes() {
                return [
                        [ null, 'NULL' ],
index 6367a0f..53b659f 100644 (file)
@@ -1390,7 +1390,7 @@ more stuff
         * @covers WikiPage::newFromID
         */
        public function testNewFromId_returnsNullOnNonExistingId() {
-               $this->assertNull( WikiPage::newFromID( 73574757437437743743 ) );
+               $this->assertNull( WikiPage::newFromID( 2147483647 ) );
        }
 
        public function provideTestInsertProtectNullRevision() {
index 0bc558a..4e9f539 100644 (file)
@@ -261,7 +261,7 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                                'jquery.foo,bar|jquery.ui.baz,quux',
                        ],
                        [
-                               'Regression fixed in r88706 with dotless names',
+                               'Regression fixed in r87497 (7fee86c38e) with dotless names',
                                [ 'foo', 'bar', 'baz' ],
                                'foo,bar,baz',
                        ],
index 3e120f4..a34c03f 100644 (file)
@@ -99,6 +99,11 @@ class LanguageRuTest extends LanguageClassesTestCase {
                                'Викисклад',
                                'genitive',
                        ],
+                       [
+                               'Викиверситета',
+                               'Викиверситет',
+                               'genitive',
+                       ],
                        [
                                'Викискладе',
                                'Викисклад',
@@ -109,6 +114,11 @@ class LanguageRuTest extends LanguageClassesTestCase {
                                'Викиданные',
                                'prepositional',
                        ],
+                       [
+                               'Викиверситете',
+                               'Викиверситет',
+                               'prepositional',
+                       ],
                        [
                                'русского',
                                'русский',
index 43e8e9b..58460e2 100644 (file)
@@ -7,7 +7,7 @@ CREATE TABLE /*_*/MediaWikiTestCaseTestTable (
 CREATE TABLE /*_*/imagelinks (
   il_from int NOT NULL DEFAULT 0,
   il_from_namespace int NOT NULL DEFAULT 0,
-  il_to varchar(255) NOT NULL DEFAULT '',
-  il_frobniz varchar(255) NOT NULL DEFAULT 'FROB',
+  il_to varchar(127) NOT NULL DEFAULT '',
+  il_frobniz varchar(127) NOT NULL DEFAULT 'FROB',
   PRIMARY KEY (il_from,il_to)
 ) /*$wgDBTableOptions*/;
index 671bdf1..2300949 100644 (file)
  */
 header( 'Content-Type: text/javascript; charset=utf-8' );
 
-require_once __DIR__ . '/../../../includes/json/FormatJson.php';
-require_once __DIR__ . '/../../../includes/Xml.php';
-
 $moduleImplementations = [
        'testUsesMissing' => "
 mw.loader.implement( 'testUsesMissing', function () {
-       QUnit.ok( false, 'Module usesMissing script should not run.' );
-       QUnit.start();
+       mw.loader.testFail( 'Module usesMissing script should not run.' );
 }, {}, {});
 ",
 
        'testUsesNestedMissing' => "
 mw.loader.implement( 'testUsesNestedMissing', function () {
-       QUnit.ok( false, 'Module testUsesNestedMissing script should not run.' );
-       QUnit.start();
+       mw.loader.testFail('Module testUsesNestedMissing script should not run.' );
 }, {}, {});
 ",
 
        'testSkipped' => "
 mw.loader.implement( 'testSkipped', function () {
-       QUnit.ok( false, 'Module testSkipped was supposed to be skipped.' );
+       mw.loader.testFail( false, 'Module testSkipped was supposed to be skipped.' );
 }, {}, {});
 ",
 
@@ -54,19 +49,57 @@ mw.loader.implement( 'testNotSkipped', function () {}, {}, {});
 
        'testUsesSkippable' => "
 mw.loader.implement( 'testUsesSkippable', function () {}, {}, {});
+",
+
+       'testUrlInc' => "
+mw.loader.implement( 'testUrlInc', function () {} );
+",
+       'testUrlInc.a' => "
+mw.loader.implement( 'testUrlInc.a', function () {} );
+",
+       'testUrlInc.b' => "
+mw.loader.implement( 'testUrlInc.b', function () {} );
+",
+       'testUrlOrder' => "
+mw.loader.implement( 'testUrlOrder', function () {} );
+",
+       'testUrlOrder.a' => "
+mw.loader.implement( 'testUrlOrder.a', function () {} );
+",
+       'testUrlOrder.b' => "
+mw.loader.implement( 'testUrlOrder.b', function () {} );
 ",
 ];
 
 $response = '';
 
-// Only support for non-encoded module names, full module names expected
+// Does not support the full behaviour of ResourceLoaderContext::expandModuleNames(),
+// Only supports dotless module names joined by comma,
+// with the exception of the hardcoded cases for testUrl*.
 if ( isset( $_GET['modules'] ) ) {
-       $modules = explode( ',', $_GET['modules'] );
+       if ( $_GET['modules'] === 'testUrlInc,testUrlIncDump|testUrlInc.a,b' ) {
+               $modules = [ 'testUrlInc', 'testUrlIncDump', 'testUrlInc.a', 'testUrlInc.b' ];
+       } elseif ( $_GET['modules'] === 'testUrlOrder,testUrlOrderDump|testUrlOrder.a,b' ) {
+               $modules = [ 'testUrlOrder', 'testUrlOrderDump', 'testUrlOrder.a', 'testUrlOrder.b' ];
+       } else {
+               $modules = explode( ',', $_GET['modules'] );
+       }
        foreach ( $modules as $module ) {
                if ( isset( $moduleImplementations[$module] ) ) {
                        $response .= $moduleImplementations[$module];
+               } elseif ( preg_match( '/^test.*Dump$/', $module ) === 1 ) {
+                       $queryModules = $_GET['modules'];
+                       $queryVersion = isset( $_GET['version'] ) ? strval( $_GET['version'] ) : null;
+                       $response .= 'mw.loader.implement( ' . json_encode( $module )
+                               . ', function ( $, jQuery, require, module ) {'
+                               . 'module.exports.query = { '
+                               . 'modules: ' . json_encode( $queryModules ) . ','
+                               . 'version: ' . json_encode( $queryVersion )
+                               . ' };'
+                               . '} );';
                } else {
-                       $response .= Xml::encodeJsCall( 'mw.loader.state', [ $module, 'missing' ], true );
+                       // Default
+                       $response .= 'mw.loader.state(' . json_encode( $module ) . ', "missing" );' . "\n";
                }
        }
 }
index 5ce61ea..7da1502 100644 (file)
                                expected: 'привилегии',
                                description: 'Grammar test for prepositional case, привилегия -> привилегии'
                        },
+                       {
+                               word: 'университет',
+                               grammarForm: 'prepositional',
+                               expected: 'университете',
+                               description: 'Grammar test for prepositional case, университет -> университете'
+                       },
+                       {
+                               word: 'университет',
+                               grammarForm: 'genitive',
+                               expected: 'университета',
+                               description: 'Grammar test for prepositional case, университет -> университете'
+                       },
                        {
                                word: 'установка',
                                grammarForm: 'prepositional',
index 64415e0..0b05ac1 100644 (file)
@@ -1,7 +1,12 @@
 ( function ( mw, $ ) {
        QUnit.module( 'mediawiki (mw.loader)', QUnit.newMwEnvironment( {
-               setup: function () {
+               setup: function ( assert ) {
                        mw.loader.store.enabled = false;
+
+                       // Expose for load.mock.php
+                       mw.loader.testFail = function ( reason ) {
+                               assert.ok( false, reason );
+                       };
                },
                teardown: function () {
                        mw.loader.store.enabled = false;
                                window.Set = this.nativeSet;
                                mw.redefineFallbacksForTest();
                        }
+                       // Remove any remaining temporary statics
+                       // exposed for cross-file mocks.
+                       if ( 'testCallback' in mw.loader ) {
+                               delete mw.loader.testCallback;
+                       }
+                       if ( 'testFail' in mw.loader ) {
+                               delete mw.loader.testFail;
+                       }
                }
        } ) );
 
 
                return mw.loader.using( 'test.callback', function () {
                        assert.strictEqual( isAwesomeDone, true, 'test.callback module should\'ve caused isAwesomeDone to be true' );
-                       delete mw.loader.testCallback;
-
                }, function () {
                        assert.ok( false, 'Error callback fired while loader.using "test.callback" module' );
                } );
 
                return mw.loader.using( 'hasOwnProperty', function () {
                        assert.strictEqual( isAwesomeDone, true, 'hasOwnProperty module should\'ve caused isAwesomeDone to be true' );
-                       delete mw.loader.testCallback;
-
                }, function () {
                        assert.ok( false, 'Error callback fired while loader.using "hasOwnProperty" module' );
                } );
                return mw.loader.using( 'test.promise' )
                        .done( function () {
                                assert.strictEqual( isAwesomeDone, true, 'test.promise module should\'ve caused isAwesomeDone to be true' );
-                               delete mw.loader.testCallback;
                        } )
                        .fail( function () {
                                assert.ok( false, 'Error callback fired while loader.using "test.promise" module' );
                assert.strictEqual( mw.loader.getState( 'test.empty' ), 'ready' );
        } );
 
+       // @covers mw.loader#batchRequest
+       // This is a regression test because in the past we called getCombinedVersion()
+       // for all requested modules, before url splitting took place.
+       // Discovered as part of T188076, but not directly related.
+       QUnit.test( 'Url composition (modules considered for version)', function ( assert ) {
+               mw.loader.register( [
+                       // [module, version, dependencies, group, source]
+                       [ 'testUrlInc', 'url', [], null, 'testloader' ],
+                       [ 'testUrlIncDump', 'dump', [], null, 'testloader' ]
+               ] );
+
+               mw.config.set( 'wgResourceLoaderMaxQueryLength', 10 );
+
+               return mw.loader.using( [ 'testUrlIncDump', 'testUrlInc' ] ).then( function ( require ) {
+                       assert.propEqual(
+                               require( 'testUrlIncDump' ).query,
+                               {
+                                       modules: 'testUrlIncDump',
+                                       // Expected: Wrapped hash just for this one module
+                                       //   $hash = hash( 'fnv132', 'dump');
+                                       //   base_convert( $hash, 16, 36 ); // "13e9zzn"
+                                       // Previously: Wrapped hash for both modules, despite being in separate requests
+                                       //   $hash = hash( 'fnv132', 'urldump' );
+                                       //   base_convert( $hash, 16, 36 ); // "18kz9ca"
+                                       version: '13e9zzn'
+                               },
+                               'Query parameters'
+                       );
+
+                       assert.strictEqual( mw.loader.getState( 'testUrlInc' ), 'ready', 'testUrlInc also loaded' );
+               } );
+       } );
+
+       // @covers mw.loader#batchRequest
+       // @covers mw.loader#buildModulesString
+       QUnit.test( 'Url composition (order of modules for version) – T188076', function ( assert ) {
+               mw.loader.register( [
+                       // [module, version, dependencies, group, source]
+                       [ 'testUrlOrder', 'url', [], null, 'testloader' ],
+                       [ 'testUrlOrder.a', '1', [], null, 'testloader' ],
+                       [ 'testUrlOrder.b', '2', [], null, 'testloader' ],
+                       [ 'testUrlOrderDump', 'dump', [], null, 'testloader' ]
+               ] );
+
+               return mw.loader.using( [
+                       'testUrlOrderDump',
+                       'testUrlOrder.b',
+                       'testUrlOrder.a',
+                       'testUrlOrder'
+               ] ).then( function ( require ) {
+                       assert.propEqual(
+                               require( 'testUrlOrderDump' ).query,
+                               {
+                                       modules: 'testUrlOrder,testUrlOrderDump|testUrlOrder.a,b',
+                                       // Expected: Combined in order after string packing
+                                       //   $hash = hash( 'fnv132', 'urldump12' );
+                                       //   base_convert( $hash, 16, 36 ); // "1knqzan"
+                                       // Previously: Combined in order of before string packing
+                                       //   $hash = hash( 'fnv132', 'url12dump' );
+                                       //   base_convert( $hash, 16, 36 ); // "11eo3in"
+                                       version: '1knqzan'
+                               },
+                               'Query parameters'
+                       );
+               } );
+       } );
+
        QUnit.test( 'Broken indirect dependency', function ( assert ) {
                // don't emit an error event
                this.sandbox.stub( mw, 'track' );
                assert.equal( target.slice( 0, 2 ), '//', 'URL is protocol-relative' );
 
                mw.loader.testCallback = function () {
+                       // Ensure once, delete now
                        delete mw.loader.testCallback;
                        assert.ok( true, 'callback' );
                        done();
                assert.equal( target.slice( 0, 1 ), '/', 'URL is relative to document root' );
 
                mw.loader.testCallback = function () {
+                       // Ensure once, delete now
                        delete mw.loader.testCallback;
                        assert.ok( true, 'callback' );
                        done();