Merge "Add test for WikiPage post-edit stats update"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 6 Mar 2018 01:51:27 +0000 (01:51 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 6 Mar 2018 01:51:27 +0000 (01:51 +0000)
223 files changed:
RELEASE-NOTES-1.31
autoload.php
includes/DefaultSettings.php
includes/EditPage.php
includes/MediaWikiServices.php
includes/Revision.php
includes/ServiceWiring.php
includes/SiteStatsInit.php
includes/Storage/NameTableAccessException.php [new file with mode: 0644]
includes/Storage/NameTableStore.php [new file with mode: 0644]
includes/Storage/RevisionRecord.php
includes/Storage/RevisionSlots.php
includes/Storage/RevisionStore.php
includes/Title.php
includes/api/ApiQueryContributors.php
includes/api/i18n/de.json
includes/api/i18n/fr.json
includes/api/i18n/it.json
includes/api/i18n/ja.json
includes/api/i18n/pt-br.json
includes/api/i18n/pt.json
includes/api/i18n/zh-hans.json
includes/config/EtcdConfig.php
includes/content/WikitextContent.php
includes/diff/DifferenceEngine.php
includes/installer/DatabaseUpdater.php
includes/installer/i18n/fa.json
includes/installer/i18n/he.json
includes/installer/i18n/sr-ec.json
includes/jobqueue/JobQueueSecondTestQueue.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/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/logging/LogPager.php
includes/parser/Parser.php
includes/parser/StripState.php
includes/resourceloader/ResourceLoader.php
includes/specials/SpecialRecentchanges.php
includes/specials/pagers/ContribsPager.php
includes/specials/pagers/NewFilesPager.php
includes/user/User.php
languages/i18n/aeb-arab.json
languages/i18n/af.json
languages/i18n/ais.json
languages/i18n/ar.json
languages/i18n/as.json
languages/i18n/ast.json
languages/i18n/awa.json
languages/i18n/azb.json
languages/i18n/ba.json
languages/i18n/bcc.json
languages/i18n/bcl.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bgn.json
languages/i18n/bho.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/cs.json
languages/i18n/cy.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dsb.json
languages/i18n/dty.json
languages/i18n/egl.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frp.json
languages/i18n/frr.json
languages/i18n/gd.json
languages/i18n/gl.json
languages/i18n/gor.json
languages/i18n/gsw.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hif-latn.json
languages/i18n/hil.json
languages/i18n/hr.json
languages/i18n/hrx.json
languages/i18n/hsb.json
languages/i18n/hu.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/ilo.json
languages/i18n/io.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/kab.json
languages/i18n/kbd-cyrl.json
languages/i18n/kk-cyrl.json
languages/i18n/ko.json
languages/i18n/krc.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/kum.json
languages/i18n/lfn.json
languages/i18n/li.json
languages/i18n/lij.json
languages/i18n/lki.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/mai.json
languages/i18n/mg.json
languages/i18n/min.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mr.json
languages/i18n/ms.json
languages/i18n/mwl.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nds-nl.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/or.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/qu.json
languages/i18n/rm.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/rue.json
languages/i18n/sa.json
languages/i18n/sah.json
languages/i18n/scn.json
languages/i18n/sco.json
languages/i18n/sd.json
languages/i18n/ses.json
languages/i18n/sh.json
languages/i18n/si.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sq.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/ta.json
languages/i18n/te.json
languages/i18n/th.json
languages/i18n/tl.json
languages/i18n/tr.json
languages/i18n/ug-arab.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/vec.json
languages/i18n/vi.json
languages/i18n/wa.json
languages/i18n/wuu.json
languages/i18n/xmf.json
languages/i18n/yo.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/archives/upgradeLogging.php
maintenance/clearInterwikiCache.php
maintenance/migrateActors.php
maintenance/populateBacklinkNamespace.php
maintenance/populateFilearchiveSha1.php
maintenance/populateIpChanges.php
maintenance/populateLogSearch.php
maintenance/populateLogUsertext.php
maintenance/populateParentId.php
maintenance/populateRecentChangesSource.php
maintenance/populateRevisionLength.php
maintenance/populateRevisionSha1.php
maintenance/rebuildFileCache.php
maintenance/refreshLinks.php
maintenance/storage/checkStorage.php
maintenance/storage/fixT22757.php
maintenance/storage/moveToExternal.php
maintenance/storage/orphanStats.php
maintenance/storage/resolveStubs.php
maintenance/storage/storageTypeStats.php
maintenance/storage/trackBlobs.php
maintenance/updateRestrictions.php
resources/src/mediawiki.action/mediawiki.action.edit.styles.less
resources/src/mediawiki/mediawiki.diff.styles.css
tests/common/TestsAutoLoader.php
tests/phpunit/includes/Storage/MutableRevisionRecordTest.php
tests/phpunit/includes/Storage/MutableRevisionSlotsTest.php
tests/phpunit/includes/Storage/NameTableStoreTest.php [new file with mode: 0644]
tests/phpunit/includes/Storage/RevisionSlotsTest.php
tests/phpunit/includes/Storage/RevisionStoreRecordTest.php
tests/phpunit/includes/config/EtcdConfigTest.php
tests/phpunit/includes/content/JavaScriptContentTest.php
tests/phpunit/includes/content/TextContentTest.php
tests/phpunit/includes/content/WikitextContentTest.php
tests/phpunit/includes/db/DatabaseSqliteTest.php
tests/phpunit/includes/db/LoadBalancerTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseMysqlBaseTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php
tests/phpunit/includes/page/WikiPageDbTestBase.php
tests/phpunit/includes/parser/StripStateTest.php [new file with mode: 0644]
tests/phpunit/includes/resourceloader/ResourceLoaderClientHtmlTest.php
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js

index 8113314..83669e6 100644 (file)
@@ -28,6 +28,9 @@ production.
   as upstream is inactive and has no plans to move to PHP 7.
 * The old CategorizedRecentChanges feature, including its related configuration
   option $wgAllowCategorizedRecentChanges, has been removed.
+* (T188472) The 'comma' value for $wgArticleCountMethod is no longer supported for
+  performance reasons, and installations with this setting will now work as if it
+  was configured with 'any'.
 
 === New features in 1.31 ===
 * Wikimedia\Rdbms\IDatabase->select() and similar methods now support
@@ -256,16 +259,32 @@ changes to languages because of Phabricator reports.
   * Title::isCssJsSubpage – use ::isUserConfigPage
   * Title::isCssSubpage – use ::isUserCssConfigPage
   * Title::isJsSubpage – use ::isUserJsConfigPage
-* The following variables and method in EditPage, deprecated in MediaWiki 1.30, were removed:
+* The following variables and methods in EditPage, deprecated in MediaWiki 1.30, were removed:
   * $isCssJsSubpage — use ::isUserConfigPage()
   * $isCssSubpage — use ::isUserCssConfigPage()
   * $isJsSubpage — use ::isUserJsConfigPage()
   * $isWrongCaseCssJsPage – use ::isWrongCaseUserConfigPage()
+  * ::getSummaryInput() – use ::getSummaryInputWidget()
+  * ::getSummaryInputOOUI() – use ::getSummaryInputWidget()
+  * ::getCheckboxes() – use ::getCheckboxesWidget() or ::getCheckboxesDefinition()
+  * ::getCheckboxesOOUI() – use ::getCheckboxesWidget() or ::getCheckboxesDefinition()
 * The method ResourceLoaderModule::getPosition(), deprecated in 1.29, has been removed.
 * The DeferredStringifier class is deprecated, use Message::listParam() instead.
 * The type string for the parameter $lang of DateFormatter::getInstance is
   deprecated.
+* In User, the cookie-related methods which were wrappers for the functions on the response
+  object, and were deprecated in 1.27, have been removed:
+  * ::setCookie()
+  * ::clearCookie()
+  * ::setExtendedLoginCookie()
+  Note that User::setCookies() remains, and is not deprecated.
 * The global functions wfProfileIn and wfProfileOut, deprecated in 1.25, have been removed.
+* The following methods related to caching of half-parsed HTML were deprecated:
+  * Parser::serializeHalfParsedText()
+  * Parser::unserializeHalfParsedText()
+  * Parser::isValidHalfParsedText()
+  * StripState::getSubState()
+  * StripState::merge()
 
 == Compatibility ==
 MediaWiki 1.31 requires PHP 5.5.9 or later. Although HHVM 3.18.5 or later is supported,
index 1aa8dc2..b5f3e4a 100644 (file)
@@ -953,6 +953,8 @@ $wgAutoloadLocalClasses = [
        'MediaWiki\\Storage\\IncompleteRevisionException' => __DIR__ . '/includes/Storage/IncompleteRevisionException.php',
        'MediaWiki\\Storage\\MutableRevisionRecord' => __DIR__ . '/includes/Storage/MutableRevisionRecord.php',
        'MediaWiki\\Storage\\MutableRevisionSlots' => __DIR__ . '/includes/Storage/MutableRevisionSlots.php',
+       'MediaWiki\\Storage\\NameTableAccessException' => __DIR__ . '/includes/Storage/NameTableAccessException.php',
+       'MediaWiki\\Storage\\NameTableStore' => __DIR__ . '/includes/Storage/NameTableStore.php',
        'MediaWiki\\Storage\\RevisionAccessException' => __DIR__ . '/includes/Storage/RevisionAccessException.php',
        'MediaWiki\\Storage\\RevisionArchiveRecord' => __DIR__ . '/includes/Storage/RevisionArchiveRecord.php',
        'MediaWiki\\Storage\\RevisionFactory' => __DIR__ . '/includes/Storage/RevisionFactory.php',
index 33418d8..fad49e4 100644 (file)
@@ -3311,9 +3311,10 @@ $wgAllowUserJs = false;
 $wgAllowUserCss = false;
 
 /**
- * Allow user-preferences implemented in CSS?
- * This allows users to customise the site appearance to a greater
- * degree; disabling it will improve page load times.
+ * Allow style-related user-preferences?
+ *
+ * This controls whether the `editfont` and `underline` preferences
+ * are availabe to users.
  */
 $wgAllowUserCssPrefs = true;
 
@@ -4438,7 +4439,6 @@ $wgEnableMagicLinks = [
  *
  * This variable can have the following values:
  * - 'any': all pages as considered as valid articles
- * - 'comma': the page must contain a comma to be considered valid
  * - 'link': the page must contain a [[wiki link]] to be considered valid
  *
  * See also See https://www.mediawiki.org/wiki/Manual:Article_count
index 08c4a72..ad5f75d 100644 (file)
@@ -3153,62 +3153,6 @@ ERROR;
                ];
        }
 
-       /**
-        * Standard summary input and label (wgSummary), abstracted so EditPage
-        * subclasses may reorganize the form.
-        * Note that you do not need to worry about the label's for=, it will be
-        * inferred by the id given to the input. You can remove them both by
-        * passing [ 'id' => false ] to $userInputAttrs.
-        *
-        * @deprecated since 1.30 Use getSummaryInputWidget() instead
-        * @param string $summary The value of the summary input
-        * @param string $labelText The html to place inside the label
-        * @param array $inputAttrs Array of attrs to use on the input
-        * @param array $spanLabelAttrs Array of attrs to use on the span inside the label
-        * @return array An array in the format [ $label, $input ]
-        */
-       public function getSummaryInput( $summary = "", $labelText = null,
-               $inputAttrs = null, $spanLabelAttrs = null
-       ) {
-               wfDeprecated( __METHOD__, '1.30' );
-               $inputAttrs = $this->getSummaryInputAttributes( $inputAttrs );
-               $inputAttrs += Linker::tooltipAndAccesskeyAttribs( 'summary' );
-
-               $spanLabelAttrs = ( is_array( $spanLabelAttrs ) ? $spanLabelAttrs : [] ) + [
-                       'class' => $this->missingSummary ? 'mw-summarymissed' : 'mw-summary',
-                       'id' => "wpSummaryLabel"
-               ];
-
-               $label = null;
-               if ( $labelText ) {
-                       $label = Xml::tags(
-                               'label',
-                               $inputAttrs['id'] ? [ 'for' => $inputAttrs['id'] ] : null,
-                               $labelText
-                       );
-                       $label = Xml::tags( 'span', $spanLabelAttrs, $label );
-               }
-
-               $input = Html::input( 'wpSummary', $summary, 'text', $inputAttrs );
-
-               return [ $label, $input ];
-       }
-
-       /**
-        * Builds a standard summary input with a label.
-        *
-        * @deprecated since 1.30 Use getSummaryInputWidget() instead
-        * @param string $summary The value of the summary input
-        * @param string $labelText The html to place inside the label
-        * @param array $inputAttrs Array of attrs to use on the input
-        *
-        * @return OOUI\FieldLayout OOUI FieldLayout with Label and Input
-        */
-       function getSummaryInputOOUI( $summary = "", $labelText = null, $inputAttrs = null ) {
-               wfDeprecated( __METHOD__, '1.30' );
-               return $this->getSummaryInputWidget( $summary, $labelText, $inputAttrs );
-       }
-
        /**
         * Builds a standard summary input with a label.
         *
@@ -4225,76 +4169,6 @@ ERROR;
                return $checkboxes;
        }
 
-       /**
-        * Returns an array of html code of the following checkboxes old style:
-        * minor and watch
-        *
-        * @deprecated since 1.30 Use getCheckboxesWidget() or getCheckboxesDefinition() instead
-        * @param int &$tabindex Current tabindex
-        * @param array $checked See getCheckboxesDefinition()
-        * @return array
-        */
-       public function getCheckboxes( &$tabindex, $checked ) {
-               wfDeprecated( __METHOD__, '1.30' );
-               $checkboxes = [];
-               $checkboxesDef = $this->getCheckboxesDefinition( $checked );
-
-               // Backwards-compatibility for the EditPageBeforeEditChecks hook
-               if ( !$this->isNew ) {
-                       $checkboxes['minor'] = '';
-               }
-               $checkboxes['watch'] = '';
-
-               foreach ( $checkboxesDef as $name => $options ) {
-                       $legacyName = isset( $options['legacy-name'] ) ? $options['legacy-name'] : $name;
-                       $label = $this->context->msg( $options['label-message'] )->parse();
-                       $attribs = [
-                               'tabindex' => ++$tabindex,
-                               'id' => $options['id'],
-                       ];
-                       $labelAttribs = [
-                               'for' => $options['id'],
-                       ];
-                       if ( isset( $options['tooltip'] ) ) {
-                               $attribs['accesskey'] = $this->context->msg( "accesskey-{$options['tooltip']}" )->text();
-                               $labelAttribs['title'] = Linker::titleAttrib( $options['tooltip'], 'withaccess' );
-                       }
-                       if ( isset( $options['title-message'] ) ) {
-                               $labelAttribs['title'] = $this->context->msg( $options['title-message'] )->text();
-                       }
-                       if ( isset( $options['label-id'] ) ) {
-                               $labelAttribs['id'] = $options['label-id'];
-                       }
-                       $checkboxHtml =
-                               Xml::check( $name, $options['default'], $attribs ) .
-                               '&#160;' .
-                               Xml::tags( 'label', $labelAttribs, $label );
-
-                       $checkboxes[ $legacyName ] = $checkboxHtml;
-               }
-
-               // Avoid PHP 7.1 warning of passing $this by reference
-               $editPage = $this;
-               Hooks::run( 'EditPageBeforeEditChecks', [ &$editPage, &$checkboxes, &$tabindex ], '1.29' );
-               return $checkboxes;
-       }
-
-       /**
-        * Returns an array of checkboxes for the edit form, including 'minor' and 'watch' checkboxes and
-        * any other added by extensions.
-        *
-        * @deprecated since 1.30 Use getCheckboxesWidget() or getCheckboxesDefinition() instead
-        * @param int &$tabindex Current tabindex
-        * @param array $checked Array of checkbox => bool, where bool indicates the checked
-        *                 status of the checkbox
-        *
-        * @return array Associative array of string keys to OOUI\FieldLayout instances
-        */
-       public function getCheckboxesOOUI( &$tabindex, $checked ) {
-               wfDeprecated( __METHOD__, '1.30' );
-               return $this->getCheckboxesWidget( $tabindex, $checked );
-       }
-
        /**
         * Returns an array of checkboxes for the edit form, including 'minor' and 'watch' checkboxes and
         * any other added by extensions.
index 3c8ce65..8bb0a40 100644 (file)
@@ -16,6 +16,7 @@ use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Shell\CommandFactory;
 use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\BlobStoreFactory;
+use MediaWiki\Storage\NameTableStore;
 use MediaWiki\Storage\RevisionFactory;
 use MediaWiki\Storage\RevisionLookup;
 use MediaWiki\Storage\RevisionStore;
@@ -770,6 +771,22 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'RevisionFactory' );
        }
 
+       /**
+        * @since 1.31
+        * @return NameTableStore
+        */
+       public function getContentModelStore() {
+               return $this->getService( 'ContentModelStore' );
+       }
+
+       /**
+        * @since 1.31
+        * @return NameTableStore
+        */
+       public function getSlotRoleStore() {
+               return $this->getService( 'SlotRoleStore' );
+       }
+
        /**
         * @since 1.31
         * @return PreferencesFactory
index f8a3fcc..22eb115 100644 (file)
@@ -938,11 +938,6 @@ class Revision implements IDBAccessObject {
                        return $this->mRecord->getContent( 'main', $audience, $user );
                }
                catch ( RevisionAccessException $e ) {
-                       wfDebugLog(
-                               'T184670',
-                               __METHOD__ . ": Cannot get content: " . $e->getMessage() .
-                               "\n" . $e->getTraceAsString()
-                       );
                        return null;
                }
        }
index 3e3c897..08d343b 100644 (file)
@@ -45,6 +45,7 @@ use MediaWiki\MediaWikiServices;
 use MediaWiki\Preferences\DefaultPreferencesFactory;
 use MediaWiki\Shell\CommandFactory;
 use MediaWiki\Storage\BlobStoreFactory;
+use MediaWiki\Storage\NameTableStore;
 use MediaWiki\Storage\RevisionStore;
 use MediaWiki\Storage\SqlBlobStore;
 use Wikimedia\ObjectFactory;
@@ -539,6 +540,35 @@ return [
                return $services->getBlobStoreFactory()->newSqlBlobStore();
        },
 
+       'ContentModelStore' => function ( MediaWikiServices $services ) {
+               return new NameTableStore(
+                       $services->getDBLoadBalancer(),
+                       $services->getMainWANObjectCache(),
+                       LoggerFactory::getInstance( 'NameTableSqlStore' ),
+                       'content_models',
+                       'model_id',
+                       'model_name'
+                       /**
+                        * No strtolower normalization is added to the service as there are examples of
+                        * extensions that do not stick to this assumption.
+                        * - extensions/examples/DataPages define( 'CONTENT_MODEL_XML_DATA','XML_DATA' );
+                        * - extensions/Scribunto define( 'CONTENT_MODEL_SCRIBUNTO', 'Scribunto' );
+                        */
+               );
+       },
+
+       'SlotRoleStore' => function ( MediaWikiServices $services ) {
+               return new NameTableStore(
+                       $services->getDBLoadBalancer(),
+                       $services->getMainWANObjectCache(),
+                       LoggerFactory::getInstance( 'NameTableSqlStore' ),
+                       'slot_roles',
+                       'role_id',
+                       'role_name',
+                       'strtolower'
+               );
+       },
+
        'PreferencesFactory' => function ( MediaWikiServices $services ) {
                global $wgContLang;
                $authManager = AuthManager::singleton();
index f527cb2..8adb218 100644 (file)
@@ -79,13 +79,6 @@ class SiteStatsInit {
                if ( $config->get( 'ArticleCountMethod' ) == 'link' ) {
                        $tables[] = 'pagelinks';
                        $conds[] = 'pl_from=page_id';
-               } elseif ( $config->get( 'ArticleCountMethod' ) == 'comma' ) {
-                       // To make a correct check for this, we would need, for each page,
-                       // to load the text, maybe uncompress it, maybe decode it and then
-                       // check if there's one comma.
-                       // But one thing we are sure is that if the page is empty, it can't
-                       // contain a comma :)
-                       $conds[] = 'page_len > 0';
                }
 
                $this->articles = $this->dbr->selectField(
diff --git a/includes/Storage/NameTableAccessException.php b/includes/Storage/NameTableAccessException.php
new file mode 100644 (file)
index 0000000..393cb1f
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Exception representing a failure to look up a row from a name table.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace MediaWiki\Storage;
+
+use RuntimeException;
+
+/**
+ * Exception representing a failure to look up a row from a name table.
+ *
+ * @since 1.31
+ */
+class NameTableAccessException extends RuntimeException {
+
+       /**
+        * @param string $tableName
+        * @param string $accessType
+        * @param string|int $accessValue
+        * @return NameTableAccessException
+        */
+       public static function newFromDetails( $tableName, $accessType, $accessValue ) {
+               $message = "Failed to access name from ${tableName} using ${accessType} = ${accessValue}";
+               return new self( $message );
+       }
+
+}
diff --git a/includes/Storage/NameTableStore.php b/includes/Storage/NameTableStore.php
new file mode 100644 (file)
index 0000000..a1eba74
--- /dev/null
@@ -0,0 +1,365 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+namespace MediaWiki\Storage;
+
+use IExpiringStore;
+use Psr\Log\LoggerInterface;
+use WANObjectCache;
+use Wikimedia\Assert\Assert;
+use Wikimedia\Rdbms\Database;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\LoadBalancer;
+
+/**
+ * @author Addshore
+ * @since 1.31
+ */
+class NameTableStore {
+
+       /** @var LoadBalancer */
+       private $loadBalancer;
+
+       /** @var WANObjectCache */
+       private $cache;
+
+       /** @var LoggerInterface */
+       private $logger;
+
+       /** @var string[] */
+       private $tableCache = null;
+
+       /** @var bool|string */
+       private $wikiId = false;
+
+       /** @var int */
+       private $cacheTTL;
+
+       /** @var string */
+       private $table;
+       /** @var string */
+       private $idField;
+       /** @var string */
+       private $nameField;
+       /** @var null|callable */
+       private $normalizationCallback = null;
+
+       /**
+        * @param LoadBalancer $dbLoadBalancer A load balancer for acquiring database connections
+        * @param WANObjectCache $cache A cache manager for caching data
+        * @param LoggerInterface $logger
+        * @param string $table
+        * @param string $idField
+        * @param string $nameField
+        * @param callable $normalizationCallback Normalization to be applied to names before being
+        * saved or queried. This should be a callback that accepts and returns a single string.
+        * @param bool|string $wikiId The ID of the target wiki database. Use false for the local wiki.
+        */
+       public function __construct(
+               LoadBalancer $dbLoadBalancer,
+               WANObjectCache $cache,
+               LoggerInterface $logger,
+               $table,
+               $idField,
+               $nameField,
+               callable $normalizationCallback = null,
+               $wikiId = false
+       ) {
+               $this->loadBalancer = $dbLoadBalancer;
+               $this->cache = $cache;
+               $this->logger = $logger;
+               $this->table = $table;
+               $this->idField = $idField;
+               $this->nameField = $nameField;
+               $this->normalizationCallback = $normalizationCallback;
+               $this->wikiId = $wikiId;
+               $this->cacheTTL = IExpiringStore::TTL_MONTH;
+       }
+
+       /**
+        * @param int $index A database index, like DB_MASTER or DB_REPLICA
+        * @param int $flags Database connection flags
+        *
+        * @return IDatabase
+        */
+       private function getDBConnection( $index, $flags = 0 ) {
+               return $this->loadBalancer->getConnection( $index, [], $this->wikiId, $flags );
+       }
+
+       private function getCacheKey() {
+               return $this->cache->makeKey( 'NameTableSqlStore', $this->table, $this->wikiId );
+       }
+
+       /**
+        * @param string $name
+        * @return string
+        */
+       private function normalizeName( $name ) {
+               if ( $this->normalizationCallback === null ) {
+                       return $name;
+               }
+               return call_user_func( $this->normalizationCallback, $name );
+       }
+
+       /**
+        * Acquire the id of the given name.
+        * This creates a row in the table if it doesn't already exist.
+        *
+        * @param string $name
+        * @throws NameTableAccessException
+        * @return int
+        */
+       public function acquireId( $name ) {
+               Assert::parameterType( 'string', $name, '$name' );
+               $name = $this->normalizeName( $name );
+
+               $table = $this->getTableFromCachesOrReplica();
+               $searchResult = array_search( $name, $table, true );
+               if ( $searchResult === false ) {
+                       $id = $this->store( $name );
+                       if ( $id === null ) {
+                               // RACE: $name was already in the db, probably just inserted, so load from master
+                               // Use DBO_TRX to avoid missing inserts due to other threads or REPEATABLE-READs
+                               $table = $this->loadTable(
+                                       $this->getDBConnection( DB_MASTER, LoadBalancer::CONN_TRX_AUTO )
+                               );
+                               $searchResult = array_search( $name, $table, true );
+                               if ( $searchResult === false ) {
+                                       // Insert failed due to IGNORE flag, but DB_MASTER didn't give us the data
+                                       $m = "No insert possible but master didn't give us a record for " .
+                                               "'{$name}' in '{$this->table}'";
+                                       $this->logger->error( $m );
+                                       throw new NameTableAccessException( $m );
+                               }
+                               $this->purgeWANCache(
+                                       function () {
+                                               $this->cache->reap( $this->getCacheKey(), INF );
+                                       }
+                               );
+                       } else {
+                               $table[$id] = $name;
+                               $searchResult = $id;
+                               // As store returned an ID we know we inserted so delete from WAN cache
+                               $this->purgeWANCache(
+                                       function () {
+                                               $this->cache->delete( $this->getCacheKey() );
+                                       }
+                               );
+                       }
+                       $this->tableCache = $table;
+               }
+
+               return $searchResult;
+       }
+
+       /**
+        * Get the id of the given name.
+        * If the name doesn't exist this will throw.
+        * This should be used in cases where we believe the name already exists or want to check for
+        * existence.
+        *
+        * @param string $name
+        * @throws NameTableAccessException The name does not exist
+        * @return int Id
+        */
+       public function getId( $name ) {
+               Assert::parameterType( 'string', $name, '$name' );
+               $name = $this->normalizeName( $name );
+
+               $table = $this->getTableFromCachesOrReplica();
+               $searchResult = array_search( $name, $table, true );
+
+               if ( $searchResult !== false ) {
+                       return $searchResult;
+               }
+
+               throw NameTableAccessException::newFromDetails( $this->table, 'name', $name );
+       }
+
+       /**
+        * Get the name of the given id.
+        * If the id doesn't exist this will throw.
+        * This should be used in cases where we believe the id already exists.
+        *
+        * Note: Calls to this method will result in a master select for non existing IDs.
+        *
+        * @param int $id
+        * @throws NameTableAccessException The id does not exist
+        * @return string name
+        */
+       public function getName( $id ) {
+               Assert::parameterType( 'integer', $id, '$id' );
+
+               $table = $this->getTableFromCachesOrReplica();
+               if ( array_key_exists( $id, $table ) ) {
+                       return $table[$id];
+               }
+
+               $table = $this->cache->getWithSetCallback(
+                       $this->getCacheKey(),
+                       $this->cacheTTL,
+                       function ( $oldValue, &$ttl, &$setOpts ) use ( $id ) {
+                               // Check if cached value is up-to-date enough to have $id
+                               if ( is_array( $oldValue ) && array_key_exists( $id, $oldValue ) ) {
+                                       // Completely leave the cache key alone
+                                       $ttl = WANObjectCache::TTL_UNCACHEABLE;
+                                       // Use the old value
+                                       return $oldValue;
+                               }
+                               // Regenerate from replica DB, and master DB if needed
+                               foreach ( [ DB_REPLICA, DB_MASTER ] as $source ) {
+                                       // Log a fallback to master
+                                       if ( $source === DB_MASTER ) {
+                                               $this->logger->info(
+                                                       __METHOD__ . 'falling back to master select from ' .
+                                                       $this->table . ' with id ' . $id
+                                               );
+                                       }
+                                       $db = $this->getDBConnection( $source );
+                                       $cacheSetOpts = Database::getCacheSetOptions( $db );
+                                       $table = $this->loadTable( $db );
+                                       if ( array_key_exists( $id, $table ) ) {
+                                               break; // found it
+                                       }
+                               }
+                               // Use the value from last source checked
+                               $setOpts += $cacheSetOpts;
+
+                               return $table;
+                       },
+                       [ 'minAsOf' => INF ] // force callback run
+               );
+
+               $this->tableCache = $table;
+
+               if ( array_key_exists( $id, $table ) ) {
+                       return $table[$id];
+               }
+
+               throw NameTableAccessException::newFromDetails( $this->table, 'id', $id );
+       }
+
+       /**
+        * Get the whole table, in no particular order as a map of ids to names.
+        * This method could be subject to DB or cache lag.
+        *
+        * @return string[] keys are the name ids, values are the names themselves
+        *  Example: [ 1 => 'foo', 3 => 'bar' ]
+        */
+       public function getMap() {
+               return $this->getTableFromCachesOrReplica();
+       }
+
+       /**
+        * @return string[]
+        */
+       private function getTableFromCachesOrReplica() {
+               if ( $this->tableCache !== null ) {
+                       return $this->tableCache;
+               }
+
+               $table = $this->cache->getWithSetCallback(
+                       $this->getCacheKey(),
+                       $this->cacheTTL,
+                       function ( $oldValue, &$ttl, &$setOpts ) {
+                               $dbr = $this->getDBConnection( DB_REPLICA );
+                               $setOpts += Database::getCacheSetOptions( $dbr );
+                               return $this->loadTable( $dbr );
+                       }
+               );
+
+               $this->tableCache = $table;
+
+               return $table;
+       }
+
+       /**
+        * Reap the WANCache entry for this table.
+        *
+        * @param callable $purgeCallback callback to 'purge' the WAN cache
+        */
+       private function purgeWANCache( $purgeCallback ) {
+               // If the LB has no DB changes don't both with onTransactionPreCommitOrIdle
+               if ( !$this->loadBalancer->hasOrMadeRecentMasterChanges() ) {
+                       $purgeCallback();
+                       return;
+               }
+
+               $this->getDBConnection( DB_MASTER )
+                       ->onTransactionPreCommitOrIdle( $purgeCallback, __METHOD__ );
+       }
+
+       /**
+        * Gets the table from the db
+        *
+        * @param IDatabase $db
+        *
+        * @return string[]
+        */
+       private function loadTable( IDatabase $db ) {
+               $result = $db->select(
+                       $this->table,
+                       [
+                               'id' => $this->idField,
+                               'name' => $this->nameField
+                       ],
+                       [],
+                       __METHOD__
+               );
+
+               $assocArray = [];
+               foreach ( $result as $row ) {
+                       $assocArray[$row->id] = $row->name;
+               }
+
+               return $assocArray;
+       }
+
+       /**
+        * Stores the given name in the DB, returning the ID when an insert occurs.
+        *
+        * @param string $name
+        * @return int|null int if we know the ID, null if we don't
+        */
+       private function store( $name ) {
+               Assert::parameterType( 'string', $name, '$name' );
+               Assert::parameter( $name !== '', '$name', 'should not be an empty string' );
+               // Note: this is only called internally so normalization of $name has already occurred.
+
+               $dbw = $this->getDBConnection( DB_MASTER );
+
+               $dbw->insert(
+                       $this->table,
+                       [ $this->nameField => $name ],
+                       __METHOD__,
+                       [ 'IGNORE' ]
+               );
+
+               if ( $dbw->affectedRows() === 0 ) {
+                       $this->logger->info(
+                               'Tried to insert name into table ' . $this->table . ', but value already existed.'
+                       );
+                       return null;
+               }
+
+               return $dbw->insertId();
+       }
+
+}
index 8734f48..6d83e1c 100644 (file)
@@ -196,6 +196,17 @@ abstract class RevisionRecord {
                return $slot;
        }
 
+       /**
+        * Returns whether the given slot is defined in this revision.
+        *
+        * @param string $role The role name of the desired slot
+        *
+        * @return bool
+        */
+       public function hasSlot( $role ) {
+               return $this->mSlots->hasSlot( $role );
+       }
+
        /**
         * Returns the slot names (roles) of all slots present in this revision.
         * getContent() will succeed only for the names returned by this method.
index 8d3d7e3..7fa5431 100644 (file)
@@ -110,6 +110,19 @@ class RevisionSlots {
                }
        }
 
+       /**
+        * Returns whether the given slot is set.
+        *
+        * @param string $role The role name of the desired slot
+        *
+        * @return bool
+        */
+       public function hasSlot( $role ) {
+               $slots = $this->getSlots();
+
+               return isset( $slots[$role] );
+       }
+
        /**
         * Returns the slot names (roles) of all slots present in this revision.
         * getContent() will succeed only for the names returned by this method.
index e13fc1f..e00deef 100644 (file)
@@ -613,7 +613,7 @@ class RevisionStore
 
                        $fields['title'] = Title::makeTitle( $current->page_namespace, $current->page_title );
 
-                       $mainSlot = $this->emulateMainSlot_1_29( $fields, 0, $title );
+                       $mainSlot = $this->emulateMainSlot_1_29( $fields, self::READ_LATEST, $title );
                        $revision = new MutableRevisionRecord( $title, $this->wikiId );
                        $this->initializeMutableRevisionFromArray( $revision, $fields );
                        $revision->setSlot( $mainSlot );
index 6dc7db5..66aadeb 100644 (file)
@@ -1320,7 +1320,7 @@ class Title implements LinkTarget {
         * @deprecated Since 1.31; use ::isSiteConfigPage() instead
         */
        public function isCssOrJsPage() {
-               // wfDeprecated( __METHOD__, '1.31' );
+               wfDeprecated( __METHOD__, '1.31' );
                return ( NS_MEDIAWIKI == $this->mNamespace
                                && ( $this->hasContentModel( CONTENT_MODEL_CSS )
                                        || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ) );
@@ -1348,7 +1348,7 @@ class Title implements LinkTarget {
         * @deprecated Since 1.31; use ::isUserConfigPage() instead
         */
        public function isCssJsSubpage() {
-               // wfDeprecated( __METHOD__, '1.31' );
+               wfDeprecated( __METHOD__, '1.31' );
                return ( NS_USER == $this->mNamespace && $this->isSubpage()
                                && ( $this->hasContentModel( CONTENT_MODEL_CSS )
                                        || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ) );
@@ -1398,7 +1398,7 @@ class Title implements LinkTarget {
         * @return bool
         */
        public function isCssSubpage() {
-               // wfDeprecated( __METHOD__, '1.31' );
+               wfDeprecated( __METHOD__, '1.31' );
                return $this->isUserCssConfigPage();
        }
 
@@ -1417,11 +1417,11 @@ class Title implements LinkTarget {
        }
 
        /**
-        * @deprecated Since 1.31; use ::isUserCssConfigPage()
+        * @deprecated Since 1.31; use ::isUserJsConfigPage()
         * @return bool
         */
        public function isJsSubpage() {
-               // wfDeprecated( __METHOD__, '1.31' );
+               wfDeprecated( __METHOD__, '1.31' );
                return $this->isUserJsConfigPage();
        }
 
index 48516a7..d07df5a 100644 (file)
@@ -174,7 +174,7 @@ class ApiQueryContributors extends ApiQueryBase {
                        $this->addJoinConds( [ 'user_groups' => [
                                $excludeGroups ? 'LEFT OUTER JOIN' : 'INNER JOIN',
                                [
-                                       'ug_user=' . $actorQuery['fields']['rev_user'],
+                                       'ug_user=' . $revQuery['fields']['rev_user'],
                                        'ug_group' => $limitGroups,
                                        'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
                                ]
index bbee4fa..b2cb6f7 100644 (file)
@@ -22,7 +22,7 @@
                        "Tacsipacsi"
                ]
        },
-       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentation]]\n* [[mw:Special:MyLanguage/API:FAQ|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n</div>\n<strong>Status:</strong> Alle auf dieser Seite gezeigten Funktionen sollten funktionieren, allerdings ist die API in aktiver Entwicklung und kann sich zu jeder Zeit ändern. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste], um über Aktualisierungen informiert zu werden.\n\n<strong>Fehlerhafte Anfragen:</strong> Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Fehler und Warnungen]].\n\n<p class=\"mw-apisandbox-link\"><strong>Testen:</strong> Zum einfachen Testen von API-Anfragen, siehe [[Special:ApiSandbox]].</p>",
+       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentation]]\n* [[mw:Special:MyLanguage/API:FAQ|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n</div>\n<strong>Status:</strong> Die MediaWiki-API ist eine ausgereifte und stabile Schnittstelle, die aktiv unterstützt und verbessert wird. Während wir versuchen, dies zu vermeiden, können wir gelegentlich Breaking Changes erforderlich machen. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste] für Mitteilungen zu Aktualisierungen.\n\n<strong>Fehlerhafte Anfragen:</strong> Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Fehler und Warnungen]].\n\n<p class=\"mw-apisandbox-link\"><strong>Testen:</strong> Zum einfachen Testen von API-Anfragen, siehe [[Special:ApiSandbox]].</p>",
        "apihelp-main-param-action": "Auszuführende Aktion.",
        "apihelp-main-param-format": "Format der Ausgabe.",
        "apihelp-main-param-maxlag": "maxlag kann verwendet werden, wenn MediaWiki auf einem datenbankreplizierten Cluster installiert ist. Um weitere Replikationsrückstände zu verhindern, lässt dieser Parameter den Client warten, bis der Replikationsrückstand kleiner als der angegebene Wert (in Sekunden) ist. Bei einem größerem Rückstand wird der Fehlercode <samp>maxlag</samp> zurückgegeben mit einer Nachricht wie <samp>Waiting for $host: $lag seconds lagged</samp>.<br />Siehe [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Handbuch: Maxlag parameter]] für weitere Informationen.",
index 4c3b74d..daa88d5 100644 (file)
@@ -33,7 +33,7 @@
                        "Kenjiraw"
                ]
        },
-       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n</div>\n<strong>État :</strong> Toutes les fonctionnalités affichées sur cette page devraient fonctionner, mais l’API est encore en cours de développement et peut changer à tout moment. Inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion mediawiki-api-announce] pour être informé des mises à jour.\n\n<strong>Requêtes erronées :</strong> Si des requêtes erronées sont envoyées à l’API, un entête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet entête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n\n<p class=\"mw-apisandbox-link\"><strong>Test :</strong> Pour faciliter le test des requêtes de l’API, voyez [[Special:ApiSandbox]].</p>",
+       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n</div>\n<strong>État :</strong>L’API MédiaWiki est une interface stable et mature qui est supportée et améliorée de façon active. Bien que nous essayions de l’éviter, nous pouvons avoir parfois besoin de faire des modifications impactantes ; inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion mediawiki-api-announce] pour être informé des mises à jour.\n\n<strong>Requêtes erronées :</strong> Si des requêtes erronées sont envoyées à l’API, un entête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet entête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n\n<p class=\"mw-apisandbox-link\"><strong>Test :</strong> Pour faciliter le test des requêtes de l’API, voyez [[Special:ApiSandbox]].</p>",
        "apihelp-main-param-action": "Quelle action effectuer.",
        "apihelp-main-param-format": "Le format de sortie.",
        "apihelp-main-param-maxlag": "La latence maximale peut être utilisée quand MédiaWiki est installé sur un cluster de base de données répliqué. Pour éviter des actions provoquant un supplément de latence de réplication de site, ce paramètre peut faire attendre le client jusqu’à ce que la latence de réplication soit inférieure à une valeur spécifiée. En cas de latence excessive, le code d’erreur <samp>maxlag</samp> est renvoyé avec un message tel que <samp>Attente de $host : $lag secondes de délai</samp>.<br />Voyez [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manuel: Maxlag parameter]] pour plus d’information.",
index 66b0942..38d2901 100644 (file)
@@ -19,7 +19,7 @@
                        "Margherita.mignanelli"
                ]
        },
-       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentazione]] (in inglese)\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]] (in inglese)\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annunci sull'API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug & richieste]\n</div>\n<strong>Stato:</strong> tutte le funzioni e caratteristiche mostrate su questa pagina dovrebbero funzionare, ma le API sono ancora in fase attiva di sviluppo, e potrebbero cambiare in qualsiasi momento. Iscriviti alla [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la mailing list sugli annunci delle API MediaWiki] per essere informato sugli aggiornamenti.\n\n<strong>Istruzioni sbagliate:</strong> quando vengono impartite alle API delle istruzioni sbagliate, un'intestazione HTTP verrà inviata col messaggio \"MediaWiki-API-Error\" e, sia il valore dell'intestazione, sia il codice d'errore, verranno impostati con lo stesso valore. Per maggiori informazioni leggi [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Errori ed avvertimenti]] (in inglese).\n\n<p class=\"mw-apisandbox-link\"><strong>Test:</strong> per testare facilmente le richieste API, vedi [[Special:ApiSandbox]].</p>",
+       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentazione]] (in inglese)\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]] (in inglese)\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annunci sull'API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug & richieste]\n</div>\n<strong>Stato:</strong> l'API MediaWiki è un'interfaccia matura e stabile che è attivamente supportata e migliorata. Anche se cerchiamo di evitarlo, potremmo dover fare delle modifiche che causano malfunzionamenti; iscriviti alla [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mailing list sugli annunci delle API MediaWiki] per essere informato sugli aggiornamenti.\n\n<strong>Istruzioni sbagliate:</strong> quando vengono impartite alle API delle istruzioni sbagliate, un'intestazione HTTP verrà inviata col messaggio \"MediaWiki-API-Error\" e, sia il valore dell'intestazione, sia il codice d'errore, verranno impostati con lo stesso valore. Per maggiori informazioni leggi [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Errori ed avvertimenti]] (in inglese).\n\n<p class=\"mw-apisandbox-link\"><strong>Test:</strong> per testare facilmente le richieste API, vedi [[Special:ApiSandbox]].</p>",
        "apihelp-main-param-action": "Azione da compiere.",
        "apihelp-main-param-format": "Formato dell'output.",
        "apihelp-main-param-assert": "Verifica che l'utente abbia effettuato l'accesso se si è impostato <kbd>user</kbd>, o che abbia i permessi di bot se si è impostato <kbd>bot</kbd>.",
index f51b03f..80f161b 100644 (file)
@@ -12,7 +12,8 @@
                        "Suchichi02",
                        "Kkairri",
                        "ネイ",
-                       "Omotecho"
+                       "Omotecho",
+                       "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>",
@@ -35,7 +36,7 @@
        "apihelp-block-param-autoblock": "その利用者が最後に使用したIPアドレスと、ブロック後に編集を試みた際のIPアドレスを自動的にブロックします。",
        "apihelp-block-param-noemail": "Wikiを通して電子メールを送信することを禁止します。(<code>blockemail</code> 権限が必要です)",
        "apihelp-block-param-hidename": "ブロック記録から利用者名を秘匿します。(<code>hideuser</code> 権限が必要です)",
-       "apihelp-block-param-allowusertalk": "自身のトークページの編集を許可する (<var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> に依存)。",
+       "apihelp-block-param-allowusertalk": "自身のトークページの編集を許可する (<var>[[mw:Special:MyLanguage/Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> に依存)。",
        "apihelp-block-param-reblock": "その利用者がすでにブロックされている場合、ブロックを上書きします。",
        "apihelp-block-param-watchuser": "その利用者またはIPアドレスの利用者ページとトークページをウォッチします。",
        "apihelp-block-example-ip-simple": "IPアドレス <kbd>192.0.2.5</kbd> を <kbd>First strike<kbd> という理由で3日ブロックする",
        "apihelp-parse-paramvalue-prop-displaytitle": "構文解析されたウィキテキストのタイトルを追加します。",
        "apihelp-parse-paramvalue-prop-headitems": "ページの <code>&lt;head&gt;</code> の中に入れてアイテムを提供します。",
        "apihelp-parse-paramvalue-prop-headhtml": "ページの解析された <code>&lt;head&gt;</code> を与える。",
-       "apihelp-parse-paramvalue-prop-jsconfigvars": "ページに固有のJavaScriptの設定変数を提供します。",
+       "apihelp-parse-paramvalue-prop-jsconfigvars": "ページに固有のJavaScriptの設定変数を提供します。適用するには、<code>mw.config.set()</code>を使用します。",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "JSON文字列としてページに固有のJavaScriptの設定変数を提供します。",
        "apihelp-parse-paramvalue-prop-indicators": "ページ上で使用されるページのステータスインジケータのHTMLを提供します。",
        "apihelp-parse-paramvalue-prop-iwlinks": "構文解析されたウィキテキスト内でウィキ間リンクを提供します。",
index fec224e..a2a0e79 100644 (file)
@@ -17,7 +17,7 @@
                        "Hamilton Abreu"
                ]
        },
-       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentação]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discussão]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anúncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e pedidos]\n</div>\n<strong>Estado:</strong> Todas as funcionalidades mostradas nesta página devem ter o comportamento documentado, mas a API ainda está em desenvolvimento ativo e pode ser alterada a qualquer momento. Inscreva-se na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discussão mediawiki-api-announce] para ser informado acerca das atualizações.\n\n<strong>Pedidos incorretos:</strong> Quando são enviados pedidos incorretos à API, será devolvido um cabeçalho HTTP com a chave \"MediaWiki-API-Error\" e depois tanto o valor desse cabeçalho como o código de erro devolvido serão definidos com o mesmo valor. Para mais informação, consulte [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Erros e avisos]].\n\n<p class=\"mw-apisandbox-link\">\n<strong>Testes:</strong> Para testar facilmente pedidos à API, visite [[Special:ApiSandbox|Testes da API]].\n</p>",
+       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentação]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discussão]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anúncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e pedidos]\n</div>\n<strong>Estado:</strong> A API MediaWiki é uma interface madura e estável que é ativamente suportada e aprimorada. Enquanto tentamos evitá-lo, talvez ocortamente precisemos fazer mudanças de ruptura; se inscrever [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discussão mediawiki-api-announce] para ser informado acerca das atualizações.\n\n<strong>Pedidos incorretos:</strong> Quando são enviados pedidos incorretos à API, será devolvido um cabeçalho HTTP com a chave \"MediaWiki-API-Error\" e depois tanto o valor desse cabeçalho como o código de erro devolvido serão definidos com o mesmo valor. Para mais informação, consulte [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Erros e avisos]].\n\n<p class=\"mw-apisandbox-link\">\n<strong>Testes:</strong> Para testar facilmente pedidos à API, visite [[Special:ApiSandbox|Testes da API]].\n</p>",
        "apihelp-main-param-action": "Qual ação executar.",
        "apihelp-main-param-format": "O formato da saída.",
        "apihelp-main-param-maxlag": "O atraso máximo pode ser usado quando o MediaWiki está instalado em um cluster replicado no banco de dados. Para salvar as ações que causam mais atraso na replicação do site, esse parâmetro pode fazer o cliente aguardar até que o atraso da replicação seja menor do que o valor especificado. Em caso de atraso excessivo, o código de erro <samp>maxlag</samp> é retornado com uma mensagem como <samp>Waiting for $host: $lag seconds lagged</samp>.<br />Veja [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manual: Maxlag parameter]] para mais informações.",
index f69fb08..669a828 100644 (file)
@@ -12,7 +12,7 @@
                        "Waldir"
                ]
        },
-       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentação]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discussão]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anúncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e pedidos]\n</div>\n<strong>Estado:</strong> Todas as funcionalidades mostradas nesta página devem ter o comportamento documentado, mas a API ainda está em desenvolvimento ativo e pode ser alterada a qualquer momento. Inscreva-se na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discussão mediawiki-api-announce] para ser informado acerca das atualizações.\n\n<strong>Pedidos incorretos:</strong> Quando são enviados pedidos incorretos à API, será devolvido um cabeçalho HTTP com a chave \"MediaWiki-API-Error\" e depois tanto o valor desse cabeçalho como o código de erro devolvido serão definidos com o mesmo valor. Para mais informação, consulte [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Erros e avisos]].\n\n<p class=\"mw-apisandbox-link\">\n<strong>Testes:</strong> Para testar facilmente pedidos à API, visite [[Special:ApiSandbox|Testes da API]].\n</p>",
+       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Estado:</strong> A API do MediaWiki é uma interface consolidada e estável que é constantemente suportada e melhorada. Enbora tentemos evitá-lo, podemos ocasionalmente realizar alterações disruptivas. Inscreva-se na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de distribuição mediawiki-api-announce] para receber notificação das atualizações.\n\n<strong>Pedidos incorretos:</strong> Quando são enviados pedidos incorretos à API, será devolvido um cabeçalho HTTP com a chave \"MediaWiki-API-Error\" e depois tanto o valor desse cabeçalho como o código de erro devolvido serão definidos com o mesmo valor. Para mais informação, consulte [[mw:Special:MyLanguage/API:Errors_and_warnings|API:Erros e avisos]].\n\n<p class=\"mw-apisandbox-link\"><strong>Testes:</strong> Para testar facilmente pedidos à API, visite [[Special:ApiSandbox|Testes da API]].</p>",
        "apihelp-main-param-action": "A operação a ser realizada.",
        "apihelp-main-param-format": "O formato do resultado.",
        "apihelp-main-param-maxlag": "O atraso máximo pode ser usado quando o MediaWiki é instalado num ''cluster'' de bases de dados replicadas. Para impedir que as operações causem ainda mais atrasos de replicação do sítio, este parâmetro pode fazer o cliente aguardar até que o atraso de replicação seja inferior ao valor especificado. Caso o atraso atual exceda esse valor, o código de erro <samp>maxlag</samp> é devolvido com uma mensagem como <samp>À espera do servidor $host: $lag segundos de atraso</samp>.<br />Consulte [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manual: Parâmetro maxlag]] para mais informações.",
index 5eec830..461757d 100644 (file)
@@ -26,7 +26,7 @@
                        "NeverBehave"
                ]
        },
-       "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/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong>当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅[[mw:Special:MyLanguage/API:Errors_and_warnings|API:错误与警告]]。\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/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong>当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅[[mw:Special:MyLanguage/API:Errors_and_warnings|API:错误与警告]]。\n\n<p class=\"mw-apisandbox-link\"><strong>测试中:</strong>测试API请求的易用性,请参见[[Special:ApiSandbox]]。</p>",
        "apihelp-main-param-action": "要执行的操作。",
        "apihelp-main-param-format": "输出的格式。",
        "apihelp-main-param-maxlag": "最大延迟可被用于MediaWiki安装于数据库复制集中。要保存导致更多网站复制延迟的操作,此参数可使客户端等待直到复制延迟少于指定值时。万一发生过多延迟,错误代码<samp>maxlag</samp>会返回消息,例如<samp>等待$host中:延迟$lag秒</samp>。<br />参见[[mw:Special:MyLanguage/Manual:Maxlag_parameter|手册:Maxlag参数]]以获取更多信息。",
index 3811da3..7020159 100644 (file)
@@ -119,6 +119,11 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                return $this->procCache['config'][$name];
        }
 
+       public function getModifiedIndex() {
+               $this->load();
+               return $this->procCache['modifiedIndex'];
+       }
+
        /**
         * @throws ConfigException
         */
@@ -151,13 +156,17 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                                // refresh the cache from etcd, using a mutex to reduce stampedes...
                                if ( $this->srvCache->lock( $key, 0, $this->baseCacheTTL ) ) {
                                        try {
-                                               list( $config, $error, $retry ) = $this->fetchAllFromEtcd();
-                                               if ( is_array( $config ) ) {
+                                               $etcdResponse = $this->fetchAllFromEtcd();
+                                               $error = $etcdResponse['error'];
+                                               if ( is_array( $etcdResponse['config'] ) ) {
                                                        // Avoid having all servers expire cache keys at the same time
                                                        $expiry = microtime( true ) + $this->baseCacheTTL;
                                                        $expiry += mt_rand( 0, 1e6 ) / 1e6 * $this->skewCacheTTL;
-
-                                                       $data = [ 'config' => $config, 'expires' => $expiry ];
+                                                       $data = [
+                                                               'config' => $etcdResponse['config'],
+                                                               'expires' => $expiry,
+                                                               'modifiedIndex' => $etcdResponse['modifiedIndex']
+                                                       ];
                                                        $this->srvCache->set( $key, $data, BagOStuff::TTL_INDEFINITE );
 
                                                        $this->logger->info( "Refreshed stale etcd configuration cache." );
@@ -165,7 +174,7 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                                                        return WaitConditionLoop::CONDITION_REACHED;
                                                } else {
                                                        $this->logger->error( "Failed to fetch configuration: $error" );
-                                                       if ( !$retry ) {
+                                                       if ( !$etcdResponse['retry'] ) {
                                                                // Fail fast since the error is likely to keep happening
                                                                return WaitConditionLoop::CONDITION_FAILED;
                                                        }
@@ -195,9 +204,10 @@ class EtcdConfig implements Config, LoggerAwareInterface {
        }
 
        /**
-        * @return array (config array or null, error string, allow retries)
+        * @return array (containing the keys config, error, retry, modifiedIndex)
         */
        public function fetchAllFromEtcd() {
+               // TODO: inject DnsSrvDiscoverer in order to be able to test this method
                $dsd = new DnsSrvDiscoverer( $this->host );
                $servers = $dsd->getServers();
                if ( !$servers ) {
@@ -209,8 +219,8 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                        $server = $dsd->pickServer( $servers );
                        $host = IP::combineHostAndPort( $server['target'], $server['port'] );
                        // Try to load the config from this particular server
-                       list( $config, $error, $retry ) = $this->fetchAllFromEtcdServer( $host );
-                       if ( is_array( $config ) || !$retry ) {
+                       $response = $this->fetchAllFromEtcdServer( $host );
+                       if ( is_array( $response['config'] ) || $response['retry'] ) {
                                break;
                        }
 
@@ -218,12 +228,12 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                        $servers = $dsd->removeServer( $server, $servers );
                } while ( $servers );
 
-               return [ $config, $error, $retry ];
+               return $response;
        }
 
        /**
         * @param string $address Host and port
-        * @return array (config array or null, error string, whether to allow retries)
+        * @return array (containing the keys config, error, retry, modifiedIndex)
         */
        protected function fetchAllFromEtcdServer( $address ) {
                // Retrieve all the values under the MediaWiki config directory
@@ -233,19 +243,21 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                        'headers' => [ 'content-type' => 'application/json' ]
                ] );
 
+               $response = [ 'config' => null, 'error' => null, 'retry' => false, 'modifiedIndex' => 0 ];
+
                static $terminalCodes = [ 404 => true ];
                if ( $rcode < 200 || $rcode > 399 ) {
-                       return [
-                               null,
-                               strlen( $rerr ) ? $rerr : "HTTP $rcode ($rdesc)",
-                               empty( $terminalCodes[$rcode] )
-                       ];
+                       $response['error'] = strlen( $rerr ) ? $rerr : "HTTP $rcode ($rdesc)";
+                       $response['retry'] = empty( $terminalCodes[$rcode] );
+                       return $response;
                }
+
                try {
-                       return [ $this->parseResponse( $rbody ), null, false ];
+                       $parsedResponse = $this->parseResponse( $rbody );
                } catch ( EtcdConfigParseError $e ) {
-                       return [ null, $e->getMessage(), false ];
+                       $parsedResponse = [ 'error' => $e->getMessage() ];
                }
+               return array_merge( $response, $parsedResponse );
        }
 
        /**
@@ -264,8 +276,8 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                                "Unexpected JSON response: Missing or invalid node at top level." );
                }
                $config = [];
-               $this->parseDirectory( '', $info['node'], $config );
-               return $config;
+               $lastModifiedIndex = $this->parseDirectory( '', $info['node'], $config );
+               return [ 'modifiedIndex' => $lastModifiedIndex, 'config' => $config ];
        }
 
        /**
@@ -275,8 +287,10 @@ class EtcdConfig implements Config, LoggerAwareInterface {
         * @param string $dirName The relative directory name
         * @param array $dirNode The decoded directory node
         * @param array &$config The output array
+        * @return int lastModifiedIndex The maximum last modified index across all keys in the directory
         */
        protected function parseDirectory( $dirName, $dirNode, &$config ) {
+               $lastModifiedIndex = 0;
                if ( !isset( $dirNode['nodes'] ) ) {
                        throw new EtcdConfigParseError(
                                "Unexpected JSON response in dir '$dirName'; missing 'nodes' list." );
@@ -290,16 +304,19 @@ class EtcdConfig implements Config, LoggerAwareInterface {
                        $baseName = basename( $node['key'] );
                        $fullName = $dirName === '' ? $baseName : "$dirName/$baseName";
                        if ( !empty( $node['dir'] ) ) {
-                               $this->parseDirectory( $fullName, $node, $config );
+                               $lastModifiedIndex = max(
+                                       $this->parseDirectory( $fullName, $node, $config ),
+                                       $lastModifiedIndex );
                        } else {
                                $value = $this->unserialize( $node['value'] );
                                if ( !is_array( $value ) || !array_key_exists( 'val', $value ) ) {
                                        throw new EtcdConfigParseError( "Failed to parse value for '$fullName'." );
                                }
-
+                               $lastModifiedIndex = max( $node['modifiedIndex'], $lastModifiedIndex );
                                $config[$fullName] = $value['val'];
                        }
                }
+               return $lastModifiedIndex;
        }
 
        /**
index bc20aa0..5beef31 100644 (file)
@@ -270,28 +270,22 @@ class WikitextContent extends TextContent {
                        return false;
                }
 
-               switch ( $wgArticleCountMethod ) {
-                       case 'any':
-                               return true;
-                       case 'comma':
-                               $text = $this->getNativeData();
-                               return strpos( $text, ',' ) !== false;
-                       case 'link':
-                               if ( $hasLinks === null ) { # not known, find out
-                                       if ( !$title ) {
-                                               $context = RequestContext::getMain();
-                                               $title = $context->getTitle();
-                                       }
-
-                                       $po = $this->getParserOutput( $title, null, null, false );
-                                       $links = $po->getLinks();
-                                       $hasLinks = !empty( $links );
+               if ( $wgArticleCountMethod === 'link' ) {
+                       if ( $hasLinks === null ) { # not known, find out
+                               if ( !$title ) {
+                                       $context = RequestContext::getMain();
+                                       $title = $context->getTitle();
                                }
 
-                               return $hasLinks;
+                               $po = $this->getParserOutput( $title, null, null, false );
+                               $links = $po->getLinks();
+                               $hasLinks = !empty( $links );
+                       }
+
+                       return $hasLinks;
                }
 
-               return false;
+               return true;
        }
 
        /**
index fa30d68..037a80f 100644 (file)
@@ -1294,7 +1294,7 @@ class DifferenceEngine extends ContextSource {
 
                if ( !$diff && !$otitle ) {
                        $header .= "
-                       <tr style=\"vertical-align: top;\" lang=\"{$userLang}\">
+                       <tr class=\"diff-title\" lang=\"{$userLang}\">
                        <td class=\"diff-ntitle\">{$ntitle}</td>
                        </tr>";
                        $multiColspan = 1;
@@ -1313,7 +1313,7 @@ class DifferenceEngine extends ContextSource {
                        }
                        if ( $otitle || $ntitle ) {
                                $header .= "
-                               <tr style=\"vertical-align: top;\" lang=\"{$userLang}\">
+                               <tr class=\"diff-title\" lang=\"{$userLang}\">
                                <td colspan=\"$colspan\" class=\"diff-otitle\">{$otitle}</td>
                                <td colspan=\"$colspan\" class=\"diff-ntitle\">{$ntitle}</td>
                                </tr>";
@@ -1321,12 +1321,12 @@ class DifferenceEngine extends ContextSource {
                }
 
                if ( $multi != '' ) {
-                       $header .= "<tr><td colspan=\"{$multiColspan}\" style=\"text-align: center;\" " .
+                       $header .= "<tr><td colspan=\"{$multiColspan}\" " .
                                "class=\"diff-multi\" lang=\"{$userLang}\">{$multi}</td></tr>";
                }
                if ( $notice != '' ) {
-                       $header .= "<tr><td colspan=\"{$multiColspan}\" style=\"text-align: center;\" " .
-                               "lang=\"{$userLang}\">{$notice}</td></tr>";
+                       $header .= "<tr><td colspan=\"{$multiColspan}\" " .
+                               "class=\"diff-notice\" lang=\"{$userLang}\">{$notice}</td></tr>";
                }
 
                return $header . $diff . "</table>";
index 500bc5a..0d55454 100644 (file)
@@ -1047,7 +1047,7 @@ abstract class DatabaseUpdater {
         * Sets the number of active users in the site_stats table
         */
        protected function doActiveUsersInit() {
-               $activeUsers = $this->db->selectField( 'site_stats', 'ss_active_users', false, __METHOD__ );
+               $activeUsers = $this->db->selectField( 'site_stats', 'ss_active_users', '', __METHOD__ );
                if ( $activeUsers == -1 ) {
                        $activeUsers = $this->db->selectField( 'recentchanges',
                                'COUNT( DISTINCT rc_user_text )',
@@ -1227,7 +1227,7 @@ abstract class DatabaseUpdater {
                                "maintenance/migrateComments.php.\n"
                        );
                        $task = $this->maintenance->runChild( MigrateComments::class, 'migrateComments.php' );
-                       $task->execute();
+                       $ok = $task->execute();
                        $this->output( $ok ? "done.\n" : "errors were encountered.\n" );
                }
        }
index aff2fd3..d75b063 100644 (file)
@@ -74,7 +74,7 @@
        "config-apc": "[http://www.php.net/apc APC] نصب شده‌است.",
        "config-apcu": "[http://www.php.net/apcu APCu] نصب شده‌است",
        "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] نصب شده‌است.",
-       "config-no-cache-apcu": "<strong>هشدار:</strong> پیوند [http://www.php.net/apcu APCu]، [http://xcache.lighttpd.net/ XCache] یا [http://www.iis.net/download/WinCacheForPhp WinCache] یافت نشد. ذخیره شی فعال نیست.",
+       "config-no-cache-apcu": "<strong>هشدار:</strong> پیوند [http://www.php.net/apcu APCu] یا [http://www.iis.net/download/WinCacheForPhp WinCache] یافت نشد. ذخیره شی فعال نیست.",
        "config-mod-security": "'''هشدار:''' وب سرور شما [https://modsecurity.org/ mod_security] فعال است.اگر اشتباه پیکربندی شده‌‌ باشد،می تواند باعث ایجاد مشکلاتی برای مدیاویکی یا دیگر نرم‌افزاری شود که به کاربران اجازه می‌دهد پیام دلخواه ارسال کنند.\nبه [https://modsecurity.org/documentation/ mod_security documentation] مراجعه کنید یا اگر با خطاهای اتفاقی مواجه شدید با پشتیبانی میزبان خود در تماس باشید.",
        "config-diff3-bad": "جی‌ان‌یو دیف۳ پیدا نشد.",
        "config-git": "کنترل نسخهٔ نرم‌افزار گیت پیدا شد: <code>$1</code>.",
        "config-cache-options": "تنظیمات برای ذخیره شی:",
        "config-cache-help": "کش شی برای بهتر شدن سرعت مدیا ویکی، از طریق کش کردن داده‌های با بیشترین استفاده انجام می‌گیرد.\nوبگاه‌های متوسط تا بزرگ به انجام این کار شدیدا توصیه می‌شوند، در عین حال وبگاه‌های کوچک نیز می‌توانند از مزایای ایم مورد بهره ببرند.",
        "config-cache-none": "بدون ذخیره (هیچ کارآمدی پاک نشده‌است، اما ممکن است سرعت در سایت‌های بزرگتر ویکی تأثیر داشته باشد)",
-       "config-cache-accel": "کاشهٔ اشیای پی‌اچ‌پی (APC یا APCu یا XCache یا WinCahe)",
+       "config-cache-accel": "کاشهٔ اشیای پی‌اچ‌پی (APC یا APCu یا WinCahe)",
        "config-cache-memcached": "از ممکچد (که نیازمند تنظیمات اضافی و پیکربندی) استفاده کنید",
        "config-memcached-servers": "سرورهای دریافت حافظه:",
        "config-memcached-help": "فهرست آدرس‌های آی‌پی برای استفاده از ممکچد.\nباید هر یک خط را تعیین کند و درگاه مورد استفاده را تعیین کند.برای مثال: \n۱۲۷.۰.۰.۱:۱۱۲۱۱\n۱۹۲.۱۶۸.۱.۲۵:۱۲۳۴",
index ec3c782..d388a59 100644 (file)
@@ -69,7 +69,7 @@
        "config-apc": "[http://www.php.net/apc APC] מותקן",
        "config-apcu": "[http://www.php.net/apcu APCu] מותקן",
        "config-wincache": "[https://www.iis.net/download/WinCacheForPhp WinCache] מותקן",
-       "config-no-cache-apcu": "<strong>אזהרה:</strong> לא נמצא [http://www.php.net/apcu APCu]‏, [http://xcache.lighttpd.net/ XCache] או [http://www.iis.net/download/WinCacheForPhp WinCache].\nמטמון עצמים לא מופעל.",
+       "config-no-cache-apcu": "<strong>אזהרה:</strong> לא נמצא [http://www.php.net/apcu APCu]‏ או [http://www.iis.net/download/WinCacheForPhp WinCache].\nמטמון עצמים לא מופעל.",
        "config-mod-security": "'''אזהרה''': בשרת הווב שלך מופעל [https://modsecurity.org/ mod_security]. אם הוא לא מוגדר טוב, זה יכול לגרום לבעיות במדיה־ויקי ובתכנה אחרת שמאפשרת למשתמשים לשלוח תוכן שרירותי.\nיש לקרוא את [https://modsecurity.org/documentation/ התיעוד של mod_security] או ליצור קשר עם אנשי התמיכה של שירותי האירוח שלכם אם מופיעות לך שגיאות אקראיות.",
        "config-diff3-bad": "GNU diff3 לא נמצא.",
        "config-git": "נמצאה Git, תכנת בקרת התצורה: <code dir=\"ltr\">$1</code>.",
        "config-cache-options": "הגדרות למטמון עצמים (object caching):",
        "config-cache-help": "מטמון עצמים משמש לשיפור המהירות של מדיה־ויקי על־ידי שמירה של נתונים שהשימוש בהם נפוץ במטמון.\nלאתרים בינוניים וגדולים כדאי מאוד להפעיל את זה, וגם אתרים קטנים ייהנו מזה.",
        "config-cache-none": "ללא מטמון (שום יכולת אינה מוּסרת, אבל הביצועים באתרים גדולים ייפגעו)",
-       "config-cache-accel": "מטמון עצמים (object caching) של PHP&rlm; (APC,&rlm; APCu,&rlm; XCache או WinCache)",
+       "config-cache-accel": "מטמון עצמים (object caching) של PHP&rlm; (APC,&rlm; APCu,&rlm; או WinCache)",
        "config-cache-memcached": "להשתמש ב־Memcached (דורש התקנות והגדרות נוספות)",
        "config-memcached-servers": "שרתי Memcached:",
        "config-memcached-help": "רשימת כתובות IP ש־Memcached ישתמש בהן.\nיש לרשום כתובת אחת בכל שורה ולציין את הפִּתְחָה (port), למשל:\n 127.0.0.1:11211\n 192.168.1.25:1234",
index 5d20ead..abf60b2 100644 (file)
@@ -13,7 +13,9 @@
        "config-desc": "Инсталација за Медијавики",
        "config-title": "Инсталација Медијавикија $1",
        "config-information": "Информација",
+       "config-localsettings-upgrade": "Откривена је датотека <code>LocalSettings.php</code>.\nДа бисте надоградили инсталацију, унесите вредности од <code>$wgUpgradeKey</code> у оквиру испод.\nНаћи ћете га у <code>LocalSettings.php</code>.",
        "config-localsettings-key": "Кључ за уградњу:",
+       "config-localsettings-badkey": "Наведени кључ за надоградњу је неисправан.",
        "config-session-error": "Грешка при започињању сесије: $1",
        "config-session-expired": "Ваши подаци о сесији су истекли.\nСесије су подешене да трају $1.\nЊихов рок можете повећати постављањем <code>session.gc_maxlifetime</code> у php.ini.\nПоново покрените инсталацију.",
        "config-no-session": "Ваши подаци о сесији су изгубљени!\nПроверите Ваш php.ini и обезбедите да је <code>session.save_path</code> постављен на одговарајући директоријум.",
@@ -40,6 +42,8 @@
        "config-page-existingwiki": "Постојећи вики",
        "config-help-restart": "Желите ли да обришете све сачуване податке које сте унели и поново покренете инсталацију?",
        "config-restart": "Да, покрени поново",
+       "config-env-good": "Окружење је проверено.\nМожете инсталирати Медијавики.",
+       "config-env-bad": "Окружење је проверено.\nНе можете инсталирати Медијавики.",
        "config-env-php": "PHP $1 је инсталиран.",
        "config-env-hhvm": "HHVM $1 је инсталиран.",
        "config-apc": "[http://www.php.net/apc APC] је инсталиран",
        "config-mssql-sqlauth": "Провера идентитета SQL Server-а",
        "config-mssql-windowsauth": "Провера идентитета Виндоуса",
        "config-site-name": "Име викија:",
+       "config-site-name-blank": "Унесите име сајта.",
+       "config-project-namespace": "Именски простор пројекта:",
+       "config-ns-generic": "Пројекат",
+       "config-ns-site-name": "Исти као име викија: $1",
+       "config-ns-other": "Друго (наведите)",
+       "config-ns-other-default": "MyWiki",
+       "config-admin-box": "Налог администратора",
        "config-admin-name": "Ваше корисничко име:",
        "config-admin-password": "Лозинка:",
+       "config-admin-password-confirm": "Поново унесите лозинку:",
+       "config-admin-help": "Овде упишите жељено корисничко име; на пример, „Јован Крстић“.\nОво име ћете користити за пријаву на вики.",
+       "config-admin-name-blank": "Унесите корисничко име администратора.",
+       "config-admin-password-blank": "Унесите лозинку за налог администратора.",
+       "config-admin-password-mismatch": "Лозинке које сте унели се не поклапају.",
        "config-admin-email": "Имејл адреса:",
+       "config-admin-error-bademail": "Унели сте неисправну имејл адресу.",
        "config-optional-skip": "Досадно ми је, само инсталирај вики.",
+       "config-profile-wiki": "Отворен вики",
        "config-profile-no-anon": "Неопходно је отворити налог",
        "config-profile-fishbowl": "Само овлашћени корисници",
        "config-profile-private": "Приватна вики",
        "config-license-gfdl": "ГНУ-ова лиценца за слободну документацију издање 1.3 или новије",
        "config-license-pd": "Јавно власништво",
        "config-email-settings": "Подешавања имејла",
+       "config-enable-email": "Омогући одлазни имејл",
+       "config-upload-settings": "Отпремања слика и датотека",
+       "config-upload-enable": "Омогући отпремање датотека",
+       "config-upload-deleted": "Фасцикла за обрисане датотеке:",
+       "config-logo": "URL логотипа:",
+       "config-instantcommons": "Омогући Instant Commons",
+       "config-cc-again": "Изаберите поново...",
        "config-cc-not-chosen": "Одаберите која Кријејтив комонс лиценца вам одговара и потврдите.",
+       "config-advanced-settings": "Напредна конфигурација",
+       "config-memcached-servers": "Memcached сервери:",
+       "config-extensions": "Екстензије",
        "config-skins": "Теме",
+       "config-skins-use-as-default": "Користи ову тему као подразумевану",
+       "config-skins-must-enable-some": "Морате изабрати барем једну тему.",
        "config-install-step-done": "готово",
        "config-install-step-failed": "није успело",
        "config-install-extensions": "Обухвата екстензије",
        "config-install-schema": "Прављење шеме",
        "config-install-tables": "Прављење табела",
+       "config-install-stats": "Покрећем статистику",
        "config-install-keys": "Генеришем тајне кључеве",
+       "config-install-sysop": "Правим кориснички налог администратора",
+       "config-install-subscribe-fail": "Не могу да Вас претплатим на mediawiki-announce: $1",
+       "config-install-mainpage": "Правим главну страну са стандардним садржајем",
        "config-install-mainpage-exists": "Главна страна већ постоји, прескакање",
        "config-install-mainpage-failed": "Не могу да убацим главну страну: „$1”",
        "config-download-localsettings": "Преузми <code>LocalSettings.php</code>",
index 4e3409a..01f467f 100644 (file)
@@ -27,6 +27,11 @@ class JobQueueSecondTestQueue extends JobQueue {
         */
        private $debugQueue;
 
+       /**
+        * @var bool
+        */
+       private $onlyWriteToDebugQueue;
+
        protected function __construct( array $params ) {
                if ( !isset( $params['mainqueue'] ) ) {
                        throw new MWException( "mainqueue parameter must be provided to the debug queue" );
@@ -39,6 +44,7 @@ class JobQueueSecondTestQueue extends JobQueue {
                $conf = [ 'wiki' => $params['wiki'], 'type' => $params['type'] ];
                $this->mainQueue = JobQueue::factory( $params['mainqueue'] + $conf );
                $this->debugQueue = JobQueue::factory( $params['debugqueue'] + $conf );
+               $this->onlyWriteToDebugQueue = isset( $params['readonly'] ) ? $params['readonly'] : false;
 
                // We need to construct parent after creating the main and debug queue
                // because super constructor calls some methods we delegate to the main queue.
@@ -118,7 +124,9 @@ class JobQueueSecondTestQueue extends JobQueue {
         * @param int $flags
         */
        protected function doBatchPush( array $jobs, $flags ) {
-               $this->mainQueue->doBatchPush( $jobs, $flags );
+               if ( !$this->onlyWriteToDebugQueue ) {
+                       $this->mainQueue->doBatchPush( $jobs, $flags );
+               }
 
                try {
                        $this->debugQueue->doBatchPush( $jobs, $flags );
index df28f93..8ccccc3 100644 (file)
@@ -27,6 +27,7 @@ namespace Wikimedia\Rdbms;
 
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
 use Wikimedia\ScopedCallback;
 use Wikimedia\Timestamp\ConvertibleTimestamp;
 use Wikimedia;
@@ -58,6 +59,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        const SLOW_WRITE_SEC = 0.500;
        const SMALL_WRITE_ROWS = 100;
 
+       /** @var string Whether lock granularity is on the level of the entire database */
+       const ATTR_DB_LEVEL_LOCKING = 'db-level-locking';
+
        /** @var string SQL query */
        protected $lastQuery = '';
        /** @var float|bool UNIX timestamp of last write query */
@@ -306,7 +310,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         *
         * This also connects to the database immediately upon object construction
         *
-        * @param string $dbType A possible DB type (sqlite, mysql, postgres)
+        * @param string $dbType A possible DB type (sqlite, mysql, postgres,...)
         * @param array $p Parameter map with keys:
         *   - host : The hostname of the DB server
         *   - user : The name of the database user the client operates under
@@ -344,6 +348,68 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @since 1.18
         */
        final public static function factory( $dbType, $p = [] ) {
+               $class = self::getClass( $dbType, isset( $p['driver'] ) ? $p['driver'] : null );
+
+               if ( class_exists( $class ) && is_subclass_of( $class, IDatabase::class ) ) {
+                       // Resolve some defaults for b/c
+                       $p['host'] = isset( $p['host'] ) ? $p['host'] : false;
+                       $p['user'] = isset( $p['user'] ) ? $p['user'] : false;
+                       $p['password'] = isset( $p['password'] ) ? $p['password'] : false;
+                       $p['dbname'] = isset( $p['dbname'] ) ? $p['dbname'] : false;
+                       $p['flags'] = isset( $p['flags'] ) ? $p['flags'] : 0;
+                       $p['variables'] = isset( $p['variables'] ) ? $p['variables'] : [];
+                       $p['tablePrefix'] = isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : '';
+                       $p['schema'] = isset( $p['schema'] ) ? $p['schema'] : '';
+                       $p['cliMode'] = isset( $p['cliMode'] )
+                               ? $p['cliMode']
+                               : ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
+                       $p['agent'] = isset( $p['agent'] ) ? $p['agent'] : '';
+                       if ( !isset( $p['connLogger'] ) ) {
+                               $p['connLogger'] = new NullLogger();
+                       }
+                       if ( !isset( $p['queryLogger'] ) ) {
+                               $p['queryLogger'] = new NullLogger();
+                       }
+                       $p['profiler'] = isset( $p['profiler'] ) ? $p['profiler'] : null;
+                       if ( !isset( $p['trxProfiler'] ) ) {
+                               $p['trxProfiler'] = new TransactionProfiler();
+                       }
+                       if ( !isset( $p['errorLogger'] ) ) {
+                               $p['errorLogger'] = function ( Exception $e ) {
+                                       trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
+                               };
+                       }
+
+                       $conn = new $class( $p );
+               } else {
+                       $conn = null;
+               }
+
+               return $conn;
+       }
+
+       /**
+        * @param string $dbType A possible DB type (sqlite, mysql, postgres,...)
+        * @param string|null $driver Optional name of a specific DB client driver
+        * @return array Map of (Database::ATTRIBUTE_* constant => value) for all such constants
+        * @throws InvalidArgumentException
+        * @since 1.31
+        */
+       final public static function attributesFromType( $dbType, $driver = null ) {
+               static $defaults = [ self::ATTR_DB_LEVEL_LOCKING => false ];
+
+               $class = self::getClass( $dbType, $driver );
+
+               return call_user_func( [ $class, 'getAttributes' ] ) + $defaults;
+       }
+
+       /**
+        * @param string $dbType A possible DB type (sqlite, mysql, postgres,...)
+        * @param string|null $driver Optional name of a specific DB client driver
+        * @return string Database subclass name to use
+        * @throws InvalidArgumentException
+        */
+       private static function getClass( $dbType, $driver = null ) {
                // For database types with built-in support, the below maps type to IDatabase
                // implementations. For types with multipe driver implementations (PHP extensions),
                // an array can be used, keyed by extension name. In case of an array, the
@@ -359,17 +425,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                $dbType = strtolower( $dbType );
                $class = false;
+
                if ( isset( $builtinTypes[$dbType] ) ) {
                        $possibleDrivers = $builtinTypes[$dbType];
                        if ( is_string( $possibleDrivers ) ) {
                                $class = $possibleDrivers;
                        } else {
-                               if ( !empty( $p['driver'] ) ) {
-                                       if ( !isset( $possibleDrivers[$p['driver']] ) ) {
+                               if ( (string)$driver !== '' ) {
+                                       if ( !isset( $possibleDrivers[$driver] ) ) {
                                                throw new InvalidArgumentException( __METHOD__ .
-                                                       " type '$dbType' does not support driver '{$p['driver']}'" );
+                                                       " type '$dbType' does not support driver '{$driver}'" );
                                        } else {
-                                               $class = $possibleDrivers[$p['driver']];
+                                               $class = $possibleDrivers[$driver];
                                        }
                                } else {
                                        foreach ( $possibleDrivers as $posDriver => $possibleClass ) {
@@ -389,42 +456,15 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                " no viable database extension found for type '$dbType'" );
                }
 
-               if ( class_exists( $class ) && is_subclass_of( $class, IDatabase::class ) ) {
-                       // Resolve some defaults for b/c
-                       $p['host'] = isset( $p['host'] ) ? $p['host'] : false;
-                       $p['user'] = isset( $p['user'] ) ? $p['user'] : false;
-                       $p['password'] = isset( $p['password'] ) ? $p['password'] : false;
-                       $p['dbname'] = isset( $p['dbname'] ) ? $p['dbname'] : false;
-                       $p['flags'] = isset( $p['flags'] ) ? $p['flags'] : 0;
-                       $p['variables'] = isset( $p['variables'] ) ? $p['variables'] : [];
-                       $p['tablePrefix'] = isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : '';
-                       $p['schema'] = isset( $p['schema'] ) ? $p['schema'] : '';
-                       $p['cliMode'] = isset( $p['cliMode'] )
-                               ? $p['cliMode']
-                               : ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' );
-                       $p['agent'] = isset( $p['agent'] ) ? $p['agent'] : '';
-                       if ( !isset( $p['connLogger'] ) ) {
-                               $p['connLogger'] = new \Psr\Log\NullLogger();
-                       }
-                       if ( !isset( $p['queryLogger'] ) ) {
-                               $p['queryLogger'] = new \Psr\Log\NullLogger();
-                       }
-                       $p['profiler'] = isset( $p['profiler'] ) ? $p['profiler'] : null;
-                       if ( !isset( $p['trxProfiler'] ) ) {
-                               $p['trxProfiler'] = new TransactionProfiler();
-                       }
-                       if ( !isset( $p['errorLogger'] ) ) {
-                               $p['errorLogger'] = function ( Exception $e ) {
-                                       trigger_error( get_class( $e ) . ': ' . $e->getMessage(), E_USER_WARNING );
-                               };
-                       }
-
-                       $conn = new $class( $p );
-               } else {
-                       $conn = null;
-               }
+               return $class;
+       }
 
-               return $conn;
+       /**
+        * @return array Map of (Database::ATTRIBUTE_* constant => value
+        * @since 1.31
+        */
+       protected static function getAttributes() {
+               return [];
        }
 
        /**
@@ -1421,14 +1461,27 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                list( $startOpts, $useIndex, $preLimitTail, $postLimitTail, $ignoreIndex ) =
                        $this->makeSelectOptions( $options );
 
-               if ( !empty( $conds ) ) {
-                       if ( is_array( $conds ) ) {
-                               $conds = $this->makeList( $conds, self::LIST_AND );
-                       }
+               if ( is_array( $conds ) ) {
+                       $conds = $this->makeList( $conds, self::LIST_AND );
+               }
+
+               if ( $conds === null || $conds === false ) {
+                       $this->queryLogger->warning(
+                               __METHOD__
+                               . ' called from '
+                               . $fname
+                               . ' with incorrect parameters: $conds must be a string or an array'
+                       );
+                       $conds = '';
+               }
+
+               if ( $conds === '' ) {
+                       $sql = "SELECT $startOpts $vars $from $useIndex $ignoreIndex $preLimitTail";
+               } elseif ( is_string( $conds ) ) {
                        $sql = "SELECT $startOpts $vars $from $useIndex $ignoreIndex " .
                                "WHERE $conds $preLimitTail";
                } else {
-                       $sql = "SELECT $startOpts $vars $from $useIndex $ignoreIndex $preLimitTail";
+                       throw new DBUnexpectedError( $this, __METHOD__ . ' called with incorrect parameters' );
                }
 
                if ( isset( $options['LIMIT'] ) ) {
@@ -2105,8 +2158,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                // We can't separate explicit JOIN clauses with ',', use ' ' for those
-               $implicitJoins = !empty( $ret ) ? implode( ',', $ret ) : "";
-               $explicitJoins = !empty( $retJOIN ) ? implode( ' ', $retJOIN ) : "";
+               $implicitJoins = $ret ? implode( ',', $ret ) : "";
+               $explicitJoins = $retJOIN ? implode( ' ', $retJOIN ) : "";
 
                // Compile our final table clause
                return implode( ' ', [ $implicitJoins, $explicitJoins ] );
@@ -2252,11 +2305,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $rows = [ $rows ];
                }
 
-               $useTrx = !$this->trxLevel;
-               if ( $useTrx ) {
-                       $this->begin( $fname, self::TRANSACTION_INTERNAL );
-               }
                try {
+                       $this->startAtomic( $fname );
                        $affectedRowCount = 0;
                        foreach ( $rows as $row ) {
                                // Delete rows which collide with this one
@@ -2289,17 +2339,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                $this->insert( $table, $row, $fname );
                                $affectedRowCount += $this->affectedRows();
                        }
+                       $this->endAtomic( $fname );
+                       $this->affectedRowCount = $affectedRowCount;
                } catch ( Exception $e ) {
-                       if ( $useTrx ) {
-                               $this->rollback( $fname, self::FLUSHING_INTERNAL );
-                       }
+                       $this->rollback( $fname, self::FLUSHING_INTERNAL );
                        throw $e;
                }
-               if ( $useTrx ) {
-                       $this->commit( $fname, self::FLUSHING_INTERNAL );
-               }
-
-               $this->affectedRowCount = $affectedRowCount;
        }
 
        /**
@@ -2365,11 +2410,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                $affectedRowCount = 0;
-               $useTrx = !$this->trxLevel;
-               if ( $useTrx ) {
-                       $this->begin( $fname, self::TRANSACTION_INTERNAL );
-               }
                try {
+                       $this->startAtomic( $fname );
                        # Update any existing conflicting row(s)
                        if ( $where !== false ) {
                                $ok = $this->update( $table, $set, $where, $fname );
@@ -2380,16 +2422,12 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        # Now insert any non-conflicting row(s)
                        $ok = $this->insert( $table, $rows, $fname, [ 'IGNORE' ] ) && $ok;
                        $affectedRowCount += $this->affectedRows();
+                       $this->endAtomic( $fname );
+                       $this->affectedRowCount = $affectedRowCount;
                } catch ( Exception $e ) {
-                       if ( $useTrx ) {
-                               $this->rollback( $fname, self::FLUSHING_INTERNAL );
-                       }
+                       $this->rollback( $fname, self::FLUSHING_INTERNAL );
                        throw $e;
                }
-               if ( $useTrx ) {
-                       $this->commit( $fname, self::FLUSHING_INTERNAL );
-               }
-               $this->affectedRowCount = $affectedRowCount;
 
                return $ok;
        }
@@ -2447,11 +2485,16 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return $this->query( $sql, $fname );
        }
 
-       public function insertSelect(
+       final public function insertSelect(
                $destTable, $srcTable, $varMap, $conds,
                $fname = __METHOD__, $insertOptions = [], $selectOptions = [], $selectJoinConds = []
        ) {
-               if ( $this->cliMode ) {
+               static $hints = [ 'NO_AUTO_COLUMNS' ];
+
+               $insertOptions = (array)$insertOptions;
+               $selectOptions = (array)$selectOptions;
+
+               if ( $this->cliMode && $this->isInsertSelectSafe( $insertOptions, $selectOptions ) ) {
                        // For massive migrations with downtime, we don't want to select everything
                        // into memory and OOM, so do all this native on the server side if possible.
                        return $this->nativeInsertSelect(
@@ -2460,7 +2503,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                $varMap,
                                $conds,
                                $fname,
-                               $insertOptions,
+                               array_diff( $insertOptions, $hints ),
                                $selectOptions,
                                $selectJoinConds
                        );
@@ -2472,12 +2515,22 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $varMap,
                        $conds,
                        $fname,
-                       $insertOptions,
+                       array_diff( $insertOptions, $hints ),
                        $selectOptions,
                        $selectJoinConds
                );
        }
 
+       /**
+        * @param array $insertOptions INSERT options
+        * @param array $selectOptions SELECT options
+        * @return bool Whether an INSERT SELECT with these options will be replication safe
+        * @since 1.31
+        */
+       protected function isInsertSelectSafe( array $insertOptions, array $selectOptions ) {
+               return true;
+       }
+
        /**
         * Implementation of insertSelect() based on select() and insert()
         *
@@ -2497,8 +2550,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $fname = __METHOD__,
                $insertOptions = [], $selectOptions = [], $selectJoinConds = []
        ) {
-               $insertOptions = array_diff( (array)$insertOptions, [ 'NO_AUTO_COLUMNS' ] );
-
                // For web requests, do a locking SELECT and then INSERT. This puts the SELECT burden
                // on only the master (without needing row-based-replication). It also makes it easy to
                // know how big the INSERT is going to be.
@@ -2543,12 +2594,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                $this->affectedRowCount = $affectedRowCount;
                        } else {
                                $this->rollback( $fname, self::FLUSHING_INTERNAL );
-                               $this->affectedRowCount = 0;
                        }
                        return $ok;
                } catch ( Exception $e ) {
                        $this->rollback( $fname, self::FLUSHING_INTERNAL );
-                       $this->affectedRowCount = 0;
                        throw $e;
                }
        }
@@ -2577,7 +2626,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( !is_array( $insertOptions ) ) {
                        $insertOptions = [ $insertOptions ];
                }
-               $insertOptions = array_diff( (array)$insertOptions, [ 'NO_AUTO_COLUMNS' ] );
 
                $insertOptions = $this->makeInsertOptions( $insertOptions );
 
@@ -3180,6 +3228,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                } catch ( Exception $e ) {
                        // already logged; let LoadBalancer move on during mass-rollback
                }
+
+               $this->affectedRowCount = 0; // for the sake of consistency
        }
 
        /**
index b1c8909..771e2e5 100644 (file)
@@ -569,7 +569,7 @@ class DatabaseMssql extends Database {
                        }
                }
 
-               return empty( $result ) ? false : $result;
+               return $result ?: false;
        }
 
        /**
index 454e0c2..a5220b9 100644 (file)
@@ -67,6 +67,8 @@ abstract class DatabaseMysqlBase extends Database {
        private $serverVersion = null;
        /** @var bool|null */
        private $insertSelectIsSafe = null;
+       /** @var stdClass|null */
+       private $replicationInfoRow = null;
 
        /**
         * Additional $params include:
@@ -508,20 +510,35 @@ abstract class DatabaseMysqlBase extends Database {
                return $this->nativeReplace( $table, $rows, $fname );
        }
 
-       protected function nativeInsertSelect(
-               $destTable, $srcTable, $varMap, $conds,
-               $fname = __METHOD__, $insertOptions = [], $selectOptions = [], $selectJoinConds = []
-       ) {
-               $isSafe = in_array( 'NO_AUTO_COLUMNS', $insertOptions, true );
-               if ( !$isSafe && $this->insertSelectIsSafe === null ) {
-                       // In MySQL, an INSERT SELECT is only replication safe with row-based
-                       // replication or if innodb_autoinc_lock_mode is 0. When those
-                       // conditions aren't met, use non-native mode.
-                       // While we could try to determine if the insert is safe anyway by
-                       // checking if the target table has an auto-increment column that
-                       // isn't set in $varMap, that seems unlikely to be worth the extra
-                       // complexity.
-                       $row = $this->selectRow(
+       protected function isInsertSelectSafe( array $insertOptions, array $selectOptions ) {
+               $row = $this->getReplicationSafetyInfo();
+               // For row-based-replication, the resulting changes will be relayed, not the query
+               if ( $row->binlog_format === 'ROW' ) {
+                       return true;
+               }
+               // LIMIT requires ORDER BY on a unique key or it is non-deterministic
+               if ( isset( $selectOptions['LIMIT'] ) ) {
+                       return false;
+               }
+               // In MySQL, an INSERT SELECT is only replication safe with row-based
+               // replication or if innodb_autoinc_lock_mode is 0. When those
+               // conditions aren't met, use non-native mode.
+               // While we could try to determine if the insert is safe anyway by
+               // checking if the target table has an auto-increment column that
+               // isn't set in $varMap, that seems unlikely to be worth the extra
+               // complexity.
+               return (
+                       in_array( 'NO_AUTO_COLUMNS', $insertOptions ) ||
+                       (int)$row->innodb_autoinc_lock_mode === 0
+               );
+       }
+
+       /**
+        * @return stdClass Process cached row
+        */
+       protected function getReplicationSafetyInfo() {
+               if ( $this->replicationInfoRow === null ) {
+                       $this->replicationInfoRow = $this->selectRow(
                                false,
                                [
                                        'innodb_autoinc_lock_mode' => '@@innodb_autoinc_lock_mode',
@@ -530,33 +547,9 @@ abstract class DatabaseMysqlBase extends Database {
                                [],
                                __METHOD__
                        );
-                       $this->insertSelectIsSafe = $row->binlog_format === 'ROW' ||
-                               (int)$row->innodb_autoinc_lock_mode === 0;
-               }
-
-               if ( !$isSafe && !$this->insertSelectIsSafe ) {
-                       return $this->nonNativeInsertSelect(
-                               $destTable,
-                               $srcTable,
-                               $varMap,
-                               $conds,
-                               $fname,
-                               $insertOptions,
-                               $selectOptions,
-                               $selectJoinConds
-                       );
-               } else {
-                       return parent::nativeInsertSelect(
-                               $destTable,
-                               $srcTable,
-                               $varMap,
-                               $conds,
-                               $fname,
-                               $insertOptions,
-                               $selectOptions,
-                               $selectJoinConds
-                       );
                }
+
+               return $this->replicationInfoRow;
        }
 
        /**
@@ -678,7 +671,7 @@ abstract class DatabaseMysqlBase extends Database {
                        }
                }
 
-               return empty( $result ) ? false : $result;
+               return $result ?: false;
        }
 
        /**
index 9152d1e..984e1c0 100644 (file)
@@ -25,6 +25,7 @@ namespace Wikimedia\Rdbms;
 use mysqli;
 use mysqli_result;
 use IP;
+use stdClass;
 
 /**
  * Database abstraction object for PHP extension mysqli.
@@ -34,8 +35,6 @@ use IP;
  * @see Database
  */
 class DatabaseMysqli extends DatabaseMysqlBase {
-       /** @var mysqli $mConn */
-
        /**
         * @param string $sql
         * @return resource
@@ -162,7 +161,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
         * @return int
         */
        function lastErrno() {
-               if ( $this->conn ) {
+               if ( $this->conn instanceof mysqli ) {
                        return $this->conn->errno;
                } else {
                        return mysqli_connect_errno();
@@ -202,7 +201,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
 
        /**
         * @param mysqli_result $res
-        * @return bool
+        * @return stdClass|bool
         */
        protected function mysqlFetchObject( $res ) {
                $object = $res->fetch_object();
@@ -235,7 +234,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $res
+        * @param mysqli_result $res
         * @return mixed
         */
        protected function mysqlNumFields( $res ) {
@@ -243,7 +242,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $res
+        * @param mysqli_result $res
         * @param int $n
         * @return mixed
         */
@@ -266,7 +265,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $res
+        * @param mysqli_result $res
         * @param int $n
         * @return mixed
         */
@@ -277,7 +276,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param mysqli $res
+        * @param mysqli_result $res
         * @param int $n
         * @return mixed
         */
index 7d34641..38cc4ae 100644 (file)
@@ -394,7 +394,7 @@ class DatabasePostgres extends Database {
                        // Forced result for simulated queries
                        return $this->lastAffectedRowCount;
                }
-               if ( empty( $this->lastResultHandle ) ) {
+               if ( !$this->lastResultHandle ) {
                        return 0;
                }
 
index 58b6ef9..3d6cee3 100644 (file)
@@ -103,6 +103,10 @@ class DatabaseSqlite extends Database {
                ] );
        }
 
+       protected static function getAttributes() {
+               return [ self::ATTR_DB_LEVEL_LOCKING => true ];
+       }
+
        /**
         * @param string $filename
         * @param array $p Options map; supports:
index 7bbb530..8210507 100644 (file)
@@ -172,7 +172,9 @@ interface ILoadBalancer {
        /**
         * Get a connection handle by server index
         *
-        * Avoid using CONN_TRX_AUTO with sqlite (e.g. check getServerType() first)
+        * The CONN_TRX_AUTO flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
+        * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
+        * can be used to check such flags beforehand.
         *
         * If the caller uses $domain or sets CONN_TRX_AUTO in $flags, then it must also
         * call ILoadBalancer::reuseConnection() on the handle when finished using it.
@@ -206,7 +208,9 @@ interface ILoadBalancer {
         *
         * The handle's methods simply wrap those of a Database handle
         *
-        * Avoid using CONN_TRX_AUTO with sqlite (e.g. check getServerType() first)
+        * The CONN_TRX_AUTO flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
+        * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
+        * can be used to check such flags beforehand.
         *
         * @see ILoadBalancer::getConnection() for parameter information
         *
@@ -223,7 +227,9 @@ interface ILoadBalancer {
         *
         * The handle's methods simply wrap those of a Database handle
         *
-        * Avoid using CONN_TRX_AUTO with sqlite (e.g. check getServerType() first)
+        * The CONN_TRX_AUTO flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
+        * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
+        * can be used to check such flags beforehand.
         *
         * @see ILoadBalancer::getConnection() for parameter information
         *
@@ -240,7 +246,9 @@ interface ILoadBalancer {
         *
         * The handle's methods simply wrap those of a Database handle
         *
-        * Avoid using CONN_TRX_AUTO with sqlite (e.g. check getServerType() first)
+        * The CONN_TRX_AUTO flag is ignored for databases with ATTR_DB_LEVEL_LOCKING
+        * (e.g. sqlite) in order to avoid deadlocks. ILoadBalancer::getServerAttributes()
+        * can be used to check such flags beforehand.
         *
         * @see ILoadBalancer::getConnection() for parameter information
         *
@@ -258,7 +266,9 @@ interface ILoadBalancer {
         * The index must be an actual index into the array. If a connection to the server is
         * already open and not considered an "in use" foreign connection, this simply returns it.
         *
-        * Avoid using CONN_TRX_AUTO with sqlite (e.g. check getServerType() first)
+        * Avoid using CONN_TRX_AUTO for databases with ATTR_DB_LEVEL_LOCKING (e.g. sqlite) in
+        * order to avoid deadlocks. ILoadBalancer::getServerAttributes() can be used to check
+        * such flags beforehand.
         *
         * If the caller uses $domain or sets CONN_TRX_AUTO in $flags, then it must also
         * call ILoadBalancer::reuseConnection() on the handle when finished using it.
@@ -319,6 +329,13 @@ interface ILoadBalancer {
         */
        public function getServerType( $i );
 
+       /**
+        * @param int $i Server index
+        * @return array (Database::ATTRIBUTE_* constant => value) for all such constants
+        * @since 1.31
+        */
+       public function getServerAttributes( $i );
+
        /**
         * Get the current master position for chronology control purposes
         * @return DBMasterPos|bool Returns false if not applicable
index 569ea0e..99a24c2 100644 (file)
@@ -680,6 +680,22 @@ class LoadBalancer implements ILoadBalancer {
                        $domain = false; // local connection requested
                }
 
+               if ( ( $flags & self::CONN_TRX_AUTO ) === self::CONN_TRX_AUTO ) {
+                       // Assuming all servers are of the same type (or similar), which is overwhelmingly
+                       // the case, use the master server information to get the attributes. The information
+                       // for $i cannot be used since it might be DB_REPLICA, which might require connection
+                       // attempts in order to be resolved into a real server index.
+                       $attributes = $this->getServerAttributes( $this->getWriterIndex() );
+                       if ( $attributes[Database::ATTR_DB_LEVEL_LOCKING] ) {
+                               // Callers sometimes want to (a) escape REPEATABLE-READ stateness without locking
+                               // rows (e.g. FOR UPDATE) or (b) make small commits during a larger transactions
+                               // to reduce lock contention. None of these apply for sqlite and using separate
+                               // connections just causes self-deadlocks.
+                               $flags &= ~self::CONN_TRX_AUTO;
+                               $this->connLogger->info( __METHOD__ . ': ignoring CONN_TRX_AUTO to avoid deadlocks.' );
+                       }
+               }
+
                $groups = ( $groups === false || $groups === [] )
                        ? [ false ] // check one "group": the generic pool
                        : (array)$groups;
@@ -981,6 +997,13 @@ class LoadBalancer implements ILoadBalancer {
                return $conn;
        }
 
+       public function getServerAttributes( $i ) {
+               return Database::attributesFromType(
+                       $this->getServerType( $i ),
+                       isset( $this->servers[$i]['driver'] ) ? $this->servers[$i]['driver'] : null
+               );
+       }
+
        /**
         * Test if the specified index represents an open connection
         *
index dc9af5a..d1acacf 100644 (file)
@@ -424,9 +424,9 @@ class LogPager extends ReverseChronologicalPager {
                $this->actionRestrictionsEnforced = true;
                $user = $this->getUser();
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::DELETED_USER ) . ' = 0';
+                       $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::DELETED_ACTION ) . ' = 0';
                } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                       $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::SUPPRESSED_USER ) .
+                       $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::SUPPRESSED_ACTION ) .
                                ' != ' . LogPage::SUPPRESSED_USER;
                }
        }
@@ -442,9 +442,9 @@ class LogPager extends ReverseChronologicalPager {
                $this->performerRestrictionsEnforced = true;
                $user = $this->getUser();
                if ( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::DELETED_ACTION ) . ' = 0';
+                       $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::DELETED_USER ) . ' = 0';
                } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
-                       $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::SUPPRESSED_ACTION ) .
+                       $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::SUPPRESSED_USER ) .
                                ' != ' . LogPage::SUPPRESSED_ACTION;
                }
        }
index 2adfd0a..8e5dcbd 100644 (file)
@@ -358,7 +358,7 @@ class Parser {
                $this->mLangLinkLanguages = [];
                $this->currentRevisionCache = null;
 
-               $this->mStripState = new StripState;
+               $this->mStripState = new StripState( $this );
 
                # Clear these on every parse, T6549
                $this->mTplRedirCache = $this->mTplDomCache = [];
@@ -543,6 +543,11 @@ class Parser {
                $this->mOutput->setLimitReportData( 'limitreport-expensivefunctioncount',
                        [ $this->mExpensiveFunctionCount, $this->mOptions->getExpensiveParserFunctionLimit() ]
                );
+
+               foreach ( $this->mStripState->getLimitReport() as list( $key, $value ) ) {
+                       $this->mOutput->setLimitReportData( $key, $value );
+               }
+
                Hooks::run( 'ParserLimitReportPrepare', [ $this, $this->mOutput ] );
 
                $limitReport = "NewPP limit report\n";
@@ -2215,8 +2220,14 @@ class Parser {
                                $link = $origLink;
                        }
 
-                       $unstrip = $this->mStripState->unstripNoWiki( $link );
-                       $nt = is_string( $unstrip ) ? Title::newFromText( $unstrip ) : null;
+                       // \x7f isn't a default legal title char, so most likely strip
+                       // markers will force us into the "invalid form" path above.  But,
+                       // just in case, let's assert that xmlish tags aren't valid in
+                       // the title position.
+                       $unstrip = $this->mStripState->killMarkers( $link );
+                       $noMarkers = ( $unstrip === $link );
+
+                       $nt = $noMarkers ? Title::newFromText( $link ) : null;
                        if ( $nt === null ) {
                                $s .= $prefix . '[[' . $line;
                                continue;
@@ -5987,11 +5998,13 @@ class Parser {
         * unserializeHalfParsedText(). The text can then be safely incorporated into
         * the return value of a parser hook.
         *
+        * @deprecated since 1.31
         * @param string $text
         *
         * @return array
         */
        public function serializeHalfParsedText( $text ) {
+               wfDeprecated( __METHOD__, '1.31' );
                $data = [
                        'text' => $text,
                        'version' => self::HALF_PARSED_VERSION,
@@ -6012,11 +6025,13 @@ class Parser {
         * If the $data array has been stored persistently, the caller should first
         * check whether it is still valid, by calling isValidHalfParsedText().
         *
+        * @deprecated since 1.31
         * @param array $data Serialized data
         * @throws MWException
         * @return string
         */
        public function unserializeHalfParsedText( $data ) {
+               wfDeprecated( __METHOD__, '1.31' );
                if ( !isset( $data['version'] ) || $data['version'] != self::HALF_PARSED_VERSION ) {
                        throw new MWException( __METHOD__ . ': invalid version' );
                }
@@ -6037,11 +6052,13 @@ class Parser {
         * serializeHalfParsedText(), is compatible with the current version of the
         * parser.
         *
+        * @deprecated since 1.31
         * @param array $data
         *
         * @return bool
         */
        public function isValidHalfParsedText( $data ) {
+               wfDeprecated( __METHOD__, '1.31' );
                return isset( $data['version'] ) && $data['version'] == self::HALF_PARSED_VERSION;
        }
 
index 5d6385e..d329f69 100644 (file)
  * @ingroup Parser
  */
 class StripState {
-       protected $prefix;
        protected $data;
        protected $regex;
 
+       protected $parser;
+
        protected $circularRefGuard;
-       protected $recursionLevel = 0;
+       protected $depth = 0;
+       protected $highestDepth = 0;
+       protected $expandSize = 0;
 
-       const UNSTRIP_RECURSION_LIMIT = 20;
+       protected $depthLimit = 20;
+       protected $sizeLimit = 5000000;
 
        /**
-        * @param string|null $prefix
-        * @since 1.26 The prefix argument should be omitted, as the strip marker
-        *  prefix string is now a constant.
+        * @param Parser|null $parser
+        * @param array $options
         */
-       public function __construct( $prefix = null ) {
-               if ( $prefix !== null ) {
-                       wfDeprecated( __METHOD__ . ' with called with $prefix argument' .
-                               ' (call with no arguments instead)', '1.26' );
-               }
+       public function __construct( Parser $parser = null, $options = [] ) {
                $this->data = [
                        'nowiki' => [],
                        'general' => []
                ];
                $this->regex = '/' . Parser::MARKER_PREFIX . "([^\x7f<>&'\"]+)" . Parser::MARKER_SUFFIX . '/';
                $this->circularRefGuard = [];
+               $this->parser = $parser;
+
+               if ( isset( $options['depthLimit'] ) ) {
+                       $this->depthLimit = $options['depthLimit'];
+               }
+               if ( isset( $options['sizeLimit'] ) ) {
+                       $this->sizeLimit = $options['sizeLimit'];
+               }
        }
 
        /**
@@ -125,25 +132,32 @@ class StripState {
                        $marker = $m[1];
                        if ( isset( $this->data[$type][$marker] ) ) {
                                if ( isset( $this->circularRefGuard[$marker] ) ) {
-                                       return '<span class="error">'
-                                               . wfMessage( 'parser-unstrip-loop-warning' )->inContentLanguage()->text()
-                                               . '</span>';
+                                       return $this->getWarning( 'parser-unstrip-loop-warning' );
                                }
-                               if ( $this->recursionLevel >= self::UNSTRIP_RECURSION_LIMIT ) {
-                                       return '<span class="error">' .
-                                               wfMessage( 'parser-unstrip-recursion-limit' )
-                                                       ->numParams( self::UNSTRIP_RECURSION_LIMIT )->inContentLanguage()->text() .
-                                               '</span>';
+
+                               if ( $this->depth > $this->highestDepth ) {
+                                       $this->highestDepth = $this->depth;
                                }
-                               $this->circularRefGuard[$marker] = true;
-                               $this->recursionLevel++;
+                               if ( $this->depth >= $this->depthLimit ) {
+                                       return $this->getLimitationWarning( 'unstrip-depth', $this->depthLimit );
+                               }
+
                                $value = $this->data[$type][$marker];
                                if ( $value instanceof Closure ) {
                                        $value = $value();
                                }
+
+                               $this->expandSize += strlen( $value );
+                               if ( $this->expandSize > $this->sizeLimit ) {
+                                       return $this->getLimitationWarning( 'unstrip-size', $this->sizeLimit );
+                               }
+
+                               $this->circularRefGuard[$marker] = true;
+                               $this->depth++;
                                $ret = $this->unstripType( $type, $value );
-                               $this->recursionLevel--;
+                               $this->depth--;
                                unset( $this->circularRefGuard[$marker] );
+
                                return $ret;
                        } else {
                                return $m[0];
@@ -154,16 +168,69 @@ class StripState {
                return $text;
        }
 
+       /**
+        * Get warning HTML and register a limitation warning with the parser
+        *
+        * @param string $type
+        * @param int $max
+        * @return string
+        */
+       private function getLimitationWarning( $type, $max = '' ) {
+               if ( $this->parser ) {
+                       $this->parser->limitationWarn( $type, $max );
+               }
+               return $this->getWarning( "$type-warning", $max );
+       }
+
+       /**
+        * Get warning HTML
+        *
+        * @param string $message
+        * @param int $max
+        * @return string
+        */
+       private function getWarning( $message, $max = '' ) {
+               return '<span class="error">' .
+                       wfMessage( $message )
+                               ->numParams( $max )->inContentLanguage()->text() .
+                       '</span>';
+       }
+
+       /**
+        * Get an array of parameters to pass to ParserOutput::setLimitReportData()
+        *
+        * @unstable Should only be called by Parser
+        * @return array
+        */
+       public function getLimitReport() {
+               return [
+                       [ 'limitreport-unstrip-depth',
+                               [
+                                       $this->highestDepth,
+                                       $this->depthLimit
+                               ],
+                       ],
+                       [ 'limitreport-unstrip-size',
+                               [
+                                       $this->expandSize,
+                                       $this->sizeLimit
+                               ],
+                       ]
+               ];
+       }
+
        /**
         * Get a StripState object which is sufficient to unstrip the given text.
         * It will contain the minimum subset of strip items necessary.
         *
+        * @deprecated since 1.31
         * @param string $text
-        *
         * @return StripState
         */
        public function getSubState( $text ) {
-               $subState = new StripState();
+               wfDeprecated( __METHOD__, '1.31' );
+
+               $subState = new StripState;
                $pos = 0;
                while ( true ) {
                        $startPos = strpos( $text, Parser::MARKER_PREFIX, $pos );
@@ -194,11 +261,14 @@ class StripState {
         * will not be preserved. The strings in the $texts array will have their
         * strip markers rewritten, the resulting array of strings will be returned.
         *
+        * @deprecated since 1.31
         * @param StripState $otherState
         * @param array $texts
         * @return array
         */
        public function merge( $otherState, $texts ) {
+               wfDeprecated( __METHOD__, '1.31' );
+
                $mergePrefix = wfRandomString( 16 );
 
                foreach ( $otherState->data as $type => $items ) {
index 830dbb4..f9b03c7 100644 (file)
@@ -1486,10 +1486,8 @@ MESSAGE;
        }
 
        /**
-        * Returns JS code which runs given JS code if the client-side framework is
-        * present.
+        * Wraps JavaScript code to run after startup and base modules.
         *
-        * @deprecated since 1.25; use makeInlineScript instead
         * @param string $script JavaScript code
         * @return string JavaScript code
         */
@@ -1499,10 +1497,10 @@ MESSAGE;
        }
 
        /**
-        * Construct an inline script tag with given JS code.
+        * Returns an HTML script tag that runs given JS code after startup and base modules.
         *
-        * The code will be wrapped in a closure, and it will be executed by ResourceLoader
-        * only if the client has adequate support for MediaWiki JavaScript code.
+        * The code will be wrapped in a closure, and it will be executed by ResourceLoader's
+        * startup module if the client has adequate support for MediaWiki JavaScript code.
         *
         * @param string $script JavaScript code
         * @return WrappedString HTML
index 4abdebf..d6d4c27 100644 (file)
@@ -686,7 +686,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
         */
        public function checkLastModified() {
                $dbr = $this->getDB();
-               $lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', false, __METHOD__ );
+               $lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', '', __METHOD__ );
 
                return $lastmod;
        }
index 6fdf05f..cd04995 100644 (file)
@@ -185,7 +185,7 @@ class ContribsPager extends RangeChronologicalPager {
                ];
 
                if ( $this->contribs == 'newbie' ) {
-                       $max = $this->mDb->selectField( 'user', 'max(user_id)', false, __METHOD__ );
+                       $max = $this->mDb->selectField( 'user', 'max(user_id)', '', __METHOD__ );
                        $queryInfo['conds'][] = $revQuery['fields']['rev_user'] . ' >' . (int)( $max - $max / 100 );
                        # ignore local groups with the bot right
                        # @todo FIXME: Global groups may have 'bot' rights
index 4815189..e764e8b 100644 (file)
@@ -75,7 +75,7 @@ class NewFilesPager extends RangeChronologicalPager {
                if ( $opts->getValue( 'newbies' ) ) {
                        // newbie = most recent 1% of users
                        $dbr = wfGetDB( DB_REPLICA );
-                       $max = $dbr->selectField( 'user', 'max(user_id)', false, __METHOD__ );
+                       $max = $dbr->selectField( 'user', 'max(user_id)', '', __METHOD__ );
                        $conds[] = $imgQuery['fields']['img_user'] . ' >' . (int)( $max - $max / 100 );
 
                        // there's no point in looking for new user activity in a far past;
index 3102cfc..ab791b4 100644 (file)
@@ -4052,76 +4052,6 @@ class User implements IDBAccessObject, UserIdentity {
                }
        }
 
-       /**
-        * Set a cookie on the user's client. Wrapper for
-        * WebResponse::setCookie
-        * @deprecated since 1.27
-        * @param string $name Name of the cookie to set
-        * @param string $value Value to set
-        * @param int $exp Expiration time, as a UNIX time value;
-        *                   if 0 or not specified, use the default $wgCookieExpiration
-        * @param bool $secure
-        *  true: Force setting the secure attribute when setting the cookie
-        *  false: Force NOT setting the secure attribute when setting the cookie
-        *  null (default): Use the default ($wgCookieSecure) to set the secure attribute
-        * @param array $params Array of options sent passed to WebResponse::setcookie()
-        * @param WebRequest|null $request WebRequest object to use; $wgRequest will be used if null
-        *        is passed.
-        */
-       protected function setCookie(
-               $name, $value, $exp = 0, $secure = null, $params = [], $request = null
-       ) {
-               wfDeprecated( __METHOD__, '1.27' );
-               if ( $request === null ) {
-                       $request = $this->getRequest();
-               }
-               $params['secure'] = $secure;
-               $request->response()->setCookie( $name, $value, $exp, $params );
-       }
-
-       /**
-        * Clear a cookie on the user's client
-        * @deprecated since 1.27
-        * @param string $name Name of the cookie to clear
-        * @param bool $secure
-        *  true: Force setting the secure attribute when setting the cookie
-        *  false: Force NOT setting the secure attribute when setting the cookie
-        *  null (default): Use the default ($wgCookieSecure) to set the secure attribute
-        * @param array $params Array of options sent passed to WebResponse::setcookie()
-        */
-       protected function clearCookie( $name, $secure = null, $params = [] ) {
-               wfDeprecated( __METHOD__, '1.27' );
-               $this->setCookie( $name, '', time() - 86400, $secure, $params );
-       }
-
-       /**
-        * Set an extended login cookie on the user's client. The expiry of the cookie
-        * is controlled by the $wgExtendedLoginCookieExpiration configuration
-        * variable.
-        *
-        * @see User::setCookie
-        *
-        * @deprecated since 1.27
-        * @param string $name Name of the cookie to set
-        * @param string $value Value to set
-        * @param bool $secure
-        *  true: Force setting the secure attribute when setting the cookie
-        *  false: Force NOT setting the secure attribute when setting the cookie
-        *  null (default): Use the default ($wgCookieSecure) to set the secure attribute
-        */
-       protected function setExtendedLoginCookie( $name, $value, $secure ) {
-               global $wgExtendedLoginCookieExpiration, $wgCookieExpiration;
-
-               wfDeprecated( __METHOD__, '1.27' );
-
-               $exp = time();
-               $exp += $wgExtendedLoginCookieExpiration !== null
-                       ? $wgExtendedLoginCookieExpiration
-                       : $wgCookieExpiration;
-
-               $this->setCookie( $name, $value, $exp, $secure );
-       }
-
        /**
         * Persist this user's session (e.g. set cookies)
         *
index d449f5b..2d9c892 100644 (file)
        "expansion-depth-exceeded-category": "الصفحات التي حدث فيها تجاوز عمق التوسيع",
        "expansion-depth-exceeded-warning": "الصفحة تجاوزت عمق التوسيع",
        "parser-unstrip-loop-warning": "حلقة معراة تم الكشف عنها",
-       "parser-unstrip-recursion-limit": "تعدى حد العودية Unstrip  ($1)",
+       "unstrip-depth-warning": "تعدى حد العودية Unstrip  ($1)",
        "undo-success": "يمكن استرجاع التعديل.\nمن فضلك تحقق من المقارنة بالأسفل للتأكد من أن هذا هو ما تريد أن تفعله، وبعد ذلك احفظ التغييرات بالأسفل للانتهاء من استرجاع التعديل.",
        "undo-failure": "لم يمكن استرجاع التعديل بسبب تعديلات متعارضة تمت على الصفحة.",
        "undo-norev": "فشل في الرجوع عن التعديل حيث أنه غير موجود أو تم حذفه.",
index 0710d40..f635f9a 100644 (file)
        "expansion-depth-exceeded-category": "Bladsye waar die uitbreidingsdiepte oorskry is",
        "expansion-depth-exceeded-warning": "Die bladsy bevat te veel sjablone",
        "parser-unstrip-loop-warning": "'n \"Unstrip\"-lus is bespreur.",
-       "parser-unstrip-recursion-limit": "Die rekursielimiet ($1) vir \"unstrip\" is oorskry",
+       "unstrip-depth-warning": "Die rekursielimiet ($1) vir \"unstrip\" is oorskry",
        "converter-manual-rule-error": "'n Fout is in 'n handmatig toegevoegde taalomskalelingsreël gevind.",
        "undo-success": "Die wysiging kan ongedaan gemaak word.\nKontroleer die vergelyking hieronder om seker te maak dis wat u wil doen, en stoor dan om die terugrol te voltooi.",
        "undo-failure": "Die wysiging kan nie ongedaan gemaak word nie omdat dit met intermediêre wysigings bots.",
index cc7b50c..5109460 100644 (file)
        "expansion-depth-exceeded-category-desc": "mangsiw micuwat kasabelih nu ilabuay a kelec.",
        "expansion-depth-exceeded-warning": "kasabelih mangsiw micuwat ilabuay a kelec",
        "parser-unstrip-loop-warning": "masedap tu Unstrip masaliyut.",
-       "parser-unstrip-recursion-limit": "Unstrip musaliyuliyud mangasiw tu kelec ($1)",
+       "unstrip-depth-warning": "Unstrip musaliyuliyud mangasiw tu kelec ($1)",
        "converter-manual-rule-error": "imahini palima-saungay kamu miliyaw likec masedap tu mungangaw",
        "undo-success": "tina mikawaway-kalumyiti kapah tu mapatiku.\nkapikinsa tu zikuz sasutili’ay sapat nu sulit, malucekay tu ukakaiyan kaidihan isu patiku, satu suped tu zikuz misumad tu pahezek mikawaway-kalumyiti patiku.",
        "undo-failure": "nay mikawaway-kalumyiti a sumad izaw sasula’cus,tina mikawaway-kalumyiti caay patiku.",
index 580ec35..141e904 100644 (file)
        "sectioneditnotsupported-text": "تعديل الأقسام غير مدعوم في هذه الصفحة",
        "permissionserrors": "خطأ في السماح",
        "permissionserrorstext": "لا تمتلك الصلاحية لفعل هذا، {{PLURAL:$1||للسبب التالي|للسببين التاليين|للأسباب التالية}}:",
-       "permissionserrorstext-withaction": "ليست لك الصلاحية ل$2، لل{{PLURAL:$1||سبب التالي|سببين التاليين|أسباب التالية}}:",
+       "permissionserrorstext-withaction": "ليست لك الصلاحية ل$2; لل{{PLURAL:$1||سبب التالي|سببين التاليين|أسباب التالية}}:",
        "contentmodelediterror": "أنت لا يمكنك تعديل هذه المراجعة لأن موديل محتواها هو  <code>$1</code>، والذي يختلف عن موديل المحتوى الحالي للصفحة  <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''تحذير: أنت تعيد إنشاء صفحة سبق حذفها.'''\n\nيجب عليك التيقن من أن الاستمرار بتحرير هذه الصفحة ملائم.\nسجلا الحذف والنقل لهذه الصفحة معروضان هنا للتيسير:",
        "moveddeleted-notice": "هذه الصفحة تم حذفها.\nسجلا حذف ونقل الصفحة معروضان بالأسفل كمرجع.",
        "expansion-depth-exceeded-category-desc": "الصفحة تجاوزت الحد الأقصى لعمق التوسيع.",
        "expansion-depth-exceeded-warning": "الصفحة تجاوزت عمق التوسيع",
        "parser-unstrip-loop-warning": "حلقة معراة تم الكشف عنها",
-       "parser-unstrip-recursion-limit": "تعدى حد العودية Unstrip  ($1)",
+       "unstrip-depth-warning": "تعدى حد العودية Unstrip  ($1)",
        "converter-manual-rule-error": "خطأ تم اكتشافه في قاعدة تحويل اللغة اليدوية",
        "undo-success": "يمكن استرجاع التعديل.\nتحقق من المقارنة بالأسفل للتأكد من أن هذا هو ما تريد أن تفعله، ثم احفظ التغييرات بالأسفل للانتهاء من استرجاع التعديل.",
        "undo-failure": "لم يمكن استرجاع التعديل بسبب تعديلات متعارضة تمت على الصفحة.",
        "emailuserfooter": "هذا البريد الإلكتروني {{GENDER:$1|تم إرساله}} بواسطة $1 إلى {{GENDER:$2|$2}} بواسطة وظيفة \"{{int:emailuser}}\" في {{SITENAME}}. لو {{GENDER:$2|أنك}} رددت على هذا البريد، فعنوان البريد الخاص {{GENDER:$2|بك}} سيتم إرساله مباشرة {{GENDER:$1|للمرسل الأصلي|للمرسلة الأصلية}}، مما يكشف عنوان البريد الإلكتروني الخاص {{GENDER:$2|بك}} {{GENDER:$1|لهم}}.",
        "usermessage-summary": "ترك رسالة نظام.",
        "usermessage-editor": "مراسل النظام",
-       "watchlist": "قائمة مراقبتي",
-       "mywatchlist": "قائمة مراقبتي",
+       "watchlist": "قائمة المراقبة",
+       "mywatchlist": "قائمة المراقبة",
        "watchlistfor2": "ل$1 $2",
        "nowatchlist": "لا توجد مدخلات في قائمة مراقبتك.",
        "watchlistanontext": "الرجاء تسجيل الدخول لعرض أو تعديل الصفحات في قائمة مراقبتك.",
index 8be15c8..cb72b81 100644 (file)
        "expansion-depth-exceeded-category": "বিস্তৃতি গভীৰতা বেছি হোৱা পৃষ্ঠা",
        "expansion-depth-exceeded-warning": "পৃষ্ঠাটোৰ বিস্তৃতি গভীৰতা বেছি হৈছে",
        "parser-unstrip-loop-warning": "আন্‌ষ্ট্ৰীপ লুপ চিনাক্ত কৰা হৈছে",
-       "parser-unstrip-recursion-limit": "আন্‌ষ্ট্ৰিপ ৰিকাৰ্ছন সীমা অতিক্ৰম হৈছে ($1)",
+       "unstrip-depth-warning": "আন্‌ষ্ট্ৰিপ ৰিকাৰ্ছন সীমা অতিক্ৰম হৈছে ($1)",
        "converter-manual-rule-error": "মেনুৱেল ভাষা পৰিৱৰ্তন নিয়মত ত্ৰুটি পোৱা গৈছে",
        "undo-success": "এই সম্পাদনা পূৰ্ববৎ কৰিব পাৰি ।\nঅনুগ্ৰহ কৰি তলৰ তুলনাটি পৰীক্ষা কৰি ঠাৱৰ কৰক যে আপুনি এনে কৰিব বিচাৰিছে, আৰু তলত সালসলনিসমূহ সাঁচি এই কাৰ্য্য সম্পন্ন কৰক ।",
        "undo-failure": "এই সম্পাদনা মধ্যৱৰ্তী সম্পাদনাসমূহৰ দ্বন্দৰ কাৰণে পূৰ্ববৎ কৰা নহ'ব ।",
index 0404cf0..2c93bc8 100644 (file)
        "expansion-depth-exceeded-category-desc": "La páxina superó la fondura máxima d'espansión.",
        "expansion-depth-exceeded-warning": "La páxina pasó la fondura d'espansión",
        "parser-unstrip-loop-warning": "Deteutóse un bucle \"unstrip\"",
-       "parser-unstrip-recursion-limit": "Pasóse la llende de recursividá d'unstrip ($1)",
+       "unstrip-depth-warning": "Pasóse la llende de recursividá d'unstrip ($1)",
        "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.",
index 0db063c..5ce0f45 100644 (file)
        "expansion-depth-exceeded-category-desc": "ई पन्ना विस्तार गहराई पार करत है।",
        "expansion-depth-exceeded-warning": "पन्ना में विस्तार गहराई पार कई गा है",
        "parser-unstrip-loop-warning": "Unstrip लूप मिला",
-       "parser-unstrip-recursion-limit": "Unstrip पुनरावर्तन सीमा पार कई गय ($1)",
+       "unstrip-depth-warning": "Unstrip पुनरावर्तन सीमा पार कई गय ($1)",
        "converter-manual-rule-error": "मैन्यूअल भाषा परिवर्तन नियम में त्रुटि",
        "undo-success": "ई संपादन पहिले जैसन रहा वईसय कई सका जात है ।\nअईसन करेक लिये कृपया निचे लिखल पाठ कय ध्यान से दखीकय बदलाव सहेजा जाय।",
        "undo-failure": "एकरे बीचे अउर बदलाव होएक कारण ई संपादन पहिले जैसन करब संभव नाई है।",
index 376c2ac..ee3523f 100644 (file)
        "expansion-depth-exceeded-category": "گئنیشلمه درین‌لیگی آشیلان صحیفه‌لر",
        "expansion-depth-exceeded-warning": "صحیفه گئنیشلنمه درین‌لیگی آشیلدی",
        "parser-unstrip-loop-warning": "تکرارلاما دونمه سی قبول ائدیلدی",
-       "parser-unstrip-recursion-limit": "حداکثر ارجاع دستور دا unstrip تجاوز گئچیب دیر ($1)",
+       "unstrip-depth-warning": "حداکثر ارجاع دستور دا unstrip تجاوز گئچیب دیر ($1)",
        "converter-manual-rule-error": "خطا ال مبدیلی قانون لاریندا",
        "undo-success": "بو دَییشیک‌لیک گئری آلینا بیلر. لطفاً آشاغی‌داکی موقاییسه ائتمیی نظارت ائدین، حقیقتن بو دییشیک‌لیگی ائتمک ایستدیگینیزدن امین اولون و صحیفنی یازا‌راق بیر اوولکی دییشیک‌لیگی گئرییه آلین.",
        "undo-failure": "دییشیک‌لیک‌لرین توققوشماسی نتیجه‌سینده گئرییه قایتارما ایشی اوغورسوز اولدو.",
index fbfde93..db55a9a 100644 (file)
        "expansion-depth-exceeded-category-desc": "Биттең асылыу тәрәнлеге мөмкин булған юғары сикте уҙған.",
        "expansion-depth-exceeded-warning": "Биттә һалыныу тәрәнлеге сиге үтеп кителгән",
        "parser-unstrip-loop-warning": "Ябылмаған pre табылды",
-       "parser-unstrip-recursion-limit": "($1) рекурсия сиге үтеп кителгән",
+       "unstrip-depth-warning": "($1) рекурсия сиге үтеп кителгән",
        "converter-manual-rule-error": "Тел әйлендереү ҡағиҙәһендә хата табылды",
        "undo-success": "Был үҙгәртеүҙе кире алып була. Үҙгәртеүҙәр нәҡ һеҙ теләгәнсә булһа, версияларҙы сағыштырып ҡарағыҙ, ғәмәлгә индерер өсөн, «Битте һаҡларға» төймәһенә баҫығыҙ.",
        "undo-failure": "Ара үҙгәртеүҙәр тура килмәү сәбәпле төҙәтеүҙе кире алып булмай.",
        "recentchangeslinked-feed": "Бәйле үҙгәртеүҙәр",
        "recentchangeslinked-toolbox": "Бәйле үҙгәртеүҙәр",
        "recentchangeslinked-title": "\"$1\" битенә бәйле үҙгәртеүҙәр",
-       "recentchangeslinked-summary": "Ð\91Ñ\8bл ÐºÒ¯Ñ\80Ò»Ó\99Ñ\82елгÓ\99н Ð±Ð¸Ñ\82 - Ò»Ñ\8bлÑ\82анма Ñ\8fһаÒ\93ан (йÓ\99ки ÐºÒ¯Ñ\80Ò»Ó\99Ñ\82елгÓ\99н ÐºÐ°Ñ\82егоÑ\80иÑ\8fÒ\93а ÐºÐµÑ\80гÓ\99н) Ò»Ñ\83Ò£Ò\93Ñ\8b Ò¯Ò\99гÓ\99Ñ\80Ñ\82еүÒ\99Ó\99Ñ\80 Ð¸Ñ\81емлеге.\n[[Special:Watchlist|Ð\9aÒ¯Ò\99Ó\99Ñ\82еү Ð¸Ñ\81емлегегеÒ\99гÓ\99]] ÐºÐµÑ\80Ó\99 Ñ\82оÑ\80Ò\93ан Ð±Ð¸Ñ\82Ñ\82әр '''ҡалын''' итеп күрһәтелгән.",
+       "recentchangeslinked-summary": "Ð\91Ñ\8bл Ð±Ð¸Ñ\82кÓ\99 Ð¹Ó\99ки Ð±Ñ\8bл Ð±Ð¸Ñ\82Ñ\82Ó\99н Ò»Ñ\8bлÑ\82анÒ\93ан Ð±Ð¸Ñ\82Ñ\82Ó\99Ñ\80Ò\99Ó\99 Ò¯Ò\99гÓ\99Ñ\80Ñ\82еүÒ\99Ó\99Ñ\80Ò\99е ÐºÒ¯Ñ\80еү Ó©Ñ\81өн Ð±Ð¸Ñ\82 Ð¸Ñ\81емен Ñ\8fÒ\99Ñ\8bÒ\93Ñ\8bÒ\99 (Ð\9aаÑ\82егоÑ\80иÑ\8fлаÑ\80 Ó©Ñ\81өн \"Ð\9aаÑ\82егоÑ\80иÑ\8f:каÑ\82еÑ\80огиÑ\8f Ð¸Ñ\81еме\"н Ñ\8fÒ\99Ñ\8bÒ\93Ñ\8bÒ\99).\n[[Special:Watchlist|Ð\9aÒ¯Ò\99Ó\99Ñ\82еү Ð¸Ñ\81емлегегеÒ\99гÓ\99]] Ð¸Ð½Ð´ÐµÑ\80елгÓ\99н Ð±Ð¸Ñ\82Ñ\82Ó\99Ñ\80Ò\99Ó\99 Ò¯Ò\99гÓ\99Ñ\80Ñ\82еүÒ\99әр '''ҡалын''' итеп күрһәтелгән.",
        "recentchangeslinked-page": "Бит исеме:",
        "recentchangeslinked-to": "Киреһенсә, был биткә һылтанма яһаған биттәрҙәге үҙгәртеүҙәрҙе күрһәтергә",
        "recentchanges-page-added-to-category": "[[:$1]] категорияға өҫтәлгән",
        "unwatchthispage": "Күҙәтеүҙе туҡтатырға",
        "notanarticle": "Мәҡәлә түгел",
        "notvisiblerev": "Башҡа ҡатнашыусы тарафынан керетелгән һуңғы өлгө юйылған",
-       "watchlist-details": "Һеҙҙең күҙәтеү исемлегегеҙҙә, фекерләшеү биттәрен һанамағанда, {{PLURAL:$1|$1 бит}} бар.",
+       "watchlist-details": "Һеҙҙең $1 күҙәтеү исемлегегеҙҙә, фекерләшеү биттәре менән бергә, {{PLURAL:$1|$1 бит}} бар.",
        "wlheader-enotif": "Электрон почта аша белдереү индерелгән.",
        "wlheader-showupdated": "Һеҙҙең аҙаҡҡы кереүегеҙҙән һуң үҙгәргән биттәр '''ҡалын''' шрифт менән күрһәтелгән.",
        "wlnote": "Түбәндә $3 $4 ваҡытына тиклем аҙаҡҡы {{PLURAL:$2|1=сәғәт|'''$2''' сәғәт}} эсендә эшләнгән {{PLURAL:$1|1=үҙгәртеү|'''$1''' үҙгәртеү}} күрһәтелгән.",
index c1b64d7..e1037ac 100644 (file)
        "expansion-depth-exceeded-category-desc": "کتگوری په دیمان که آوانی تا پرش بوتینی  جولی  گیشتیر شُته گنت.",
        "expansion-depth-exceeded-warning": "پیج چه مکسیمم تچک کتنء امک(عمق) گیش شُت",
        "parser-unstrip-loop-warning": "حلقهء unstrip ودی بوت",
-       "parser-unstrip-recursion-limit": "چه مکسیمم ارجاع مان دستور unstrip گیش شُت ات($1)",
+       "unstrip-depth-warning": "چه مکسیمم ارجاع مان دستور unstrip گیش شُت ات($1)",
        "converter-manual-rule-error": "ارور مان قوانین مبدل دستی زبان",
        "undo-success": "اصلاح برگشت نه بیت. لطفا مقایسه جهلگینء کنترل کنیت په تایید شی که شی هما انت که شما لوٹیت، و بعدا تغغیرات جهلی په تمام کتن بر نگردگ اصلاح ذخیره کنیت.",
        "undo-failure": "اصلاح بر نرگردیت په خاطر تضاد میان اصلاحاتی",
index f234fe2..427ccdb 100644 (file)
        "expansion-depth-exceeded-category": "Mga pahina kun saen an panrarom na kalakbangan nagsobra",
        "expansion-depth-exceeded-warning": "An pahina nagsobra sa panrarom na kalakbangan",
        "parser-unstrip-loop-warning": "Panul-ot na kaluktusan namansayan",
-       "parser-unstrip-recursion-limit": "Panul-ot na rekusyong kasagkodan nagsobra ($1)",
+       "unstrip-depth-warning": "Panul-ot na rekusyong kasagkodan nagsobra ($1)",
        "converter-manual-rule-error": "Kasalaan detektado sa manwal na konbersyon kan pinapasunod sa lengguwahe",
        "undo-success": "Pwedeng bawion an paghirá. Sosogon tabì an pagkakaiba sa babâ tangarig maberipikár kun ini an boot mong gibohon, dangan itagama an mga pagbabàgo sa babâ tangarig tapuson an pagbawì sa paghirá.",
        "undo-failure": "Dai napogol an paghirá ta igwa pang ibang paghirá sa tahaw na nagkokomplikto.",
index 8a14787..4120ffc 100644 (file)
        "expansion-depth-exceeded-category-desc": "Старонка перавышае максымальную глыбіню раскрыцьця.",
        "expansion-depth-exceeded-warning": "Старонка перавысіла дазволеную глыбіню разгортваньня",
        "parser-unstrip-loop-warning": "Вызначаная пятля unstrip",
-       "parser-unstrip-recursion-limit": "Перавышаны ліміт рэкурсіі unstrip ($1)",
+       "unstrip-depth-warning": "Перавышаны ліміт рэкурсіі unstrip ($1)",
        "converter-manual-rule-error": "Знойдзеная памылка ў ручным правіле моўнага канвэртару",
        "undo-success": "Рэдагаваньне можа быць адмененае. Калі ласка, параўнайце адрозьненьні паміж вэрсіямі, каб упэўніцца, што гэта адпаведныя зьмены, а потым запішыце зьмены для сканчэньня рэдагаваньня.",
        "undo-failure": "Рэдагаваньне ня можа быць скасаванае праз канфлікт паміж папярэднімі рэдагаваньнямі.",
        "right-ipblock-exempt": "Абход блякаваньняў IP-адрасоў, аўтаблякаваньняў і блякаваньняў дыяпазонаў",
        "right-unblockself": "Разблякаваньне самога сябе",
        "right-protect": "Зьмена ўзроўню абароны старонак і рэдагаваньне каскадна абароненых старонак",
-       "right-editprotected": "рэдагаваньне старонак, абароненых у рэжыме «{{int:protect-level-sysop}}»",
-       "right-editsemiprotected": "рэдагаваньне старонак, абароненых у рэжыме «{{int:protect-level-autoconfirmed}}»",
+       "right-editprotected": "Рэдагаваньне старонак, абароненых у рэжыме «{{int:protect-level-sysop}}»",
+       "right-editsemiprotected": "Рэдагаваньне старонак, абароненых у рэжыме «{{int:protect-level-autoconfirmed}}»",
        "right-editcontentmodel": "рэдагаваньне мадэлі зьместу старонкі",
-       "right-editinterface": "рэдагаваньне інтэрфэйса карыстальніка",
-       "right-editusercss": "рэдагаваньне CSS файлаў іншых удзельнікаў",
-       "right-edituserjs": "рэдагаваньне JS файлаў іншых удзельнікаў",
+       "right-editinterface": "Рэдагаваньне інтэрфэйсу карыстальніка",
+       "right-editusercss": "Рэдагаваньне CSS-файлаў іншых удзельнікаў",
+       "right-edituserjs": "Рэдагаваньне JavaScript-файлаў іншых удзельнікаў",
        "right-editmyusercss": "рэдагаваць уласныя карыстальніцкія CSS-файлы",
        "right-editmyuserjs": "рэдагаваць уласныя карыстальніцкія JavaScript-файлы",
        "right-viewmywatchlist": "праглядаць уласны сьпіс назіраньня",
index 5a6d37c..fa1e7a0 100644 (file)
@@ -32,7 +32,8 @@
                        "Mechanizatar",
                        "Artsiom91",
                        "Andrus",
-                       "Da voli"
+                       "Da voli",
+                       "OlegCinema"
                ]
        },
        "tog-underline": "Падкрэсліваць спасылкі:",
        "expansion-depth-exceeded-category-desc": "На старонцы перасягнута максімальная глыбіня разгортвання.",
        "expansion-depth-exceeded-warning": "Старонка перасягнула глыбіню разгортвання",
        "parser-unstrip-loop-warning": "Выяўлены закальцаваны unstrip",
-       "parser-unstrip-recursion-limit": "Перавышаны ліміт рэкурсіі unstrip ($1)",
+       "unstrip-depth-warning": "Перавышаны ліміт рэкурсіі unstrip ($1)",
        "converter-manual-rule-error": "Выяўлена памылка ў ручным правіле моўнага канвертара",
        "undo-success": "Праўку можна адкаціць, але праверце папярэдні паказ, што ніжэй, каб упэўніцца ў адпаведнасці будучых змяненняў, і толькі тады запішыце іх, каб завершыць адкат праўкі.",
        "undo-failure": "Немагчыма адкаціць праўку, таму што перашкаджаюць праўкі, што былі перад ёй.",
        "rcfilters-savedqueries-remove": "Сцерці",
        "rcfilters-savedqueries-new-name-label": "Назва",
        "rcfilters-savedqueries-apply-label": "Запісаць настройкі",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Стварыць фільтр па ўмаўчанню",
        "rcfilters-savedqueries-cancel-label": "Скасаваць",
        "rcfilters-savedqueries-add-new-title": "Запісаць цяперашнія настройкі фільтра",
        "rcfilters-restore-default-filters": "Аднавіць фільтры па змоўчанні",
        "uploadstash-errclear": "Ачыстка файлаў не ўдалася",
        "uploadstash-refresh": "Абнавіць спіс файлаў",
        "uploadstash-thumbnail": "паказаць мініяцюру",
+       "uploadstash-file-not-found-no-local-path": "Не знойдзена лакальнага шляху да отмасштабированному файлу.",
+       "uploadstash-file-not-found-no-object": "Не атрымалася стварыць аб'ект лакальнага файла для мініяцюры.",
+       "uploadstash-file-not-found-missing-content-type": "Отсутствует загаловак content-type.",
+       "uploadstash-file-not-found-not-exists": "Шлях не знойдзены, альбо файл незразумелы.",
+       "uploadstash-no-extension": "Пустое расшырэнне.",
        "invalid-chunk-offset": "Недапушчальнае зрушэнне фрагмента",
        "img-auth-accessdenied": "Доступ забаронены",
        "img-auth-nopathinfo": "Адсутнічае PATH_INFO.\nВаш сервер не настроены на перадачу гэтых звестак.\nМагчыма, ён на аснове CGI і не падтрымлівае img_auth.\nГл. https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "apisandbox-results": "Вынікі",
        "apisandbox-sending-request": "Адпраўка API-запыту…",
        "apisandbox-loading-results": "Атрымліваем API-вынікі…",
+       "apisandbox-request-format-url-label": "Радок URL-запыту",
        "apisandbox-request-url-label": "URL-адрас запыту:",
+       "apisandbox-request-json-label": "Запытаць JSON:",
        "apisandbox-request-time": "Час запыту: {{PLURAL:$1|$1 мс}}",
        "apisandbox-results-fixtoken": "Папраўце токен і паўтарыце адпраўку",
        "apisandbox-alert-page": "Палі на гэтай старонцы недапушчальныя.",
        "trackingcategories-msg": "Катэгорыя для асочвання",
        "trackingcategories-name": "Назва паведамлення",
        "trackingcategories-desc": "Крытэрый уключэння ў катэгорыю",
+       "restricted-displaytitle-ignored": "Старонкі з игнорируемыми отображаемыми назвамі",
        "restricted-displaytitle-ignored-desc": "Старонка змяшчае <code><nowiki>{{DISPLAYTITLE}}</nowiki></code>, які ігнаруецца з-за несупадзення з актуальнай назвай старонкі",
        "noindex-category-desc": "Старонка не індэксуецца пошукавымі робатамі, таму што на ёй ёсць магічнае слова <code><nowiki>__NOINDEX__</nowiki></code> і яна знаходзіцца ў прасторы назваў, дзе гэты сцяг дазволены.",
        "index-category-desc": "На старонцы ёсць магічнае слова <code><nowiki>__INDEX__</nowiki></code> (і старонка знаходзіцца ў прасторы назваў, дзе гэты сцяг дазволены), таму яна індэксуецца пошукавымі робатамі у выпадках, калі гэтага звычайна не адбываецца.",
        "enotif_lastdiff": "Гл. $1 каб бачыць гэтую мену.",
        "enotif_anon_editor": "ананімны ўдзельнік $1",
        "enotif_body": "Паважаны(ая) $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nКароткае апісанне змены: $PAGESUMMARY $PAGEMINOREDIT\n\nЗвярнуцца да змяніўшага:\nэл. пошта: $PAGEEDITOR_EMAIL\nвікі: $PAGEEDITOR_WIKI\n\nКалі вы не наведаеце гэтую старонку, прадставіўшыся сістэме, у выпадку далейшай актыўнасці апавяшчэнняў больш не будзе. Вы можаце таксама адключыць опцыю паведамлення для ўсіх старонак у вашым спісе назірання.\n\nСістэма апавяшчэння {{grammar:genitive|{{SITENAME}}}}\n\n--\nЗмена настроек апавяшчэння\n{{canonicalurl:{{#special:Preferences}}}}\n\nЗмена наладаў вашага спісу назірання\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nВыдаліць старонку з вашага спісу назірання\n$UNWATCHURL\n\nЗваротная сувязь і дапамога\n$HELPPAGE",
+       "enotif_minoredit": "Гэта малая праўка",
        "created": "створана",
        "changed": "зменена",
        "deletepage": "Сцерці старонку",
        "undelete-search-title": "Шукаць у сцёртых старонках",
        "undelete-search-box": "Знайсці ў сцёртых старонках",
        "undelete-search-prefix": "Паказаць старонкі, пачынаючы з:",
+       "undelete-search-full": "Паказаць назвы старонак, якія змяшчаюць:",
        "undelete-search-submit": "Шукаць",
        "undelete-no-results": "Не знойдзены адпаведныя старонкі ў архіве сціранняў.",
        "undelete-filename-mismatch": "Немагчыма аднавіць версію файла з адзнакай часу $1: не супадаюць назвы файлаў",
        "unblocked-id": "Блок $1 быў зняты",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] быў разблакіраваны.",
        "blocklist": "Заблакаваныя ўдзельнікі",
+       "autoblocklist": "Аўтаблакіроўкі",
        "autoblocklist-submit": "Шукаць",
+       "autoblocklist-legend": "Спіс аўтаблакіровак",
+       "autoblocklist-empty": "Спіс аўтаблакіровак пусты.",
        "ipblocklist": "Заблакаваныя ўдзельнікі",
        "ipblocklist-legend": "Знайсці заблакаванага ўдзельніка",
        "blocklist-userblocks": "Схаваць блакіроўкі ўліковых запісаў",
        "thumbnail_dest_directory": "Немагчыма стварыць мэтавую тэчку",
        "thumbnail_image-type": "Дадзены тып выявы не падтрымліваецца",
        "thumbnail_gd-library": "Няпоўная канфігурацыя бібліятэкі GD, адсутнічае функцыя $1",
+       "thumbnail_image-size-zero": "Верагодна, памер файла роўны нулю.",
        "thumbnail_image-missing": "Хутчэй за ўсё, адсутнічае файл $1",
        "thumbnail_image-failure-limit": "Занадта шмат нядаўніх няўдалых спроб ($1 ці болей) стварыць гэту мініяцюру. Калі ласка, паспрабуйце пазней.",
        "import": "Імпартаваць старонкі",
        "import-mapping-namespace": "Імпартаваць у прастору назваў:",
        "import-mapping-subpage": "Імпартаваць як падстаронкі наступнай старонкі:",
        "import-upload-filename": "Назва файла:",
+       "import-upload-username-prefix": "Прэфіксы интервики:",
+       "import-assign-known-users": "Связать праўкі з лакальнымі ўдзельнікамі, калі ўдзельнікі з такімі імямі существуют.",
        "import-comment": "Каментарый:",
        "importtext": "Калі ласка, экспартуйце файл з крынічнай вікі з дапамогай [[Special:Export|прылады экспарту]].\nЗахавайце яго на свой камп'ютар, а потым загрузіце сюды.",
        "importstart": "Імпартаванне старонак...",
        "imported-log-entries": "{{PLURAL:$1|Імпартаваны $1 запіс журнала|Імпартавана $1 запісы журнала|Імпартавана $1 запісаў журнала}}.",
        "importfailed": "Не ўдалося імпартаваць: $1",
        "importunknownsource": "Невядомы тып імпартаванай крыніцы",
+       "importnoprefix": "Не пазначаны прэфікс інтэрвікі",
        "importcantopen": "Немагчыма адкрыць файл імпарту",
        "importbadinterwiki": "Кепская спасылка interwiki",
        "importsuccess": "Імпартаванне скончана!",
        "tooltip-pt-mycontris": "Пералік {{GENDER:|вашага}} ўкладу",
        "tooltip-pt-anoncontribs": "Спіс правак, зробленых з гэтага IP-адраса",
        "tooltip-pt-login": "Вам прапануецца ўвайсці ў сістэму, але гэта неабавязкова.",
+       "tooltip-pt-login-private": "Вы павінны ўвайсці ў, каб выкарыстоўваць гэтую вікі",
        "tooltip-pt-logout": "Выйсці з сістэмы",
        "tooltip-pt-createaccount": "Вам прапануецца стварыць уліковы запіс і ўвайсці ў сістэму, але гэта не абавязкова",
        "tooltip-ca-talk": "Размовы пра змест гэтай старонкі",
        "newimages-summary": "Тут паказаныя нядаўна ўкладзеныя файлы.",
        "newimages-legend": "Фільтр",
        "newimages-label": "Назва файла (або яе частка):",
+       "newimages-user": "Адрас IP або імя ўдзельніка",
+       "newimages-newbies": "Паказаць толькі ўклады з новых рахункаў",
        "newimages-showbots": "Паказваць укладанні ботамі",
        "newimages-hidepatrolled": "Без паказу ўхваленых ўкладанняў",
+       "newimages-mediatype": "Тып медиафайла:",
        "noimages": "Тут нічога няма.",
+       "gallery-slideshow-toggle": "Переключить мініяцюры",
        "ilsubmit": "Знайсці",
        "bydate": "п. датаў",
        "sp-newimages-showfrom": "Паказаць новыя файлы, пачынаючы з $2, $1",
        "confirmrecreate-noreason": "{{GENDER:$1|Удзельнік|Удзельніца}} [[User:$1|$1]] ([[User talk:$1|размовы]]) {{GENDER:$1|сцёр|сцёрла}} гэту старонку пасля таго, як вы пачалі яе рэдагаваць.\nКалі ласка, пацвердзіце, што вы сапраўды жадаеце аднавіць гэтую старонку.",
        "recreate": "Аднавіць",
        "unit-pixel": "крпк",
+       "confirm-purge-title": "Ачысціць кэш гэтай старонкі",
        "confirm_purge_button": "ОК",
        "confirm-purge-top": "Ці ачысціць кэш для гэтай старонкі?",
        "confirm-purge-bottom": "Асвяжэнне старонкі ачышчае копію ў кэшы і вымушае паказ самай новай версіі.",
        "autosumm-blank": "Выдаленне ўсяго зместу старонкі",
        "autosumm-replace": "Замена старонкі на '$1'",
        "autoredircomment": "Перасылае да [[$1]]",
+       "autosumm-removed-redirect": "Выдаленае перенаправление на [[$1]]",
        "autosumm-new": "Новая старонка: '$1'",
        "autosumm-newblank": "Створана пустая старонка",
        "lag-warn-normal": "Змены, зробленыя менш за $1 {{PLURAL:$1|сек.|сек.}} таму назад, могуць не трапіць у гэты спіс.",
        "watchlistedit-clear-titles": "Складнікі:",
        "watchlistedit-clear-submit": "Ачысціць спіс назірання (адкат будзе немагчымы!)",
        "watchlistedit-clear-done": "Ваш спіс назірання ачышчаны.",
+       "watchlistedit-clear-jobqueue": "Лік назіраных чысціцца. Гэта можа заняць некаторы час.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 складнік выняты|$1 складнікі выняты|$1 складнікаў вынята}}:",
        "watchlistedit-too-many": "Занадта шмат старонак, каб паказаць тут.",
        "watchlisttools-clear": "Ачысціць спіс назірання",
        "tag-filter-submit": "Фільтр",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Тэг|Тэгі}}]]: $2)",
        "tag-mw-contentmodelchange": "змена мадэлі змесціва",
+       "tag-mw-new-redirect": "Новае перенаправление",
+       "tag-mw-removed-redirect": "Выдаленае перанакіраванне",
+       "tag-mw-changed-redirect-target": "Змяненне мэты перенаправления",
+       "tag-mw-blank": "ачыстка",
+       "tag-mw-blank-description": "Праўкі, ачышчальныя гэтую старонку",
+       "tag-mw-replace": "Заменена",
+       "tag-mw-rollback": "адкат",
+       "tag-mw-undo": "адмена",
        "tags-title": "Біркі",
        "tags-intro": "Тут пералічаныя біркі, якімі праграмы могуць пазначыць праўку, а таксама іх значэнні.",
        "tags-tag": "Назва біркі",
        "compare-title-not-exists": "Не існуе названай вамі назвы.",
        "compare-revision-not-exists": "Паказанай вамі версіі не існуе.",
        "diff-form": "'''фармуляр'''",
+       "diff-form-oldid": "Стары ідэнтыфікатар версіі (неабавязкова)",
+       "diff-form-submit": "Паказаць адрозненні",
+       "permanentlink": "Пастаянная спасылка",
+       "permanentlink-revid": "ідэнтыфікатар праўкі",
+       "permanentlink-submit": "Перайсці да версіі",
        "dberr-problems": "Прабачце, на пляцоўцы здарыліся тэхнічныя цяжкасці.",
        "dberr-again": "Паспрабуйце перачытаць праз некалькі хвілін.",
        "dberr-info": "(Немагчыма звязацца з базай даных: $1)",
        "htmlform-cloner-create": "Дадаць яшчэ",
        "htmlform-cloner-delete": "Сцерці",
        "htmlform-cloner-required": "Неабходна хаця б адно значэнне.",
+       "htmlform-date-placeholder": "ГГГГ-ММ-ДД",
+       "htmlform-time-placeholder": "ЧЧ:ММ:СС",
+       "htmlform-datetime-placeholder": "ГГГГ-ММ-ДД ЧЧ:ММ:СС",
+       "htmlform-date-invalid": "Указанае вамі значэнне не похоже на дату. Паспрабуйце выкарыстоўваць фармат ГГГГ-ММ-ДД.",
+       "htmlform-datetime-invalid": "Вамі выбрана значэнне не падобна на дату і час. Паспрабуйце выкарыстоўваць фармат ГГГГ-ММ-ДД ГГ-ММ-СС.",
        "htmlform-title-badnamespace": "[[:$1]] не ў прасторы назваў \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" - немагчымы загаловак для старонкі",
        "htmlform-title-not-exists": "$1 не існуе.",
        "feedback-bugornote": "Калі вы гатовыя падрабязна апісаць тэхнічную праблему, калі ласка, [$1 паведаміце пра памылку].\nУ адваротным выпадку вы можаце выкарыстоўваць гэтую простую форму. Ваш каментар будзе дададзены на старонку «[$3 $2]» разам з вашым імем удзельніка і выкарыстоўваемым браўзерам.",
        "feedback-cancel": "Адмена",
        "feedback-close": "Зроблена.",
+       "feedback-external-bug-report-button": "адправіць тэхнічнае заданне",
        "feedback-dialog-title": "Даслаць водгук",
        "feedback-error1": "Памылка. Невядомы вынік з API",
        "feedback-error2": "Памылка. Збой праўкі",
        "feedback-error3": "Памылка. Няма адказу ад API",
+       "feedback-error4": "Памылка: Немагчыма размясціць запіс з паказаным загалоўкам зваротнай сувязі",
        "feedback-message": "Паведамленне",
        "feedback-subject": "Тэма:",
        "feedback-submit": "Даслаць",
        "feedback-thanks": "Дзякуй! Ваш водгук размешчаны на старонцы «[$2 $1]».",
        "feedback-thanks-title": "Дзякуем!",
+       "feedback-useragent": "Браўзэр:",
        "searchsuggest-search": "Шукаць у {{GRAMMAR:месны|{{SITENAME}}}}",
        "searchsuggest-containing": "змяшчае...",
        "api-error-badtoken": "Унутраная памылка: няслушны ключ.",
        "pagelang-language": "Мова",
        "pagelang-use-default": "Прадвызначаная мова",
        "pagelang-select-lang": "Выберыце мову",
+       "pagelang-reason": "Прычына",
        "pagelang-submit": "Адправіць",
        "right-pagelang": "Змяняць мову старонкі",
        "action-pagelang": "змяняць мову старонкі",
        "default-skin-not-found-no-skins": "Упс! Прадвызначаная вокладка для вашай вікі (<code>$wgDefaultSkin</code>), <code>$1</code>, недаступна.\n\nВы не ўстанавілі вокладкі.\n\n; Калі вы толькі што ўстанавілі ці абнавілі MediaWiki:\n: Магчыма, вы ўстанавілі з git, ці наўпрост з зыходнага коду, выкарыстаўшы іншы метад. Гэта нармальна. MediaWiki 1.24 і навейшыя не ўключаюць вокладкі ў асноўнае сховішча. Паспрабуйце ўстанавіць некалькі вокладак з [https://www.mediawiki.org/wiki/Category:All_skins каталога вокладак mediawiki.org], такім чынам:\n:* Узяўшы [https://www.mediawiki.org/wiki/Download tarball-інсталятар], які ўтрымлівае некалькі вокладак і прыставак. Вы можаце скапіяваць і ўставіць каталог <code>skins/</code> адтуль.\n:* Зрабіўшы клон аднаго з сховішчаў <code>mediawiki/skins/*</code> праз git у каталог <code>skins/</code> вашай інсталяцыі MediaWiki.\n: Калі вы распрацоўшчык MediaWiki, гэта не павінна адбіцца на вашым git-сховішчы. Гл. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя: Настройка вокладак] дзеля інфармацыі па ўключэнні вокладак і выбары прадвызначэння.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (уключана)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>выключана</strong>)",
+       "mediastatistics": "статыстыка медыя",
+       "mediastatistics-summary": "Статыстычная звесткі пра тыпы запампаваных файлаў. Статыстыка ўключае звесткі толькі пра апошнія версіі файлаўю Старыя або выдаленыя версіі файлаў не ўлічваюцца.",
+       "mediastatistics-bytespertype": "Агульны памер файлаў у гэтай секцыі: $1 {{PLURAL:$1|байт|байта|байт}} ($2; $3%).",
+       "mediastatistics-table-mimetype": "MIME-тып",
        "mediastatistics-table-extensions": "Магчымыя прыстаўкі",
        "mediastatistics-table-count": "Колькасць файлаў",
        "mediastatistics-table-totalbytes": "Агульны памер",
        "mediastatistics-header-unknown": "Невядомыя",
        "mediastatistics-header-bitmap": "Растравыя выявы",
-       "mediastatistics-header-drawing": "Рысункі (вектарныя выявы)",
+       "mediastatistics-header-drawing": "Малюнкі (вектарныя выявы)",
+       "mediastatistics-header-audio": "Аўдыё",
+       "mediastatistics-header-video": "Відэа",
+       "mediastatistics-header-multimedia": "Мультымедыя",
+       "mediastatistics-header-office": "Офісныя",
        "mediastatistics-header-text": "Тэкст",
+       "mediastatistics-header-executable": "Выкананыя",
        "mediastatistics-header-archive": "Сціснутыя фарматы",
        "mediastatistics-header-total": "Усе файлы",
        "json-error-state-mismatch": "Недапушчальны або некарэктны JSON",
index 9255bdf..7b3628f 100644 (file)
        "expansion-depth-exceeded-category-desc": "Страницата превишава максимално допустимата дълбочина на разгръщане.",
        "expansion-depth-exceeded-warning": "Страницата е превишила разрешената дълбочина на разгръщане",
        "parser-unstrip-loop-warning": "Открито е ''unstrip'' зацикляне",
-       "parser-unstrip-recursion-limit": "''Unstrip'' лимита на рекурсия превишава ($1)",
+       "unstrip-depth-warning": "''Unstrip'' лимита на рекурсия превишава ($1)",
        "undo-success": "Редакцията може да бъде върната.\nПрегледайте долното сравнение и се уверете, че наистина искате да го направите. След това съхранете страницата, за да извършите връщането.",
        "undo-failure": "Редакцията не може да бъде върната поради конфликтни междинни редакции.",
        "undo-norev": "Редакцията не може да бъде върната, тъй като не съществува или е била изтрита.",
        "ipb_expiry_old": "Срокът на изтичане е минал.",
        "ipb_expiry_temp": "Скритите потребителски имена трябва да се блокират безсрочно.",
        "ipb_hide_invalid": "Тази потребителска сметка не може да бъде прикрита; с нея са направени повече от {{PLURAL:$1|една редакция|$1 редакции}}.",
-       "ipb_already_blocked": "„$1“ е вече блокиран",
+       "ipb_already_blocked": "„$1“ е вече блокиран.",
        "ipb-needreblock": "$1 е вече блокиран. Желаете ли да промените настройките?",
        "ipb-otherblocks-header": "{{PLURAL:$1|Друго блокиране|Други блокирания}}",
        "unblock-hideuser": "Не можете да отблокирате този потребител, тъй като потребителското му име е скрито.",
index 9c2cf41..0157021 100644 (file)
        "expansion-depth-exceeded-category-desc": "تاکدیم که که آیی پراخئ جُهلئ شه اندازه گ ئا گیشتیر بوته.",
        "expansion-depth-exceeded-warning": "تاکدیم شه حداکثر بسط داتین عمق ئا تجاوز کورت",
        "parser-unstrip-loop-warning": "حلقه بی دستور unstrip ئی تا ودی نه بوت",
-       "parser-unstrip-recursion-limit": "شه حداکثر ارجاع بئ دستور unstrip ئی تا تجاوز بوت ($1)",
+       "unstrip-depth-warning": "شه حداکثر ارجاع بئ دستور unstrip ئی تا تجاوز بوت ($1)",
        "converter-manual-rule-error": "خطا بئ زانئ دستی ئین بدل کورتینی قوانین ئی تا",
        "undo-success": "ای ایڈیٹ ئا توانیت شه بین بَریت.\nمهربانی بکنیت جهلگی فرق ئا بگنیدیت و قبول بکنیت که آ چیزی است که شما ئه لوٹیت انجام دهیت،پدا جهلگئ تغیراتانا ذخیره بکنیت تا که ایڈیٹ ئی شه بین بورتینئ کار الاس بکنیت.",
        "undo-failure": "ایڈیٹ ئا نتوانتیت شه بین بَریت، بی خاتیرئ بعضی تعرض ئان یا میانئ ئین ایڈیٹان.",
index f03f266..93f1abc 100644 (file)
        "expansion-depth-exceeded-category-desc": "पन्ना अधिकतम बिस्तार गहिराई के पार क गइल बा।",
        "expansion-depth-exceeded-warning": "पन्ना अधिकतम बिस्तार गहिराई के पार क गइल",
        "parser-unstrip-loop-warning": "अनस्ट्रिप लूप पकड़ में आइल बा",
-       "parser-unstrip-recursion-limit": "अनस्ट्रिप रिकर्शन सीमा पार हो गइल ($1)",
+       "unstrip-depth-warning": "अनस्ट्रिप रिकर्शन सीमा पार हो गइल ($1)",
        "converter-manual-rule-error": "मैनुअल भाषा परिवर्तन नियम में खराबी पकड़ल गइल",
        "undo-success": "संपादन वापस कइल जा सकत बा।\nनीचे दिहल तुलना के चेक करीं आ पुष्टी करीं की आप इहे कइल चाहत बाड़ीं, ओकरा बाद बदलाव सहेज के संपादन वापसी के पूरा करीं।",
        "undo-failure": "बीच में अउरी संपादन होखला की कारण ई संपादन वापस नइखे लिहल जा सकत।",
index 003966a..bcceb8f 100644 (file)
        "expansion-depth-exceeded-category-desc": "পাতাটি সর্বোচ্চ এক্সপশন সীমানা অতিক্রম করেছে।",
        "expansion-depth-exceeded-warning": "পাতাটি এক্সেপশন সীমানা অতিক্রম করেছে",
        "parser-unstrip-loop-warning": "ত্রুটিপূর্ণ লুপ খুঁজে পাওয়া গিয়েছে",
-       "parser-unstrip-recursion-limit": "লুপ রিকারশন সীমানা অতিক্রম করেছে ($1)",
+       "unstrip-depth-warning": "লুপ রিকারশন সীমানা অতিক্রম করেছে ($1)",
        "converter-manual-rule-error": "ম্যানুয়াল ভাষা রূপান্তর নিয়মে ত্রুটি পাওয়া গিয়েছে",
        "undo-success": "সম্পাদনাটি বাতিল করা যাবে। অনুগ্রহ করে নিচের তুলনাটি পরীক্ষা করে দেখুন ও নিশ্চিত করুন যে এটাই আপনি করতে চান, এবং তারপর নিচের সম্পাদনাগুলি সংরক্ষণ করে সম্পাদনাটির বাতিল প্রক্রিয়া সমাপ্ত করুন।",
        "undo-failure": "এ সম্পাদনা মধ্যবর্তী সম্পাদনাসমূহের কারণে পূর্বাবস্থায় ফিরিয়ে নেওয়া যাবে না।",
        "thumbnail_dest_directory": "গন্তব্য ডিরেক্টরি তৈরি করা যায়নি",
        "thumbnail_image-type": "চিত্রের ধরন সমর্থন করে না",
        "thumbnail_gd-library": "অসম্পূর্ণ জিডি লাইব্রেরী কনফিগারেশন: $1 ফাংশন নেই",
+       "thumbnail_image-size-zero": "চিত্রের ফাইলের আকার শূন্য বলে মনে হচ্ছে।",
        "thumbnail_image-missing": "ফাইলটি খুজে পাওয়া যাচ্ছে না: $1",
        "thumbnail_image-failure-limit": "সাম্প্রতিককালে এই ক্ষুদ্র প্রাকপ্রদর্শনমূলক চিত্রটিকে (thumbnail) রেন্ডার করার চেষ্টা অত্যধিকবার ($1 বা তার বেশিবার) ব্যর্থ হয়েছে। অনুগ্রহ করে কিছুক্ষণ পরে আবার চেষ্টা করুন।",
        "import": "পাতা আমদানি",
        "import-mapping-subpage": "নিচের পাতার উপপাতাসমূহ হিসাবে আমদানি করুন:",
        "import-upload-filename": "ফাইলনাম:",
        "import-upload-username-prefix": "আন্তঃউইকি উপসর্গ:",
+       "import-assign-known-users": "ব্যবহারকারী স্থানীয়ভাবে থাকলে তার নামে সম্পাদনা অর্পণ করুন",
        "import-comment": "মন্তব্য:",
        "importtext": "অনুগ্রহ করে ফাইলটি উৎস উইকি থেকে [[Special:Export|রপ্তানি ইউটিলিটি]] ব্যবহার করে রপ্তানি করুন।\nফাইলটি আপনার কম্পিউটারে সংরক্ষণ করুন এবং এখানে আপলোড করুন।",
        "importstart": "পাতা আমদানি করা হচ্ছে...",
        "watchlistedit-clear-titles": "শিরোনামসমূহ:",
        "watchlistedit-clear-submit": "নজরতালিকা পরিষ্কার করুন (এটি স্থায়ী!)",
        "watchlistedit-clear-done": "আপনার নজরতালিকা পরিষ্কার করা হয়েছে।",
+       "watchlistedit-clear-jobqueue": "আপনার নজরতালিকা পরিষ্কার করা হচ্ছে। এটি কিছু সময় নিতে পারে!",
        "watchlistedit-clear-removed": "{{PLURAL:$1|১টি শিরোনাম|$1টি শিরোনাম}} সরিয়ে ফেলা হয়েছে:",
        "watchlistedit-too-many": "এখানে প্রদর্শনের জন্য অনেক পাতা রয়েছে।",
        "watchlisttools-clear": "নজরতালিকা পরিষ্কার করুন",
        "tag-mw-rollback": "পুনর্বহাল",
        "tag-mw-rollback-description": "সম্পাদনাগুলি যা রোলব্যাক সংযোগ ব্যবহার করে পূর্বের সম্পাদনায় ফেরত নেয়",
        "tag-mw-undo": "পূর্বাবস্থায় ফেরত",
+       "tag-mw-undo-description": "সম্পাদনা পূর্বাবস্থায় আনার লিঙ্ক ব্যবহার করে পূর্বাবস্থায় আনা সম্পাদনাগুলি",
        "tags-title": "ট্যাগসমূহ",
        "tags-intro": "এই পাতায় সফটওয়্যারটি একটি সম্পাদনা চিহ্নিত করার জন্য যে সকল ট্যাগ ব্যবহার করে তার তালিকা ও বর্ণনা রয়েছে।",
        "tags-tag": "ট্যাগ নাম",
index 70594d3..736ee00 100644 (file)
        "expansion-depth-exceeded-category-desc": "En tu all d'an donder astenn brasañ emañ ar bajenn.",
        "expansion-depth-exceeded-warning": "Pajenn a ya dreist d'an donder astenn",
        "parser-unstrip-loop-warning": "Detektet ez eus bet ul lagadenn n'haller ket divontañ",
-       "parser-unstrip-recursion-limit": "Aet dreist d'ar vevenn rekurziñ n'haller ket divontañ : $1",
+       "unstrip-depth-warning": "Aet dreist d'ar vevenn rekurziñ n'haller ket divontañ : $1",
        "converter-manual-rule-error": "Fazi dinodet  er reolenn cheñch yezh dre zorn",
        "undo-success": "Gallout a reer dizober ar c'hemmoù-mañ. Gwiriit, mar plij, gant ar geñveriadenn a-is evit bezañ sur eo an dra-se a fell deoc'h ober; goude-se enrollit ar c'hemmoù a-is a-benn echuiñ disteurel ar c'hemmoù.",
        "undo-failure": "N'eus ket bet tu da zisteuler ar c'hemm-mañ abalamour d'un tabut gant kemmoù degaset e-keit-se.",
index a015b14..fad50b2 100644 (file)
        "expansion-depth-exceeded-category-desc": "Stranica je prešla najveću dubinu proširenja.",
        "expansion-depth-exceeded-warning": "Stranice koje su prekoračile dubinu proširenja",
        "parser-unstrip-loop-warning": "Pronađena petlja",
-       "parser-unstrip-recursion-limit": "Prekoračeno ograničenje rekurzije ($1)",
+       "unstrip-depth-warning": "Prekoračeno ograničenje rekurzije ($1)",
        "converter-manual-rule-error": "Pronađena je greška u pravilu za ručno pretvaranje jezika",
        "undo-success": "Izmjenu je moguće poništiti.\nMolimo da ispod uporedite razlike u verzijama kako biste bili sigurni da ovo zaista želite uraditi, te sačuvajte stranicu i izmjene će biti poništene.",
        "undo-failure": "Ova izmjena se ne može poništiti jer se međuverzije sukobe.",
index 4fe01e6..0e578c3 100644 (file)
        "expansion-depth-exceeded-category-desc": "La pàgina ha excedit la profunditat màxima d'expansió.",
        "expansion-depth-exceeded-warning": "La pàgina ha excedit la profunditat d'expansió",
        "parser-unstrip-loop-warning": "S'ha detectat un bucle no desmuntable",
-       "parser-unstrip-recursion-limit": "S'ha excedit el límit ($1) de recursivitat no desmuntable",
+       "unstrip-depth-warning": "S'ha excedit el límit ($1) de recursivitat no desmuntable",
        "converter-manual-rule-error": "Error detectat a la norma de conversió de llengua manual",
        "undo-success": "Pot desfer-se la modificació. Si us plau, reviseu la comparació de sota per a assegurar-vos que és el que voleu fer; llavors deseu els canvis per a finalitzar la desfeta de l'edició.",
        "undo-failure": "No pot desfer-se la modificació perquè hi ha edicions intermèdies en conflicte.",
        "allpages": "Totes les pàgines",
        "nextpage": "Pàgina següent ($1)",
        "prevpage": "Pàgina anterior ($1)",
-       "allpagesfrom": "Mostra les pàgines que comencin per:",
-       "allpagesto": "Mostra pàgines que acabin en:",
+       "allpagesfrom": "Mostra les pàgines a partir de:",
+       "allpagesto": "Mostra les pàgines fins a:",
        "allarticles": "Totes les pàgines",
        "allinnamespace": "Totes les pàgines (de l’espai de noms $1)",
        "allpagessubmit": "Vés-hi",
index 964b9e4..9616cbe 100644 (file)
@@ -57,8 +57,8 @@
        "tog-showhiddencats": "Гайта къайлаха йолу категореш",
        "tog-norollbackdiff": "Юха яьккхиначул тӀаьхьа ма гайта версийн башхо",
        "tog-useeditwarning": "Хаамбе бина хийцамаш дӀаязцабеш аса болх дӀатосучу хенахь",
-       "tog-prefershttps": "СиÑ\81Ñ\82емин Ð´Ð¾Ð²Ð·Ð¸Ð¹Ñ\82ина Ñ\87Ñ\83л Ñ\82Ó\80еÑ\85Ñ\8cа Ð´Ð°Ð¸Ð¼Ð°Ð½ Ð»ÐµÐ»Ð°Ð´Ðµ Ð»Ð°Ñ\80дина Ð²Ð¾Ð²Ñ\88аÑ\85Ñ\82аÑ\81ар",
-       "underline-always": "Ð\94аимна",
+       "tog-prefershttps": "Ð\93Ñ\83Ñ\82Ñ\82аÑ\80а Ð»ÐµÐ»Ð°Ð´Ðµ ÐºÑ\85еÑ\80амза Ñ\82аÑ\81далар",
+       "underline-always": "Ð\93Ñ\83Ñ\82Ñ\82аÑ\80",
        "underline-never": "Цкъа а",
        "underline-default": "Лелае браузеран нисярца",
        "editfont-style": "Тадар чохь долу шрифт:",
        "history_short": "Истори",
        "history_small": "истори",
        "updatedmarker": "Керла яккхина сона гинчултӀаьхьа",
-       "printableversion": "Зорба туху верси",
-       "permalink": "Ð\94аиман Ð¹Ð¾Ð»Ñ\83 хьажорг",
+       "printableversion": "Зорбанан верси",
+       "permalink": "ЦаÑ\85ийÑ\86алÑ\83н хьажорг",
        "print": "Зорба тоха",
        "view": "Хьажа",
        "view-foreign": "Сайтехь $1 хьажа",
        "noemailcreate": "Ахьа нийса электронан поштан адрес дӀаяздан деза",
        "passwordsent": "Керла пароль декъашхочун $1 электронан адрес тӀе дӀахьажина. Дехар до, керла пароль еъча юху системин чугӀо.",
        "blocked-mailpassword": "Хьан IP-адрес ца тадарш дан магийна дац, цуьндела пароль меттахӀотош йолу функци блоктоьхна ю.",
-       "eauthentsent": "Ð\94Ó\80аÑ\8fздинÑ\87Ñ\83 Ñ\8dлекÑ\82Ñ\80онан Ð°Ð´Ñ\80еÑ\81 Ñ\82Ó\80е Ñ\85аам Ð±Ð°Ð¸Ð¹Ñ\82ина.\nÐ\94аиман хаамаш баийта хааман чохь де бохург дан деза адрес хьай хилар бакъдеш.",
+       "eauthentsent": "Ð\94Ó\80аÑ\8fздинÑ\87Ñ\83 Ñ\8dлекÑ\82Ñ\80онан Ð°Ð´Ñ\80еÑ\81 Ñ\82Ó\80е Ñ\85аам Ð±Ð°Ð¸Ð¹Ñ\82ина.\nÐ\93Ñ\83Ñ\82Ñ\82аÑ\80а хаамаш баийта хааман чохь де бохург дан деза адрес хьай хилар бакъдеш.",
        "throttled-mailpassword": "Пароль дага йоуьйту функци {{PLURAL:$1|тӀаьххьара $1 сахьтехь}} лелина.\nЗулам цахилийта $1 {{PLURAL:$1|сахьтан чохь}} цӀа бен функци лело йиш яц.",
        "mailerror": "Кехат дохьуьйтуш гӀалат ду: $1",
        "acct_creation_throttle_hit": "Де-буьйса хена чохь хьа IP-адрес тӀера {{PLURAL:$1|кхоьллина $1 декъашхочун дӀаяздар|кхоьллина $1 декъашхочун дӀаяздарш}} оьцу хана юкъахь кхин дукха дӀаяздарш кхолла магийна дац.\nЦундела и IP-адрес лелочарна кхин керла дӀаяздарш кхолла цало.",
        "rcfilters-liveupdates-button-title-off": "Керла хийцамаш ма-бинехь гайта",
        "rcfilters-preference-label": "Керла хийцамийн дика кечйина верси къайлаяккха",
        "rcfilters-preference-help": "2017 шеран интерфейсан редизайн а, оцу хенахь дуьйна тӀетоьхна гӀирсаш а къайлайоху.",
+       "rcfilters-filter-showlinkedfrom-label": "Хьажоргаш йолучу агӀонашна тӀехь нисдарш гайта",
+       "rcfilters-filter-showlinkedfrom-option-label": "<strong>Хаьржиначунна хьажоргаш йолу агӀонаш</strong>",
+       "rcfilters-filter-showlinkedto-label": "Хьажоргаш йолучу агӀонашна тӀехь нисдарш гайта",
        "rcnotefrom": "Лахахь гайтина тӀера <strong>$2</strong> (хийцамаш <strong>$1</strong> кӀезиг).",
        "rclistfromreset": "Терахь харжар дӀадаккха",
        "rclistfrom": "Гайта хийцам {{CURRENTYEAR}} шеран {{CURRENTDAY}} {{CURRENTMONTHNAMEGEN}} {{CURRENTTIME}} бина болу",
        "rc-enhanced-expand": "Гайта мадарра",
        "rc-enhanced-hide": "Ма дарра дерг къайладаккха",
        "rc-old-title": "дуьххьара кхоьллина яра «$1» цӀарца",
-       "recentchangeslinked": "Ð\9aÑ\85Ñ\83Ñ\8cнÑ\86а Ð´Ð¾Ð»Ñ\83 нисдарш",
-       "recentchangeslinked-feed": "Ð\9aÑ\85Ñ\83Ñ\8cнÑ\86а Ð´Ð¾Ð»Ñ\83 нисдарш",
-       "recentchangeslinked-toolbox": "Ð\9aÑ\85Ñ\83Ñ\8cнÑ\86а Ð´Ð¾Ð»Ñ\83 нисдарш",
-       "recentchangeslinked-title": "Ð\9aÑ\85Ñ\83Ñ\8cнÑ\86а Ð´Ð¾Ð»Ñ\83 Ð½Ð¸Ñ\81даÑ\80Ñ\88 $1",
+       "recentchangeslinked": "Ð\94иÑ\85кина нисдарш",
+       "recentchangeslinked-feed": "Ð\94иÑ\85кина нисдарш",
+       "recentchangeslinked-toolbox": "Ð\94иÑ\85кина нисдарш",
+       "recentchangeslinked-title": "Ð\94иÑ\85кина Ð½Ð¸Ñ\81даÑ\80Ñ\88 Â«$1»",
        "recentchangeslinked-summary": "ХӀара хийцам биначу агӀонийн могӀам бу, тӀетовжар долуш хьагучу агӀон (я хьагойтуш йолучу категорена).\nАгӀонаш юькъа йогӀуш йолу хьан [[Special:Watchlist|тергаме могӀам чохь]] '''къастийна ю'''.",
        "recentchangeslinked-page": "АгӀон цӀе:",
        "recentchangeslinked-to": "Кхечу агӀор, гайта хийцамаш агӀонашца, хӀоттийначу агӀонтӀе хьажорг йолуш",
        "tooltip-t-emailuser": "ДӀабахьийта хаам оцу декъашхона",
        "tooltip-t-upload": "Чуйаха файлаш",
        "tooltip-t-specialpages": "Белхан агӀонанийн могӀам",
-       "tooltip-t-print": "Ð¥Ó\80окÑ\85Ñ\83 Ð°Ð³Ó\80онна Ð·Ð¾Ñ\80ба Ñ\82Ñ\83Ñ\85Ñ\83 Ð±Ð°Ñ\88Ñ\85о",
-       "tooltip-t-permalink": "Ð\94аима Ð¹Ð¾Ð»Ñ\83 Ñ\85Ñ\8cажоÑ\80г Ñ\85Ó\80окÑ\85Ñ\83 Ð±Ð°Ñ\88Ñ\85а Ð°Ð³Ó\80онна",
+       "tooltip-t-print": "Ð¥Ó\80окÑ\85Ñ\83 Ð°Ð³Ó\80она Ð·Ð¾Ñ\80банан Ð²ÐµÑ\80Ñ\81и",
+       "tooltip-t-permalink": "Ð¥Ó\80окÑ\85Ñ\83 Ð°Ð³Ó\80она Ð²ÐµÑ\80Ñ\81ин Ñ\82Ó\80е Ñ\86аÑ\85ийÑ\86алÑ\83н Ñ\85Ñ\8cажоÑ\80г",
        "tooltip-ca-nstab-main": "Коьрта яззаман чулацам",
        "tooltip-ca-nstab-user": "ХӀора декъашхочун долахь йолу агӀо ю",
        "tooltip-ca-nstab-media": "Медиа-файл",
        "pageinfo-hidden-categories": "{{PLURAL:$1|Къайла категори|Къайла категореш}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|1=Кеп|Кепаш}} ($1)",
        "pageinfo-transclusions": "{{PLURAL:$1|1=Юкъатохало агӀо|Юкъатохало агӀонаш}} ($1)",
-       "pageinfo-toolboxlink": "Агlонах болу бовзам",
+       "pageinfo-toolboxlink": "АгӀонан хаам",
        "pageinfo-redirectsto": "ДӀасахьажорг",
        "pageinfo-redirectsto-info": "Хаам",
        "pageinfo-contentpage": "Лорурго чулацаме гойту агӀо",
        "yesterday-at": "селхана $1 даьлча",
        "bad_image_list": "Барам хила беза иштта:\n\nЛораш хира ю могӀамяхь йолу элементнаш (могӀийн, йола луш йолу символ тӀира *).\nДуьххьаралера хьажорг магӀанийн хила беза хьажорг кху цамагдо сурт дуьлаче.\nТӀехьа йогӀуш йолу хьажорг оцу могӀарехь хира ю магóш, билгалла аьлча яззамаш долуче, сурт хьаллаточехь.",
        "metadata": "Метахаамаш",
-       "metadata-help": "Ð¥Ó\80окÑ\85Ñ\83 Ñ\84айлаÑ\86а ÐºÑ\85ин Ñ\82Ó\80е Ñ\85аам Ð±Ñ\83, Ð´Ð°Ð¸Ð¼Ð°Ð½ чуйоккхуш йолу терахьца чоьнашца йа тӀейоккхучуьнца. Нагахь файлан тӀаьхьа хийцам биняхь, тӀаккха цӀхьаболу барам цӀхьаьна ца ба мега хӀинцалера суьртаца.",
+       "metadata-help": "Ð¥Ó\80окÑ\85Ñ\83 Ñ\84айлаÑ\86а ÐºÑ\85ин Ñ\82Ó\80е Ñ\85аам Ð±Ñ\83, Ð³Ñ\83Ñ\82Ñ\82аÑ\80а чуйоккхуш йолу терахьца чоьнашца йа тӀейоккхучуьнца. Нагахь файлан тӀаьхьа хийцам биняхь, тӀаккха цӀхьаболу барам цӀхьаьна ца ба мега хӀинцалера суьртаца.",
        "metadata-expand": "Гайта кхин тlе болу хаам",
        "metadata-collapse": "Къайла баккха кхин тlе болу хаам",
        "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",
        "diff-form-oldid": "Версин шира идентификатор (тӀехь дац)",
        "diff-form-revid": "Башхаллаш йолу версин идентификатор",
        "diff-form-submit": "Схьагайта башхаллаш",
-       "permanentlink": "Ð\94аиман Ð¹Ð¾Ð»Ñ\83 хьажорг",
+       "permanentlink": "ЦаÑ\85ийÑ\86алÑ\83н хьажорг",
        "permanentlink-revid": "Нисдаран ID",
        "permanentlink-submit": "Хьажа версега",
        "dberr-problems": "Бехк ма бил! ХӀокху сайтехь техникан халонаш хила.",
        "htmlform-user-not-exists": "<strong>$1</strong> яц.",
        "htmlform-user-not-valid": "<strong>$1</strong> — декъашхочун магийна йоцу цӀе.",
        "logentry-delete-delete": "$1 {{GENDER:$2|дӀаяьккхина}} агӀо $3",
-       "logentry-delete-delete_redir": "$1 {{GENDER:$2|дӀаяьккхина}} $3 дӀасахьажорг гӀоьнца",
+       "logentry-delete-delete_redir": "$1 {{GENDER:$2|дӀаяьккхина}} $3 дӀасахьажорг тӀехула дӀаязйина",
        "logentry-delete-restore": "$1 {{GENDER:$2|меттахӀоттайина|меттахӀоттайина}} агӀо $3",
        "logentry-delete-event": "$1 {{GENDER:$2|хийцина}} гуш хилар {{PLURAL:$5|1=$5 дӀаяздаран|$5 дӀаяздаршан}} тептаран → $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|хийцина}} {{PLURAL:$5|1=$5 верси|$5 версеш}} гуш хилар $3: $4 агӀорахь",
index e553d4a..d023d8e 100644 (file)
        "expansion-depth-exceeded-category-desc": "Stránka překročila maximální hloubku expanze.",
        "expansion-depth-exceeded-warning": "Stránka překročila hloubku expanze",
        "parser-unstrip-loop-warning": "Detekováno zacyklení unstrip",
-       "parser-unstrip-recursion-limit": "Překročen limit rekurze unstrip ($1)",
+       "unstrip-depth-warning": "Překročen limit rekurze unstrip ($1)",
        "converter-manual-rule-error": "Detekována chyba v pravidlech manuální jazykové konverze",
        "undo-success": "Editace může být zrušena. Zkontrolujte a pak potvrďte změny zobrazené níže.",
        "undo-failure": "Editace nemohla být zrušena kvůli konfliktu mezilehlých editací.",
index f4f377b..2ecc67a 100644 (file)
        "expansion-depth-exceeded-category-desc": "Mae'r dudalen yn rhy fawr!",
        "expansion-depth-exceeded-warning": "Mae dyfnder ehangu'r dudalen y tu hwnt i'r terfyn",
        "parser-unstrip-loop-warning": "Wedi darganfod dolen dad-blicio (unstrip loop)",
-       "parser-unstrip-recursion-limit": "Wedi mynd dros ben y terfyn ar ddychweliad dad-blicio (unstrip recursion) ($1)",
+       "unstrip-depth-warning": "Wedi mynd dros ben y terfyn ar ddychweliad dad-blicio (unstrip recursion) ($1)",
        "converter-manual-rule-error": "Cafwyd hyd i wall yn y rheol trosi iaith â llaw",
        "undo-success": "Gellir dadwneud y golygiad. Byddwch gystal â gwirio'r gymhariaeth isod i sicrhau mai dyma sydd arnoch eisiau gwneud, ac yna rhowch y newidiadau ar gadw i gwblhau'r gwaith o ddadwneud y golygiad.",
        "undo-failure": "Methwyd a dadwneud y golygiad oherwydd gwrthdaro â golygiadau cyfamserol.",
index f30cdab..f92c660 100644 (file)
        "expansion-depth-exceeded-category-desc": "Siden overskrider den maksimale udvidelsesdybde.",
        "expansion-depth-exceeded-warning": "Siden overskred ekspansionsdybden",
        "parser-unstrip-loop-warning": "Unstrip-loop opdaget",
-       "parser-unstrip-recursion-limit": "Unstrip rekursionsgrænse er nået ($1)",
+       "unstrip-depth-warning": "Unstrip rekursionsgrænse er nået ($1)",
        "converter-manual-rule-error": "Fejl opdaget i manuel sprogkonvertingsregel",
        "undo-success": "Redigeringen kan fjernes.\nKontroller venligst sammenligningen herunder for at bekræfte at det er hvad du ønsker at gøre, og gem så ændringerne for at fuldføre fjernelsen.",
        "undo-failure": "Redigeringen kunne ikke fjernes på grund af konflikter med efterfølgende redigeringer.",
index ef9a2e8..9a92ef2 100644 (file)
        "expansion-depth-exceeded-category-desc": "Die Seite überschreitet die maximale Expandierungstiefe.",
        "expansion-depth-exceeded-warning": "Die Seite hat die Expansionstiefe überschritten.",
        "parser-unstrip-loop-warning": "Zirkelbezug festgestellt",
-       "parser-unstrip-recursion-limit": "Rekursionsgrenze beim Auflösen überschritten ($1)",
+       "unstrip-depth-warning": "Rekursionsgrenze beim Auflösen überschritten ($1)",
+       "unstrip-depth-category": "Seiten, auf denen die Unstrip-Tiefengrenze überschritten ist.",
        "converter-manual-rule-error": "Bei der manuellen Sprachkonvertierungsregel wurde ein Fehler entdeckt.",
        "undo-success": "Die Bearbeitung kann rückgängig gemacht werden.\nBitte prüfe den Vergleich unten, um sicherzustellen, dass du dies tun möchtest, und speichere dann unten deine Änderungen, um die Bearbeitung rückgängig zu machen.",
        "undo-failure": "Die Änderung konnte nicht rückgängig gemacht werden, da der betroffene Abschnitt zwischenzeitlich verändert wurde.",
index 131d189..f9ac094 100644 (file)
        "history_small": "tarix",
        "updatedmarker": "cı kewtena mına peyêne ra dıme biyo rocane",
        "printableversion": "Versiyonê çapkerdışi",
-       "permalink": "Gıreyo vınderde",
+       "permalink": "Gıreyo daimi",
        "print": "Bınuşne",
        "view": "Bıvin",
        "view-foreign": "$1 de bıvin",
        "expansion-depth-exceeded-category": "Perrê ke xoriyiya herabiyayışi tede ravêrdeya.",
        "expansion-depth-exceeded-warning": "Ravêriya pela xori herayêna",
        "parser-unstrip-loop-warning": "Unstrip lete vineya",
-       "parser-unstrip-recursion-limit": "Sinorê limit dê qayış dê ($1) ravêrya",
+       "unstrip-depth-warning": "Sinorê limit dê qayış dê ($1) ravêrya",
        "converter-manual-rule-error": "Rehberê zıwan açarnayışi dı xırabin tesbit biya",
        "undo-success": "No vurnayiş tepeye geryeno. pêverronayişêyê cêrıni kontrol bıkeri.",
        "undo-failure": "Poxta pëverameyişa vurnayişan ra  peyd grotışë kari në bı",
        "compare-title-not-exists": "Sernameyo ke şımayê vanê mewcud niyo.",
        "compare-revision-not-exists": "Revizyono ke şımaye vanê mewcud niyo.",
        "diff-form": "yew '''form'''",
+       "permanentlink": "Gıreyo daimi",
        "dberr-problems": "Mayê muxulêm! Ena sita dı newke xırabiya teknik esta.",
        "dberr-again": "Dı-rê deqiqeyi vınde û heni bar ke.",
        "dberr-info": "(Erzmelumati ra xızmetkari nêreseno: $1)",
index e0326de..1e89bbf 100644 (file)
        "expansion-depth-exceeded-category": "Boki, źož ekspansiska dłymokosć jo pśekšocona",
        "expansion-depth-exceeded-warning": "Bok jo ekspansisku dłymokosć pśekšocył",
        "parser-unstrip-loop-warning": "Njeskóńcna kokula namakana",
-       "parser-unstrip-recursion-limit": "Rekursiska granica pśekšocona ($1)",
+       "unstrip-depth-warning": "Rekursiska granica pśekšocona ($1)",
        "converter-manual-rule-error": "Zmólka w manuelnem pšawidle rěcnego konwertěrowanja namakana",
        "undo-success": "Wobźěłanje móžo se wótpóraś. Pšosym pśeglěduj dołojcne pśirownowanje aby se wěsty był, až to wót wěrnosći coš, a pón składuj změny, aby se wobźěłanje doskóńcnje wótpórało.",
        "undo-failure": "Změna njejo se mógała wótpóraś, dokulaž jo něchten pótrjefjony wótrězk mjaztym změnił.",
index ec399fd..df4faa6 100644 (file)
        "expansion-depth-exceeded-category-desc": "ये पानाले उच्चतम विस्तार सिमा नाघ्या छ ।",
        "expansion-depth-exceeded-warning": "पानाले सल्दिले सिमालाई नाघ्या छ",
        "parser-unstrip-loop-warning": "अनस्ट्रिप लुप धेखिन्छ",
-       "parser-unstrip-recursion-limit": "अन्स्ट्रिप पुनरावर्तन सिमा पार गरियो ($1)",
+       "unstrip-depth-warning": "अन्स्ट्रिप पुनरावर्तन सिमा पार गरियो ($1)",
        "converter-manual-rule-error": "म्यानुअल भाषा अनुवाद सिध्दान्तमी समस्या धेखियो",
        "viewpagelogs": "यै पानाका लगहरू हेर",
        "nohistory": "ये पृष्ठका लागी कोइ सम्पादन इतिहास छैन।",
index b11a058..1202ecc 100644 (file)
        "expansion-depth-exceeded-category-desc": "La pàgina la và d'ed là dal fònd mâsim de slarghêda.",
        "expansion-depth-exceeded-warning": "Cla pàgina ché la pasê al fònd de şlargamèint",
        "parser-unstrip-loop-warning": "Catê sèria 'd Unistrip",
-       "parser-unstrip-recursion-limit": "A s'é pasê i lémit 'd arciâm 'd Unstrip ($1)",
+       "unstrip-depth-warning": "A s'é pasê i lémit 'd arciâm 'd Unstrip ($1)",
        "converter-manual-rule-error": "È stê catê un erōr int la règola a mân ed cambiamèint ed la léngua",
        "undo-success": "Cla mudéfica ché la pō, èser scanşlêda., Cuntròla che sòta al diferèinsi che gh'é tr' al dō versiòun per èser sicûr che còl che gh'é scrét al cumbîna cun còl ch'ét vō, e dòunca salvêr al mudéfici per finîr la scanşladûra.",
        "undo-failure": "Imposébil scanşlêr la mudéfica a câşva 'd un cuntrâst cun dal mudéfichi fâti dôp.",
index 2ebb094..daa5066 100644 (file)
        "expansion-depth-exceeded-category-desc": "Η σελίδα υπερβαίνει το μέγιστο βάθος επέκτασης.",
        "expansion-depth-exceeded-warning": "Η σελίδα υπερέβη το βάθος επέκτασης",
        "parser-unstrip-loop-warning": "εντοπίστηκε ένας βρόχος unstrip",
-       "parser-unstrip-recursion-limit": "Υπέρβαση του ορίου αναδρομής Unstrip ($1)",
+       "unstrip-depth-warning": "Υπέρβαση του ορίου αναδρομής Unstrip ($1)",
        "converter-manual-rule-error": "Εντοπίστηκε σφάλμα σε μη αυτόματο κανόνα μετατροπής γλώσσας",
        "undo-success": "Η επεξεργασία μπορεί να αναιρεθεί.\nΠαρακαλούμε ελέγξτε την σύγκριση παρακάτω για να επιβεβαιώσετε ότι είναι αυτό το οποίο θέλετε να κάνετε και έπειτα αποθηκεύστε τις αλλαγές παρακάτω για να ολοκληρώσετε την αναίρεση της επεξεργασίας.",
        "undo-failure": "Η επεξεργασία δεν μπορούσε να αναστραφεί λόγω αντικρουόμενων ενδιάμεσων επεξεργασιών.",
        "rcfilters-filter-watchlist-watched-label": "Στην λίστα παρακολούθησης",
        "rcfilters-filter-watchlist-watched-description": "Αλλαγές σελίδων στην λίστα παρακολούθησης σας",
        "rcfilters-filter-watchlist-watchednew-label": "Νέες αλλαγές λίστας παρακολούθησης",
+       "rcfilters-filter-watchlist-watchednew-description": "Έχουν συμβεί αλλαγές σε σελίδες που παρακολουθείτε τις οποίες δεν έχετε επισκεφθεί από τότε.",
        "rcfilters-filter-watchlist-notwatched-label": "Εκτός λίστας παρακολούθησης",
        "rcfilters-filter-watchlist-notwatched-description": "Τα πάντα εκτός από τις αλλαγές των σελίδων στην λίστα παρακολούθησης σας.",
        "rcfilters-filtergroup-watchlistactivity": "Δραστηριότητα λίστας παρακολούθησης",
        "rcfilters-filter-previousrevision-label": "Μη πρόσφατη αναθεώρηση",
        "rcfilters-filter-previousrevision-description": "Όλες οι αλλαγές που δεν αποτελούν την \"πρόσφατη αναθεώρηση\"",
        "rcfilters-filter-excluded": "Εξαιρεμένοι",
+       "rcfilters-tag-prefix-namespace-inverted": "<strong>:όχι</strong> $1",
        "rcfilters-exclude-button-off": "Εξαίρεση επιλεγμένων",
+       "rcfilters-exclude-button-on": "Εξαίρεση επιλεγμένων",
        "rcfilters-view-tags": "Επεξεργασίες με ετικέτες",
        "rcfilters-view-namespaces-tooltip": "Φιλτράρισμα αποτελεσμάτων κατά ονοματοχώρο",
        "rcfilters-liveupdates-button": "Ζωντανή ανανέωση",
        "apisandbox": "Αμμοδοχείο API",
        "apisandbox-api-disabled": "Η Διεπαφή Προγραμματισμού Εφαρμογών (API) είναι απενεργοποιημένη σε αυτήν την τοποθεσία.",
        "apisandbox-intro": "Χρησιμοποιήστε αυτήν τη σελίδα για να πειραματιστείτε με το <strong>API της υπηρεσίας ιστού του MediaWiki</strong>.\nΑνατρέξτε στην [[mw:API:Main page|τεκμηρίωση του API]] για περισσότερες πληροφορίες πάνω στη χρήση του API. \nΠαράδειγμα: [https://www.mediawiki.org/wiki/API#A_simple_example λήψη του περιεχομένου της Αρχικής Σελίδας]. Επιλέξτε κάποια ενέργεια για να δείτε περισσότερα παραδείγματα.\n\nΝα σημειωθεί ότι, παρόλο που αυτό εδώ είναι αμμοδοχείο, οι ενέργειες που εκτελείτε σε αυτήν τη σελίδα μπορούν να τροποποιήσουν το wiki.",
+       "apisandbox-fullscreen": "Επέκταση πίνακα",
        "apisandbox-unfullscreen": "Εμφάνιση της σελίδας",
        "apisandbox-submit": "Υποβολή του αιτήματος",
        "apisandbox-reset": "Εκκαθάριση",
        "editcomment": "Το σχόλιο της επεξεργασίας ήταν: <em>$1</em>.",
        "revertpage": "Ανάκληση των αλλαγών [[Special:Contributions/$2|$2]] ([[User talk:$2|συζήτηση]]) επιστροφή στην προηγούμενη αναθεώρηση [[User:$1|$1]]",
        "revertpage-nouser": "Αναστράφηκαν οι επεξεργασίες από τον (όνομα χρήστη αφαιρέθηκε) στη τελευταία έκδοση από τον/την {{GENDER:$1|[[User:$1|$1]]}}φ",
-       "rollback-success": "Î\91νεÏ\83Ï\84Ï\81αμμένεÏ\82 ÎµÎºÎ´Ï\8cÏ\83ειÏ\82 Î±Ï\80Ï\8c $1, Î±Î»Î»Î¬Ï\87θηκαν Ï\83Ï\84ην Ï\80Ï\81οηγοÏ\8dμενη Î­ÎºÎ´Î¿Ï\83η Î±Ï\80Ï\8c $2.",
+       "rollback-success": "Î\91ναÏ\83Ï\84Ï\81οÏ\86ή ÎµÏ\80εξεÏ\81γαÏ\83ιÏ\8eν Î±Ï\80Ï\8c {{GENDER:$3|Ï\84ον|Ï\84ην}} $1, ÎµÏ\80ιÏ\83Ï\84Ï\81οÏ\86ή Ï\83Ï\84ην Ï\80Ï\81οηγοÏ\8dμενη Î­ÎºÎ´Î¿Ï\83η Î±Ï\80Ï\8c {{GENDER:$4|Ï\84ον|Ï\84ην}} $2.",
        "rollback-success-notify": "Αναίρεση επεξεργασιών από $1; επιστροφή στην τελευταία αναθεώρηση από $2.[$3 Εμφάνιση αλλαγών]",
        "sessionfailure-title": "Η συνεδρία απέτυχε",
        "sessionfailure": "Υπάρχει πρόβλημα με τη σύνδεσή σας -η ενέργεια αυτή ακυρώθηκε προληπτικά για την αντιμετώπιση τυχόν πειρατείας συνόδου (session hijacking). Παρακαλoύμε πατήστε \"Επιστροφή\", ξαναφορτώστε τη σελίδα από την οποία φθάσατε εδώ και προσπαθήστε ξανά.",
        "sp-contributions-uploads": "ανεβάσματα αρχείων",
        "sp-contributions-logs": "καταγραφές",
        "sp-contributions-talk": "συζήτηση",
-       "sp-contributions-userrights": "διαχείριση δικαιωμάτων χρηστών",
+       "sp-contributions-userrights": "διαχείριση δικαιωμάτων {{GENDER:$1|χρήστη|χρήστριας|χρηστών}}",
        "sp-contributions-blocked-notice": "{{GENDER:$1|Αυτός ο χρήστης|Αυτή η χρήστης}} έχει αποκλειστεί επί του παρόντος.\nΗ πιο πρόσφατη καταχώρηση του αρχείου καταγραφής φραγών παρέχεται παρακάτω για αναφορά:",
        "sp-contributions-blocked-notice-anon": "Αυτή η διεύθυνση IP υπόκειται επί του παρόντος σε φραγή",
        "sp-contributions-search": "Αναζήτηση για συνεισφορές",
        "unblocked-id": "Η φραγή του $1 έχει τερματιστεί",
        "unblocked-ip": "Έχει αρθεί η φραγή της [[Special:Contributions/$1|$1]].",
        "blocklist": "Αποκλεισμένοι χρήστες",
+       "autoblocklist": "Αυτόματες φραγές",
        "autoblocklist-submit": "Αναζήτηση",
        "ipblocklist": "Αποκλεισμένοι χρήστες",
        "ipblocklist-legend": "Εύρεση ενός χρήστη που έχει υποστεί φραγή",
        "cant-move-to-user-page": "Δεν έχετε άδεια για να μετακινήσετε μια σελίδα σε σελίδα χρήστη (παρά μόνο σε υποσελίδα χρήστη).",
        "cant-move-category-page": "Δεν έχετε άδεια να μετακινείτε σελίδες κατηγοριών.",
        "cant-move-to-category-page": "Δεν έχετε άδεια να μετακινήσετε μια σελίδα σε σελίδα της κατηγορίας.",
+       "cant-move-subpages": "Δεν έχετε άδεια να μετακινείτε υποσελίδες.",
+       "namespace-nosubpages": "Ο ονοματοχώρος \"$1\" δεν επιτρέπει υποσελίδες.",
        "newtitle": "Νέος τίτλος:",
        "move-watch": "Παρακολούθησε αυτή τη σελίδα",
        "movepagebtn": "Μετακίνηση σελίδας",
        "import-nonewrevisions": "Καμία αναθεώρηση δεν εισήχθει (όλες είτε ήταν ήδη παρούσες, ή παραλήφθηκαν λόγω σφαλμάτων).",
        "xml-error-string": "$1 στη γραμμή $2, στήλη $3 (byte $4): $5",
        "import-upload": "Ανέβασμα δεδομένων XML",
-       "import-token-mismatch": "Απώλεια δεδομένων περιόδου λειτουργίας.\n\nΜπορεί να έχετε αποσυνδεθεί. <strong>Παρακαλούμε επιβεβαιώστε ότι βρίσκεστε ακόμα σε σύνδεση και προσπαθήστε ξανά</strong>.\nΑν εξακολουθεί να μην λειτουργεί, δοκιμάστε να [[Special:UserLogout|αποσυνδεθείτε]] και να συνδεθείτε ξανά, και βεβαιωθείτε ότι το πρόγραμμα περιήγησής σας επιτρέπει cookies από αυτόν τον ιστότοπο.",
+       "import-token-mismatch": "Απώλεια δεδομένων περιόδου λειτουργίας.\n\nΜπορεί να έχετε αποσυνδεθεί. '''Παρακαλούμε επιβεβαιώστε ότι βρίσκεστε ακόμα σε σύνδεση και προσπαθήστε ξανά'''.\nΑν εξακολουθεί να μην λειτουργεί, δοκιμάστε να [[Special:UserLogout|αποσυνδεθείτε]] και να συνδεθείτε ξανά, και βεβαιωθείτε ότι το πρόγραμμα περιήγησής σας επιτρέπει cookies από αυτόν τον ιστότοπο.",
        "import-invalid-interwiki": "Δεν είναι δυνατή η εισαγωγή από το καθορισμένο wiki.",
        "import-error-edit": "Η σελίδα «$1» δεν εισήχθη επειδή δεν σας επιτρέπεται να την επεξεργαστείτε.",
        "import-error-create": "Η σελίδα «$1» δεν εισήχθη επειδή δεν σας επιτρέπεται να την δημιουργήσετε.",
        "tooltip-pt-mycontris": "Κατάλογος των συνεισφορών {{GENDER:|σας}}",
        "tooltip-pt-anoncontribs": "Μια λίστα με τις επεξεργασίες που έγιναν από αυτή τη διεύθυνση IP",
        "tooltip-pt-login": "Σας ενθαρρύνουμε να συνδεθείτε· ωστόσο, δεν είναι υποχρεωτικό",
+       "tooltip-pt-login-private": "Πρέπει να συνδεθείτε για να χρησιμοποιήσετε αυτό το βίκι",
        "tooltip-pt-logout": "Έξοδος",
        "tooltip-pt-createaccount": "Σας ενθαρρύνουμε να δημιουργήσετε ένα λογαριασμό και να συνδεθείτε· ωστόσο, δεν είναι υποχρεωτικό",
        "tooltip-ca-talk": "Συζήτηση για τη σελίδα περιεχομένου",
        "newimages-legend": "Φίλτρο",
        "newimages-label": "Όνομα αρχείου (ή μέρος αυτού):",
        "newimages-user": "Διεύθυνση IP ή όνομα χρήστη",
+       "newimages-newbies": "Εμφάνιση των συνεισφορών των νέων λογαριασμών μόνο",
        "newimages-showbots": "Εμφάνιση αρχείων ανεβασμένων από ρομπότ",
        "newimages-hidepatrolled": "Απόκρυψη ελεγμένων αρχείων.",
        "newimages-mediatype": "Τύπος μέσου:",
        "autosumm-blank": "Διαγραφή του περιεχομένου της σελίδας",
        "autosumm-replace": "Αντικατάσταση σελίδας με '$1'",
        "autoredircomment": "Ανακατεύθυνση στη σελίδα [[$1]]",
+       "autosumm-removed-redirect": "Αφαιρέθηκε ανακατεύθυνση προς το [[$1]]",
+       "autosumm-changed-redirect-target": "Άλλαξε στόχος ανακατεύθυνσης από το [[$1]] στο [[$2]]",
        "autosumm-new": "Νέα σελίδα με '$1'",
        "autosumm-newblank": "Δημιουργήθηκε κενή σελίδα",
        "lag-warn-normal": "Αλλαγές νεότερες από {{PLURAL:$1|δευτερόλεπτο|δευτερόλεπτα}} μπορεί να μην φαίνονται σε αυτή τη λίστα.",
        "watchlistedit-clear-titles": "Τίτλοι:",
        "watchlistedit-clear-submit": "Εκκαθάριση της λίστας παρακολούθησης (Αυτό είναι οριστικό!)",
        "watchlistedit-clear-done": "Η λίστα παρακολούθησής σας έχει καθαριστεί.",
+       "watchlistedit-clear-jobqueue": "Η λίστα παρακολούθησής σας καθαρίζεται. Αυτό ίσως πάρει λίγο χρόνο!",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 τίτλος αφαιρέθηκε|$1 τίτλοι αφαιρέθηκαν}}:",
        "watchlistedit-too-many": "Υπάρχουν υπερβολικά πολλές σελίδες και δεν μπορούν να εμφανιστούν εδώ.",
        "watchlisttools-clear": "Εκκαθάριση της λίστας παρακολούθησης",
        "version-poweredby-others": "άλλοι",
        "version-poweredby-translators": "translatewiki.net μεταφραστές",
        "version-credits-summary": "Θα θέλαμε να αναγνωρίσουμε τη συμβολή των παρακάτω προσώπων στο [[Special:Version|MediaWiki]].",
-       "version-license-info": "Το MediaWiki είναι ελεύθερο λογισμικό. Μπορείτε να το αναδιανείμετε ή/και να το τροποποιήσετε υπό τους όρους της άδειας GNU General Public License όπως αυτή εκδόθηκε από το Free Software Foundation· είτε της δεύτερης έκδοσης της άδειας, είτε (κατ' επιλογή σας) οποιασδήποτε επόμενης έκδοσης.\n\nΤο MediaWiki διανέμεται με την ελπίδα ότι θα είναι χρήσιμο, αλλά ΧΩΡΙΣ ΚΑΜΙΑ ΕΓΓΥΗΣΗ· ούτε καν την σιωπηρή εγγύηση ΕΜΠΟΡΕΥΣΙΜΟΤΗΤΑΣ ή ΚΑΤΑΛΛΗΛΟΤΗΤΑΣ ΓΙΑ ΕΝΑ ΣΥΓΚΕΚΡΙΜΕΝΟ ΣΚΟΠΟ. Βλ. GNU General Public License για περισσότερες λεπτομέρειες.\n\nΘα πρέπει να έχετε λάβει [{{SERVER}}{{SCRIPTPATH}}/COPYING ένα αντίγραφο της GNU General Public License] μαζί με αυτό το πρόγραμμα· αν όχι, στείλτε ένα γράμμα στο Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ή [//www.gnu.org/licenses/old-licenses/gpl-2.0.html διαβάστε το διαδικτυακά].",
+       "version-license-info": "Το MediaWiki είναι ελεύθερο λογισμικό. Μπορείτε να το αναδιανείμετε ή/και να το τροποποιήσετε υπό τους όρους της άδειας GNU General Public License όπως αυτή εκδόθηκε από το Free Software Foundation· είτε της δεύτερης έκδοσης της άδειας, είτε (κατ' επιλογή σας) οποιασδήποτε επόμενης έκδοσης.\n\nΤο MediaWiki διανέμεται με την ελπίδα ότι θα είναι χρήσιμο, αλλά <em>ΧΩΡΙΣ ΚΑΜΙΑ ΕΓΓΥΗΣΗ</em>· ούτε καν την σιωπηρή εγγύηση <strong>ΕΜΠΟΡΕΥΣΙΜΟΤΗΤΑΣ</strong> ή <strong>ΚΑΤΑΛΛΗΛΟΤΗΤΑΣ ΓΙΑ ΕΝΑ ΣΥΓΚΕΚΡΙΜΕΝΟ ΣΚΟΠΟ</strong>. Δείτε την GNU General Public License για περισσότερες λεπτομέρειες.\n\nΘα πρέπει να έχετε λάβει [{{SERVER}}{{SCRIPTPATH}}/COPYING ένα αντίγραφο της GNU General Public License] μαζί με αυτό το πρόγραμμα· αν όχι, στείλτε ένα γράμμα στο Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ή [//www.gnu.org/licenses/old-licenses/gpl-2.0.html διαβάστε το διαδικτυακά].",
        "version-software": "Εγκατεστημένο λογισμικό",
        "version-software-product": "Προϊόν",
        "version-software-version": "Έκδοση",
        "tag-filter-submit": "Φίλτρο",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Ετικέτα|Ετικέτες}}]]: $2)",
        "tag-mw-new-redirect": "Νέα ανακατεύθυνση",
+       "tag-mw-removed-redirect": "Αφαιρέθηκε ανακατεύθυνση",
+       "tag-mw-changed-redirect-target": "Στόχος ανακατεύθυνσης άλλαξε",
        "tag-mw-blank": "Άδειασμα περιεχομένου σελίδας",
        "tag-mw-blank-description": "Επεξεργασίες που σβήνουν όλο το περιεχόμενο σελίδας",
        "tag-mw-replace": "Αντικαταστάθηκε",
        "tag-mw-replace-description": "Επεξεργασίες που αφαιρούν πάνω από 90% του περιεχομένου της σελίδας",
        "tag-mw-rollback": "Επαναφορά",
+       "tag-mw-undo": "Αναιρέθηκε",
        "tags-title": "Ετικέτες",
        "tags-intro": "Η σελίδα καταγράφει τις ετικέτες, καθώς και το τι σημαίνει η κάθε μία, με τις οποίες το λογισμικό μπορεί να μαρκάρει μία επεξεργασία.",
        "tags-tag": "Όνομα ετικέτας",
        "tags-create-reason": "Αιτία:",
        "tags-create-submit": "Δημιουργία",
        "tags-create-no-name": "Πρέπει να καθορίσετε όνομα ετικέτας.",
-       "tags-create-invalid-chars": "Τα ονόματα ετικετών δεν πρέπει να περιέχουν κόμματα (<code>,</code>) ή καθέτους (<code>/</code>).",
+       "tags-create-invalid-chars": "Τα ονόματα ετικετών δεν πρέπει να περιέχουν κόμματα (<code>,</code>), κατακόρυφες καθέτους (<code>|</code>), ή καθέτους (<code>/</code>).",
        "tags-create-invalid-title-chars": "Τα ονόματα ετικετών δεν πρέπει να περιέχουν χαρακτήρες που δεν είναι δυνατό να χρησιμοποιηθούν σε τίτλους σελίδων.",
        "tags-create-already-exists": "Η ετικέτα «$1» υπάρχει ήδη.",
        "tags-create-warnings-above": "{{PLURAL:$2|Αντιμετωπίστηκε η ακόλουθη προειδοποίηση|Αντιμετωπίστηκαν οι ακόλουθες προειδοποιήσεις}} όταν έγινε προσπάθεια για τη δημιουργία της ετικέτας «$1»:",
        "compare-invalid-title": "Ο τίτλος που καθορίσατε δεν είναι έγκυρος.",
        "compare-title-not-exists": "Ο τίτλος που καθορίσατε δεν υπάρχει.",
        "compare-revision-not-exists": "Η αναθεώρηση που καθορίσατε δεν υπάρχει.",
-       "diff-form": "μια '''φόρμα'''",
+       "diff-form": "Διαφορές",
+       "diff-form-submit": "Εμφάνιση διαφορών",
        "permanentlink": "Σταθερός σύνδεσμος",
        "permanentlink-revid": "Αναγνωριστικό αναθεώρησης",
+       "permanentlink-submit": "Πήγαινε στην αναθεώρηση",
        "dberr-problems": "Λυπούμαστε! Αυτός ο ιστότοπος αντιμετωπίζει τεχνικές δυσκολίες.",
        "dberr-again": "Δοκιμάστε να περιμενένετε λίγα λεπτά και να ανανεώσετε.",
        "dberr-info": "(Δεν είναι δυνατή η πρόσβαση στη βάση δεδομένων: $1)",
        "limitreport-expansiondepth": "Μεγαλύτερο βάθος ανάπτυξης",
        "limitreport-expensivefunctioncount": "Πλήθος ακριβών συναρτήσεων συντακτικού αναλυτή",
        "expandtemplates": "Επέκταση προτύπων",
-       "expand_templates_intro": "Αυτή η ειδική σελίδα παίρνει κείμενο και αναπτύσσει όλα τα πρότυπα σε αυτό αναδρομικά. \nΕπίσης αναπτύσσει συναρτήσεις συντακτικού αναλυτή όπως η\n<nowiki>{{</nowiki>#language:…}}, και μεταβλητές όπως η\n<nowiki>{{</nowiki>CURRENTDAY}}.\nΟυσιαστικά επεκτείνει οτιδήποτε βρίσκεται σε διπλές αγκύλες.",
+       "expand_templates_intro": "Αυτή η ειδική σελίδα παίρνει κώδικα wiki και αναπτύσσει όλα τα πρότυπα σε αυτό αναδρομικά. \nΕπίσης αναπτύσσει συναρτήσεις συντακτικού αναλυτή όπως η\n<nowiki>{{</nowiki>#language:…}}, και μεταβλητές όπως η\n<nowiki>{{</nowiki>CURRENTDAY}}.\nΟυσιαστικά επεκτείνει οτιδήποτε βρίσκεται σε διπλές αγκύλες.",
        "expand_templates_title": "Τίτλων συμφραζόμενων, για την {{FULLPAGENAME}} κ.τ.λ.:",
-       "expand_templates_input": "Î\9aείμενο εισόδου:",
+       "expand_templates_input": "Î\92ικικείμενο εισόδου:",
        "expand_templates_output": "Αποτέλεσμα",
        "expand_templates_xml_output": "Έξοδος XML",
        "expand_templates_html_output": "Ανεπεξέργαστη έξοδος HTML",
        "special-characters-group-thai": "ταϊλανδικά",
        "special-characters-group-lao": "λαοτινά",
        "special-characters-group-khmer": "καμποτζιανά",
+       "special-characters-group-canadianaboriginal": "Καναδικό Αβοριγινικό",
        "special-characters-title-endash": "παύλα",
        "special-characters-title-emdash": "διπλή παύλα",
        "special-characters-title-minus": "σύμβολο πλην",
        "log-action-filter-contentmodel-change": "Αλλαγή του μοντέλου περιεχομένου",
        "log-action-filter-contentmodel-new": "Δημιουργία σελίδας με μη προεπιλεγμένο μοντέλο περιεχομένου",
        "log-action-filter-delete-delete": "Διαγραφή σελίδας",
+       "log-action-filter-delete-restore": "Ξεδιαγραφή σελίδας",
+       "log-action-filter-import-interwiki": "Εισαγωγή Transwiki",
        "log-action-filter-import-upload": "Εισαγωγή μέσω ανεβάσματος XML",
        "log-action-filter-managetags-create": "Δημιουργία ετικέτας",
        "log-action-filter-managetags-delete": "Διαγραφή ετικέττας",
        "log-action-filter-newusers-autocreate": "Αυτόματη δημιουργία",
+       "log-action-filter-patrol-patrol": "Χειροκίνητη περιπολία",
+       "log-action-filter-patrol-autopatrol": "Αυτόματη περιπολία",
        "log-action-filter-protect-protect": "Προστασία",
        "log-action-filter-protect-modify": "Τροποποίηση προστασίας",
        "log-action-filter-protect-unprotect": "Άρση προστασίας",
        "log-action-filter-protect-move_prot": "Μετακίνηση προστασίας",
        "log-action-filter-rights-rights": "Χειροκίνητη αλλαγή",
        "log-action-filter-rights-autopromote": "Αυτόματη αλλαγή",
+       "log-action-filter-upload-upload": "Νέα μεταφόρτωση",
+       "log-action-filter-upload-overwrite": "Επαναμεταφόρτωση",
        "authmanager-create-disabled": "Η δημιουργία λογαριασμού έχει απενεργοποιηθεί.",
        "authmanager-authplugin-setpass-failed-title": "Η αλλαγή κωδικού πρόσβασης απέτυχε",
        "authmanager-email-label": "Διεύθυνση ηλ. ταχυδρομείου",
+       "authmanager-email-help": "Διεύθυνση ηλεκτρονικού ταχυδρομείου:",
        "authmanager-realname-label": "Πραγματικό όνομα",
        "authmanager-realname-help": "Πραγματικό όνομα του χρήστη",
        "authmanager-provider-temporarypassword": "Προσωρινός κωδικός",
        "authprovider-resetpass-skip-label": "Παράβλεψη",
        "authprovider-resetpass-skip-help": "Παράβλεψη της επαναφοράς του κωδικού πρόσβασης.",
        "specialpage-securitylevel-not-allowed-title": "Δεν επιτρέπεται",
+       "authpage-cannot-login": "Αποτυχία στο ξεκίνημα σύνδεσης.",
+       "authpage-cannot-create": "Αποτυχία στην αρχή δημιουργίας λογαριασμού.",
        "cannotauth-not-allowed-title": "Δεν έχετε δικαίωμα πρόσβασης.",
        "cannotauth-not-allowed": "Δεν επιτρέπεται να χρησιμοποιήσετε αυτή τη σελίδα",
        "credentialsform-account": "Όνομα λογαριασμού:",
index d0ee41c..6ff4237 100644 (file)
        "expansion-depth-exceeded-category-desc": "The page exceeds the maximum expansion depth.",
        "expansion-depth-exceeded-warning": "Page exceeded the expansion depth",
        "parser-unstrip-loop-warning": "Unstrip loop detected",
-       "parser-unstrip-recursion-limit": "Unstrip recursion limit exceeded ($1)",
+       "unstrip-depth-warning": "Unstrip depth limit exceeded ($1)",
+       "unstrip-depth-category": "Pages where the unstrip depth limit is exceeded",
+       "unstrip-size-warning": "Unstrip size limit exceeded ($1)",
+       "unstrip-size-category": "Pages where the unstrip size limit is exceeded",
        "converter-manual-rule-error": "Error detected in manual language conversion rule",
        "undo-success": "The edit can be undone.\nPlease check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.",
        "undo-failure": "The edit could not be undone due to conflicting intermediate edits.",
        "limitreport-expansiondepth-value": "$1/$2",
        "limitreport-expensivefunctioncount": "Expensive parser function count",
        "limitreport-expensivefunctioncount-value": "$1/$2",
+       "limitreport-unstrip-depth": "Unstrip recursion depth",
+       "limitreport-unstrip-depth-value": "$1/$2",
+       "limitreport-unstrip-size": "Unstrip post-expand size",
+       "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte|bytes}}",
        "expandtemplates": "Expand templates",
        "expand_templates_intro": "This special page takes wikitext and expands all templates in it recursively.\nIt also expands supported parser functions like\n<code><nowiki>{{</nowiki>#language:…}}</code> and variables like\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nIn fact, it expands pretty much everything in double-braces.",
        "expand_templates_title": "Context title, for {{FULLPAGENAME}}, etc.:",
index 4605bad..035abcb 100644 (file)
        "expansion-depth-exceeded-category-desc": "La paĝo superis maksimuman profundecon de ekspando.",
        "expansion-depth-exceeded-warning": "Paĝo preterpasis la ekpansiprofundon.",
        "parser-unstrip-loop-warning": "Cirkloreferencon detektis",
-       "parser-unstrip-recursion-limit": "Rikurlimiton de analizopoj ($1) superis",
+       "unstrip-depth-warning": "Rikurlimiton de analizopoj ($1) superis",
        "converter-manual-rule-error": "Eraron detektis en mana lingvokonverta regulo",
        "undo-success": "La redakto estas malfarebla.\nBonvolu kontroli la jenan komparaĵon por certiĝi ĉu tio estas tio, kion vi volas, kaj konservi la ŝanĝojn malsupre por fine malfari la redakton.",
        "undo-failure": "Ne povis nuligi redakton pro konfliktaj intermezaj redaktoj.",
index 3c5b4ab..9cb3299 100644 (file)
        "expansion-depth-exceeded-category-desc": "Esta página sobrepasa la profundidad de expansión máxima.",
        "expansion-depth-exceeded-warning": "La página ha sobrepasado el límite de profundidad de expansión",
        "parser-unstrip-loop-warning": "Se ha detectado un bucle en la función \"unstrip\"",
-       "parser-unstrip-recursion-limit": "Se ha superado el límite de recursividad de la función \"unstrip\" ($1)",
+       "unstrip-depth-warning": "Se ha superado el límite de recursividad de la función \"unstrip\" ($1)",
        "converter-manual-rule-error": "Se ha detectado un error en una regla manual de conversión de idioma",
        "undo-success": "Puedes deshacer la edición. Antes de deshacer la edición, comprueba la siguiente comparación para verificar que realmente es lo que quieres hacer, y entonces guarda los cambios para así efectuar la reversión.",
        "undo-failure": "No se ha podido deshacer la edición ya que otro usuario ha realizado una edición intermedia.",
index 029e7ca..6206b0b 100644 (file)
        "expansion-depth-exceeded-category-desc": "Lehekülg ületab hõrendussügavuse ülemmäära.",
        "expansion-depth-exceeded-warning": "Lehekülg ületas hõrendussügavuse.",
        "parser-unstrip-loop-warning": "''Unstrip''-funktsiooni silmus tuvastatud",
-       "parser-unstrip-recursion-limit": "''Unstrip''-funktsioonis rekursiooni piirmäär ületatud ($1)",
+       "unstrip-depth-warning": "''Unstrip''-funktsioonis rekursiooni piirmäär ületatud ($1)",
        "converter-manual-rule-error": "Tõrge keelevariandi käsivahetusreeglis",
        "undo-success": "Selle redaktsiooni käigus tehtud muudatusi saab eemaldada. Palun kontrolli allolevat võrdlust veendumaks, et tahad need muudatused tõepoolest eemaldada. Seejärel saad lehekülje salvestada.",
        "undo-failure": "Muudatust ei saa vahapeal tehtud redigeerimiste tõttu tühistada.",
index e375fd9..2b1f1af 100644 (file)
        "expansion-depth-exceeded-category-desc": "Orriak zabalkunde sakonera maximoa gainditzen du.",
        "expansion-depth-exceeded-warning": "Espantsio sakonera gainditu duten orrialdeak",
        "parser-unstrip-loop-warning": "Loop unstrip bat aurkitu da",
-       "parser-unstrip-recursion-limit": "Unstrip errekurtsio limitea gainditu da ($1)",
+       "unstrip-depth-warning": "Unstrip errekurtsio limitea gainditu da ($1)",
        "converter-manual-rule-error": "Akatsa aurkitu da hizkuntzen eskuszko konbertsio arauan",
        "undo-success": "Aldaketa desegin daiteke.\nMesedez beheko alderaketa egiaztatu, egin nahi duzuna hori dela frogatzeko, eta ondoren azpiko aldaketak gorde, aldaketa desegiten amaitzeko.",
        "undo-failure": "Ezin izan da aldaketa desegin tarteko aldaketekin gatazkak direla-eta.",
index f5d07ce..9086795 100644 (file)
        "expansion-depth-exceeded-category-desc": "رده برای صفحاتی که در آنها از عمق گسترش فراتر رفته است.",
        "expansion-depth-exceeded-warning": "صفحه حداکثر عمق بسط دادن تجاوز کرد",
        "parser-unstrip-loop-warning": "حلقه در دستور unstrip پیدا شد",
-       "parser-unstrip-recursion-limit": "از حداکثر ارجاع در دستور unstrip تجاوز شد ($1)",
+       "unstrip-depth-warning": "از حداکثر ارجاع در دستور unstrip تجاوز شد ($1)",
        "converter-manual-rule-error": "خطا در قوانین مبدل دستی زبان",
        "undo-success": "این ویرایش را می‌توان خنثی کرد.\nلطفاً تفاوت زیر را بررسی کنید تا تأیید کنید که این چیزی است که می‌خواهید انجام دهید، سپس تغییرات زیر را ذخیره کنید تا خنثی‌سازی ویرایش را به پایان ببرید.",
        "undo-failure": "به علت تعارض با ویرایش‌های میانی، این ویرایش را نمی‌توان خنثی کرد.",
        "recentchanges-summary": "آخرین تغییرات ویکی را در این صفحه پی‌گیری کنید.",
        "recentchanges-noresult": "در فاصله زمانی ارائه شده هیچ تغییری با این معیارهای صورت نگرفته است",
        "recentchanges-timeout": "این جستجو زمانش تمام شد. اگر مایلید کلیدواژه‌های دیگری را جستجو کنید.",
-       "recentchanges-network": "به دلیل خطای فنی، نتیجه‌ای بدست نیامد. لطفاً برای تازه‌سازی صفحخ مجدداُ تلاش کنید.",
+       "recentchanges-network": "به دلیل خطای فنی، نتیجه‌ای بدست نیامد. لطفاً برای تازه‌سازی صفحه مجدداً تلاش کنید.",
        "recentchanges-notargetpage": "نام صفحه را در بالا وارد کنید تا تغییرات مرتبط با آن صفحه را مشاهده کنید.",
        "recentchanges-feed-description": "آخرین تغییرات ویکی را در این خوراک پی‌گیری کنید.",
        "recentchanges-label-newpage": "این ویرایش صفحه‌ای تازه ایجاد کرد",
index b89abac..a7645e4 100644 (file)
        "passwordreset-emailelement": "Käyttäjätunnus: \n$1\n\nVäliaikainen salasana: \n$2",
        "passwordreset-emailsentemail": "Jos tämä on sinun tunnuksellesi rekisteröity sähköpostiosoite, salasanan uudistamisesta kertova viesti lähetetään.",
        "passwordreset-emailsentusername": "Jos on olemassa vastaava rekisteröity sähköpostiosoite, salasanan uudistamisesta kertova viesti lähetetään.",
+       "passwordreset-nosuchcaller": "Kutsuvaa funktiota ei ole olemassa: $1",
        "passwordreset-ignored": "Salasanan palauttamista ei käsitelty. Ehkä tarjoajaa ei ollut määritetty?",
        "passwordreset-invalidemail": "Virheellinen sähköpostiosoite",
        "passwordreset-nodata": "Käyttäjätunnusta ja salasanaa ei annettu",
        "expansion-depth-exceeded-category-desc": "Tämä sivu ylittää suurimman sallitun laajentamissyvyyden (expansion depth).",
        "expansion-depth-exceeded-warning": "Sivu ylitti laajentamissyvyyden.",
        "parser-unstrip-loop-warning": "Unstrip-silmukka havaittiin",
-       "parser-unstrip-recursion-limit": "Unstrip-rekursion enimmäissyvyys ($1) ylitettiin",
+       "unstrip-depth-warning": "Unstrip-rekursion enimmäissyvyys ($1) ylitettiin",
        "converter-manual-rule-error": "Kielivarianttisäännössä on virhe",
        "undo-success": "Kumoaminen voidaan suorittaa.\nVarmista alla olevasta vertailusta, että haluat saada aikaan tämän lopputuloksen, ja sen jälkeen tallenna alla näkyvät muutokset.",
        "undo-failure": "Muokkausta ei voi kumota välissä olevien ristiriitaisten muutosten vuoksi.",
        "rcfilters-state-message-subset": "Tällä suodattimella ei ole vaikutusta, koska sen tulokset sisältyvät {{PLURAL:$2|seuraavaan laajempaan suodattimeen|seuraaviin laajempiin suodattimiin}} (kokeile korostusta sen erottamiseksi): $1",
        "rcfilters-state-message-fullcoverage": "Tässä ryhmässä kaikkien suodattimien valitseminen on sama, kuin ei valitse mitään, joten tällä suodattimella ei ole vaikutusta. Ryhmään sisältyy: $1",
        "rcfilters-filtergroup-authorship": "Muutoksen tekijä",
-       "rcfilters-filter-editsbyself-label": "Sinun tekemät muutokset",
+       "rcfilters-filter-editsbyself-label": "Sinun muutoksesi",
        "rcfilters-filter-editsbyself-description": "Tekemäsi muutokset.",
        "rcfilters-filter-editsbyother-label": "Muiden muutokset",
        "rcfilters-filter-editsbyother-description": "Muiden käyttäjien tekemät muutokset.",
        "upload-tryagain": "Lähetä muutettu tiedostokuvaus",
        "upload-tryagain-nostash": "Lähetä uudelleenlähetetty tiedosto ja muokattu kuvaus",
        "uploadnologin": "Et ole kirjautunut sisään",
-       "uploadnologintext": "Sinun pitää $1, jotta voit tallentaa tiedostoja.",
+       "uploadnologintext": "Ole hyvä ja $1, jotta voit tallentaa tiedostoja.",
        "upload_directory_missing": "Tallennushakemisto $1 puuttuu, eikä palvelin pysty luomaan sitä.",
        "upload_directory_read_only": "Palvelimella ei ole kirjoitusoikeuksia tallennushakemistoon $1.",
        "uploaderror": "Tallennusvirhe",
        "uploadstash-bad-path": "\nPolkua ei ole.",
        "uploadstash-bad-path-invalid": "Polku ei kelpaa.",
        "uploadstash-bad-path-unknown-type": "Tuntematon tyyppi \"$1\".",
+       "uploadstash-bad-path-bad-format": "Avain \"$1\" ei ole sopivassa muodossa.",
+       "uploadstash-file-not-found": "Avainta \"$1\" ei löytynyt kätköstä.",
+       "uploadstash-file-not-found-no-object": "Ei voitu luoda paikallista tiedostokohdetta pienoiskuvalle.",
+       "uploadstash-file-not-found-missing-content-type": "Puuttuva sisältötyypin ylätunniste",
        "uploadstash-not-logged-in": "Käyttäjää ei ole kirjautunut sisään, tiedostojen on kuuluttava käyttäjille.",
+       "uploadstash-wrong-owner": "Tämä tiedosto ($1) ei kuulu nykyiselle käyttäjälle.",
        "uploadstash-no-such-key": "Ei tälläistä avainta ($1), ei voi poistaa.",
        "uploadstash-no-extension": "Laajennus on tyhjä.",
        "uploadstash-zero-length": "Tiedoston pituus on nolla.",
        "apisandbox-results-error": "Tapahtui virhe ladattaessa API-kyselyn vastausta: $1",
        "apisandbox-request-format-url-label": "URL-kyselymerkkijono",
        "apisandbox-request-url-label": "Pyynnön URL",
+       "apisandbox-request-json-label": "Pyydetty JSON:",
        "apisandbox-request-time": "Pyyntöön kulunut aika: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Korjaa \"token\" ja lähetä uudelleen",
        "apisandbox-alert-page": "Tällä sivulla olevat kentät eivät ole kelvollisia.",
        "booksources-text": "Alla linkkejä ulkopuolisiin sivustoihin, joilla myydään uusia ja käytettyjä kirjoja. Sivuilla voi myös olla lisätietoa kirjoista.",
        "booksources-invalid-isbn": "Annettu ISBN-numero ei ole kelvollinen. Tarkista alkuperäisestä lähteestä kirjoitusvirheiden varalta.",
        "magiclink-tracking-rfc": "Sivut, jotka käyttävät RFC-taikalinkkejä",
+       "magiclink-tracking-rfc-desc": "Tämä sivu käyttää RFC-taikalinkkejä. Katso sivulta [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] miten siirtyä käyttämään.",
        "magiclink-tracking-pmid": "Sivut, jotka käyttävät PMID-taikalinkkejä",
+       "magiclink-tracking-pmid-desc": "Tämä sivu käyttää PMID-taikalinkkejä. Katso sivulta\n[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] miten siirtyä käyttämään.",
        "magiclink-tracking-isbn": "Sivut, jotka käyttävät ISBN-taikalinkkejä",
+       "magiclink-tracking-isbn-desc": "Tämä sivu käyttää ISBN-taikalinkkejä. Katso sivulta [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] miten siirtyä käyttämään.",
        "specialloguserlabel": "Suorittaja:",
        "speciallogtitlelabel": "Kohde (sivu tai {{ns:user}}:käyttäjänimi):",
        "log": "Lokit",
        "allinnamespace": "Kaikki sivut nimiavaruudessa $1",
        "allpagessubmit": "Hae",
        "allpagesprefix": "Sivut, jotka alkavat etuliitteellä:",
-       "allpagesbadtitle": "Annettu otsikko oli kelvoton tai siinä oli wikien välinen etuliite.",
+       "allpagesbadtitle": "Annettu sivun nimi oli kelvoton tai siinä oli etuliite, joka tarkoittaa toista wikiprojektia tai toisenkielistä wikiä.\nSivun nimessä on voinut olla yksi tai useampia merkkejä, jotka eivät ole sallittuja sivun nimessä.",
        "allpages-bad-ns": "{{GRAMMAR:inessive|{{SITENAME}}}} ei ole nimiavaruutta ”$1”.",
        "allpages-hide-redirects": "Piilota ohjaukset",
        "cachedspecial-viewing-cached-ttl": "Tarkastelet arkistoitua versiota tästä sivusta, joka voi olla jopa $1 vanha.",
        "rollback-success": "Käyttäjän {{GENDER:$3|$1}} tekemät muokkaukset kumottiin ja sivu palautettiin käyttäjän {{GENDER:$4|$2}} versioon.",
        "rollback-success-notify": "Kumottiin käyttäjän $1 muokkaukset; palautettiin viimeiseen käyttäjän $2 versioon. [$3 Näytä muutokset]",
        "sessionfailure-title": "Istuntovirhe",
-       "sessionfailure": "Näyttää siltä, että tämänhetkisessä istunnossasi on jokin ongelma. \nTämä toiminto on peruutettu varotoimena, jotta estetään istunnon kaappaaminen.\nMene aikaisemmalle sivulle ja päivitä se. Yritä sitten uudelleen.",
+       "sessionfailure": "Näyttää siltä, että tämänhetkisessä istunnossasi on jokin ongelma; \ntämä toiminto on peruutettu varotoimena istunnon kaappaamisen estämiseksi.\nLähetä lomake uudelleen.",
        "changecontentmodel": "Muuta sivun sisältömallia",
        "changecontentmodel-legend": "Muuta sisältömallia",
        "changecontentmodel-title-label": "Sivun otsikko",
        "tag-mw-removed-redirect-description": "Muokkaukset, jotka muuttavat olemassa olevan uudelleenohjauksen ei-uudelleenohjaukseksi",
        "tag-mw-changed-redirect-target": "Uudelleenohjauksen kohde muutettu",
        "tag-mw-changed-redirect-target-description": "Muokkaukset, jotka muuttavat uudelleenohjauksen kohdetta",
+       "tag-mw-blank": "Tyhjennys",
        "tag-mw-blank-description": "Muokkaukset, jotka tyhjentävät sivun",
        "tag-mw-replace": "Korvattu",
        "tag-mw-replace-description": "Muokkaukset, joissa on poistettu yli 90 % sivun sisällöstä",
index f8fc0fd..012ba17 100644 (file)
        "expansion-depth-exceeded-category-desc": "La page dépasse la profondeur d’expansion maximale.",
        "expansion-depth-exceeded-warning": "Page dépassant la profondeur d’expansion maximale",
        "parser-unstrip-loop-warning": "Boucle non dépilable détectée",
-       "parser-unstrip-recursion-limit": "Limite de récursion non dépilable dépassée ($1)",
+       "unstrip-depth-warning": "Limite de récursion non dépilable dépassée ($1)",
        "converter-manual-rule-error": "Erreur détectée dans la règle manuelle de conversion de langue",
        "undo-success": "Cette modification va être annulée.\nVeuillez vérifier les différences ci-dessous, puis publier l’annulation si c’est bien ce que vous voulez faire.",
        "undo-failure": "Cette modification ne peut pas être défaite : cela entrerait en conflit avec les modifications intermédiaires.",
index c9ea180..ee9842a 100644 (file)
        "expansion-depth-exceeded-category-desc": "La pâge dèpâsse la provondior maximon d’èxpension.",
        "expansion-depth-exceeded-warning": "Pâge que dèpâsse la provondior d’èxpension",
        "parser-unstrip-loop-warning": "Boclla pas dèmontâbla dècelâye",
-       "parser-unstrip-recursion-limit": "Limita de rècursion pas dèmontâbla dèpassâye ($1)",
+       "unstrip-depth-warning": "Limita de rècursion pas dèmontâbla dèpassâye ($1)",
        "converter-manual-rule-error": "Fôta dècelâye dedens la règlla de convèrsion manuâla de lengoua",
        "undo-success": "Lo changement pôt étre dèfêt.\nSe vos plét, controlâd la comparèson ce-desot por vos assurar qu’o est franc cen que vos voléd fâre, et pués encartâd los changements por chavonar sa dèfêta.",
        "undo-failure": "Lo changement at pas possu étre dèfêt a côsa d’una disputa avouéc des changements entèrmèdièros.",
index 97ef571..930822a 100644 (file)
        "expansion-depth-exceeded-category-desc": "Detdiar sidj hää tuföl ütjwidjangen.",
        "expansion-depth-exceeded-warning": "Detdiar sidj hää tuföl ütjwidjangen (expansion)",
        "parser-unstrip-loop-warning": "Diar as en jinsidjag ferwisang",
-       "parser-unstrip-recursion-limit": "Tuföl jinsidjag ferwisangen bi $1",
+       "unstrip-depth-warning": "Tuföl jinsidjag ferwisangen bi $1",
        "converter-manual-rule-error": "Bi't manuel reegel för't spriakferanrang lääpt wat skiaf.",
        "undo-success": "Detdiar feranrang koon turag nimen wurd. \nLuke oner, of dü det uk würelk du wel, an do seekre din feranrangen.",
        "undo-failure": "Det feranrang küd ei stregen wurd, auer di kirew uuntesken feranert wurden as.",
index 036ef01..fd82600 100644 (file)
        "expansion-depth-exceeded-category-desc": "Tha an leudachadh san duilleag nas doimhne na tha ceadaichte.",
        "expansion-depth-exceeded-warning": "Bha an leudachadh san duilleag na bu dhoimhne na tha ceadaichte",
        "parser-unstrip-loop-warning": "Mhothaich sinn do lùb unstrip",
-       "parser-unstrip-recursion-limit": "Chaidheas thairis air crìoch unstrip recursion ($1)",
+       "unstrip-depth-warning": "Chaidheas thairis air crìoch unstrip recursion ($1)",
        "converter-manual-rule-error": "Mhothaich sinn do mhearachd san riaghailt iompachadh làimhe airson cànan",
        "undo-success": "Gabhaidh an deasachadh seo a neo-dhèanamh.\nThoir sùil air a' choimeas gu h-ìosal is dearbhaich gur e sin a tha fa-near dhut agus sàbhail na h-atharraichean gu h-ìosal gus neo-dhèanamh an deasachaidh a choileanadh.",
        "undo-failure": "Cha b' urrainn dhuinn an deasachadh a neo-dhèanamh air sgàth 's gun robh deasachaidhean eile sa mheadhan.",
index 0e7a58e..efb5db1 100644 (file)
        "expansion-depth-exceeded-category-desc": "A páxina supera a profundidade de expansión máxima.",
        "expansion-depth-exceeded-warning": "A páxina supera a profundidade de expansión",
        "parser-unstrip-loop-warning": "Detectouse un bucle inamovible",
-       "parser-unstrip-recursion-limit": "Excedeuse o límite de recursión inamovible ($1)",
+       "unstrip-depth-warning": "Excedeuse o límite de recursión inamovible ($1)",
        "converter-manual-rule-error": "Detectouse un erro na regra manual de conversión da lingua",
        "undo-success": "A edición pódese desfacer.\nComprobe a comparación que aparece a continuación para confirmar que isto é o que desexa facer; despois, garde os cambios para desfacer a edición.",
        "undo-failure": "Non se pode desfacer a edición debido a un conflito con algunha das edicións intermedias.",
index a56016a..3f4c1ab 100644 (file)
@@ -37,7 +37,7 @@
        "tog-shownumberswatching": "Popobilohe jumula lo ta he'awasiyalo",
        "tog-oldsig": "Pali lo ulu'umu masatiya",
        "tog-fancysig": "Popopasiya pali lo'ulu'u odelo tuladuwiki (diyalu tuwawu pranala otomatis)",
-       "tog-uselivepreview": "Popohunawa mopobilohu langsung",
+       "tog-uselivepreview": "Popobilohe pratayang wawu ja detohe ulangi halaman",
        "tog-forceeditsummary": "Popo'eelawa wa'u wonu dosi monguba diipo otuwa",
        "tog-watchlisthideown": "Wantoa u iluba'u to daputari lo he'awasiyalo",
        "tog-watchlisthidebots": "Wanto'a u iluba lo bot to daputari lo he'awasiyalo",
index 9c1dcfe..19c3af1 100644 (file)
        "expansion-depth-exceeded-category-desc": "D Syte iberschrytet di maximal Expandierigstiefi.",
        "expansion-depth-exceeded-warning": "Die Syte het d Expansionsdiefi überschritte.",
        "parser-unstrip-loop-warning": "Zirkelbezug festgstellt",
-       "parser-unstrip-recursion-limit": "Rekursionsgränz bim Ufflöse überschritte ($1)",
+       "unstrip-depth-warning": "Rekursionsgränz bim Ufflöse überschritte ($1)",
        "converter-manual-rule-error": "Bi dr manuälle Sprochkonvertierigsregle isch e Fähler entdeckt wore.",
        "undo-success": "Zum die Änderig ruckgängig z mache, kontrollier bitte d Bearbeitig in dr Verglichsaasicht un druck derno uf „Syte spichere“.",
        "undo-failure": "D Änderig het nid chenne ruckgängig gmacht wäre, wel dää Abschnitt mittlerwyli gänderet woren isch.",
index a291093..5ed594b 100644 (file)
        "expansion-depth-exceeded-category-desc": "עומק ההרחבה בדף גדול מהעומק המרבי.",
        "expansion-depth-exceeded-warning": "עומק ההרחבה בדף גדול מדי",
        "parser-unstrip-loop-warning": "נמצאה לולאה בפריסה",
-       "parser-unstrip-recursion-limit": "עומק הרקורסיה של הפריסה עבר את המגבלה ($1)",
+       "unstrip-depth-warning": "עומק הרקורסיה של הפריסה עבר את המגבלה ($1)",
        "converter-manual-rule-error": "התגלתה שגיאה בכלל המרת שפה ידני",
        "undo-success": "ניתן לבטל את העריכה.\nאנא {{GENDER:|בדוק|בִדקי|בִדקו}} את השוואת הגרסאות שלהלן כדי לוודא שזה אכן מה ש{{GENDER:|אתה רוצה|את רוצה|אתם רוצים}} לעשות, ולאחר מכן {{GENDER:|שמור|שִמרי|שִמרו}} את השינויים למטה כדי לסיים את ביטול העריכה.",
        "undo-failure": "לא ניתן היה לבטל את העריכה עקב התנגשות עם עריכות מאוחרות יותר.",
index a36d1d3..14163b6 100644 (file)
        "expansion-depth-exceeded-category-desc": "यह पृष्ठ विस्तार गहराई पार करता है।",
        "expansion-depth-exceeded-warning": "पृष्ठ में विस्तार गहराई पार की गई है",
        "parser-unstrip-loop-warning": "Unstrip लूप पाया गया",
-       "parser-unstrip-recursion-limit": "Unstrip पुनरावर्तन सीमा पार की गई ($1)",
+       "unstrip-depth-warning": "Unstrip पुनरावर्तन सीमा पार की गई ($1)",
        "converter-manual-rule-error": "मैन्यूअल भाषा परिवर्तन नियम में त्रुटि",
        "undo-success": "यह संपादन पूर्ववत किया जा सकता है।\nऐसा करने के लिये कृपया निम्नलिखित पाठ को ध्यान से देखकर बदलाव संजोयें।",
        "undo-failure": "इस बीच अन्य बदलाव होने के कारण यह संपादन पूर्ववत करना संभव नहीं है।",
index b96f5d0..f470fdd 100644 (file)
        "expansion-depth-exceeded-category-desc": "Panna, maximum expansion depth, se jaada hae.",
        "expansion-depth-exceeded-warning": "Panna expansion depth ke exceed karis hae",
        "parser-unstrip-loop-warning": "Unstrip loop ke pawa gai shae",
-       "parser-unstrip-recursion-limit": "Unstrip recursion limit ke exceed karaa gais hae ($1)",
+       "unstrip-depth-warning": "Unstrip recursion limit ke exceed karaa gais hae ($1)",
        "converter-manual-rule-error": "Bhasa ke anuwaad kare waala niyam me galti hae",
        "undo-success": "Ii badlao ke pahile jaise karaa jaae sake hai.\nNiche ke comparison ke check kar ke dekho ki aap yahi kare mangta rahaa, aur fir niche ke badlao ke save kar ke aapan badlao ke pahile jaise karo.",
        "undo-failure": "Ii badalo ke paile jaise nai karaa jaae sake hai kahe ki biich me badlao hai.",
index 79d086a..e0eacc7 100644 (file)
        "expansion-depth-exceeded-category": "Mga panid kon diin ang kadalumon sang pagpalapad nagsobra na",
        "expansion-depth-exceeded-warning": "Ang panid nagsobra na sa kadalumon sang pagpalapad",
        "parser-unstrip-loop-warning": "May loop nga unstrip nga nakita",
-       "parser-unstrip-recursion-limit": "Naglapaw ka na sa ginapasugtan nga pagliwat-liwat ($1)",
+       "unstrip-depth-warning": "Naglapaw ka na sa ginapasugtan nga pagliwat-liwat ($1)",
        "converter-manual-rule-error": "May sala nga nakita sa mano-mano nga pagsulunsan sa pagbadbad sang lenggwahe",
        "undo-success": "Ang pag-ilis indi mahuman.\nPalihog lantaw sang pagbaki-baki sa dalom agod to nga mapamatud-an kon amo gid man sini ang imo luyag buhaton, dayon tipona ang mga pagbag-o sa dalom agod to nga matapos ang pagliwat sang pag-ilis.",
        "undo-failure": "Ang pag-ilis indi na maliwat pa tungod sang nagakonplikto nga mga pang-tunga nga pag-ilis.",
index 5b96d4d..fa38fca 100644 (file)
        "expansion-depth-exceeded-category": "Stranice s prevelikom dubinom proširenja",
        "expansion-depth-exceeded-warning": "Na ovoj stranici dubina proširenja je prevelika",
        "parser-unstrip-loop-warning": "Nedopuštena petlja",
-       "parser-unstrip-recursion-limit": "Dosegnuto je ograničenje rekurzije ($1)",
+       "unstrip-depth-warning": "Dosegnuto je ograničenje rekurzije ($1)",
        "converter-manual-rule-error": "Pronađena je pogrješka u pravilu ručnog prijevoda",
        "undo-success": "Izmjenu je moguće ukloniti.\nMolimo Vas, usporedite niže navedene razlike u inačicama kako biste bili sigurni da ovo zaista želite učiniti, te sačuvajte stranicu i izmjene će biti uklonjene.",
        "undo-failure": "Ova izmjena ne može biti uklonjena zbog postojanja međuinačica.",
index b9e8dcf..6241578 100644 (file)
        "expansion-depth-exceeded-category": "Seite, wo die Expansionstiefe überschritt honn",
        "expansion-depth-exceeded-warning": "Die Seit hot die Expansionstiefe üwerschritt.",
        "parser-unstrip-loop-warning": "Zirkelbezuch festgestellt",
-       "parser-unstrip-recursion-limit": "Rekursionsgrenz beim Ufflöse üwerschritt ($1)",
+       "unstrip-depth-warning": "Rekursionsgrenz beim Ufflöse üwerschritt ($1)",
        "converter-manual-rule-error": "Bei der manuelle Sprochkonvertierungsrechel woard en Fehler entdeckt.",
        "undo-success": "Die Beoorbeitung kann rückgänchig gemacht werre.\nBittschön prüf den Vergleich do unne, um sicherzustelle, dass du das tun möchst, und speichre dann do unne deine Ändrunge, um die Beoorbeitung rückgängig zu mache.",
        "undo-failure": "Die Ännrung konnt net rückgängich gemacht sin, weil der betroffne Abschnitt zwischenzeitlich verännert woard.",
index 2412e0f..185a60d 100644 (file)
        "expansion-depth-exceeded-category-desc": "Strona překroša maksimalnu ekspansisku hłubokosć.",
        "expansion-depth-exceeded-warning": "Strona je ekspansisku hłubokosć překročił",
        "parser-unstrip-loop-warning": "Njeskónčna sekla namakana",
-       "parser-unstrip-recursion-limit": "Rekursiska hranica překročena ($1)",
+       "unstrip-depth-warning": "Rekursiska hranica překročena ($1)",
        "converter-manual-rule-error": "Zmylk w manuelnym prawidle rěčneho konwertowanja namakany",
        "undo-success": "Wersija je so wuspěšnje wotstroniła. Prošu přepruwuj deleka w přirunanskim napohledźe, hač twoja změna bu přewzata a klikń potom na „Składować”, zo by změnu składował.",
        "undo-failure": "Wobdźěłanje njehodźeše so wotstronić, dokelž wotpowědny wotrězk bu mjeztym změnjeny.",
index 822d64e..a38b78c 100644 (file)
        "expansion-depth-exceeded-category-desc": "Az oldal meghaladja a maximális expanziós mélységet.",
        "expansion-depth-exceeded-warning": "A lap meghaladta az engedélyezett kiterjesztési mélységet",
        "parser-unstrip-loop-warning": "Unstrip hurok észlelve",
-       "parser-unstrip-recursion-limit": "Túl mély unstrip rekurzió: $1",
+       "unstrip-depth-warning": "Túl mély unstrip rekurzió: $1",
        "converter-manual-rule-error": "Hiba van a kézi nyelvi konverziós szabályban",
        "undo-success": "A szerkesztés visszavonható. Kérlek ellenőrizd alább a változásokat, hogy valóban ezt szeretnéd-e tenni, majd kattints a lap mentése gombra a visszavonás véglegesítéséhez.",
        "undo-failure": "A szerkesztést nem lehet automatikusan visszavonni vele ütköző későbbi szerkesztések miatt.",
index fbb1bec..4910918 100644 (file)
        "expansion-depth-exceeded-category-desc": "Le pagina excede le profunditate de expansion maxime.",
        "expansion-depth-exceeded-warning": "Le profunditate de expansion in iste pagina excede le limite",
        "parser-unstrip-loop-warning": "Bucla de \"unstrip\" detegite",
-       "parser-unstrip-recursion-limit": "Limite de recursion de \"unstrip\" excedite ($1)",
+       "unstrip-depth-warning": "Limite de recursion de \"unstrip\" excedite ($1)",
        "converter-manual-rule-error": "Error detegite in le regula manual de conversion de lingua",
        "undo-success": "Le modification pote esser disfacite.\nPer favor controla le comparation infra pro verificar que tu vole facer isto, e postea salveguarda le modificationes infra pro assi disfacer le modification.",
        "undo-failure": "Le modification non poteva esser annullate a causa de conflicto con modificationes intermedie.",
index 1525a1f..4e58912 100644 (file)
        "expansion-depth-exceeded-category-desc": "Halaman yang melebihi kedalaman luas maksimum.",
        "expansion-depth-exceeded-warning": "Page exceeded the expansion depth",
        "parser-unstrip-loop-warning": "Unstrip loop detected",
-       "parser-unstrip-recursion-limit": "Unstrip recursion limit exceeded ($1)",
+       "unstrip-depth-warning": "Unstrip recursion limit exceeded ($1)",
        "converter-manual-rule-error": "Kesalahan terdeteksi di aturan manual konversi bahasa",
        "undo-success": "Suntingan ini dapat dibalikkan. Silakan periksa perbandingan di bawah untuk meyakinkan bahwa benar itu yang Anda ingin lakukan, lalu simpan perubahan tersebut untuk menyelesaikan pembalikkan suntingan.",
        "undo-failure": "Suntingan ini tidak dapat dibalikkan karena konflik penyuntingan antara.",
index 679152d..7af5424 100644 (file)
        "expansion-depth-exceeded-category-desc": "Ti panid ket nasurokanna ti kaaduan ti kauneg ti panagpadakkel.",
        "expansion-depth-exceeded-warning": "Ti panid ket nasurokanna ti kauneg ti panagpadakkel",
        "parser-unstrip-loop-warning": "Nakaduktal ti di-naukisan a silo",
-       "parser-unstrip-recursion-limit": "Nalabsan ti patingga ti panagdullit ti di-naukisan ($1)",
+       "unstrip-depth-warning": "Nalabsan ti patingga ti panagdullit ti di-naukisan ($1)",
        "converter-manual-rule-error": "Adda biddut a naduktalan iti manual nga alagaden ti panagbalbaliw ti pagsasao",
        "undo-success": "Mabalin a maisubli ti panagurnos.\nPangngaasi a kitaen ti panangiyasping dita baba tapno maammuan no daytoy ti kayatmo nga aramiden, ken kalpasanna idulin dagiti sinukatan dita baba tapno malpas ti panangisubli ti inurnos.",
        "undo-failure": "Ti inurnos ket saan a maipasubli gapu ta adda dagiti nakisinnungat a patingnga a naurnos.",
index 5bbfcda..7e2f8e6 100644 (file)
        "hiddencategories": "Ca pagino esas membro di {{PLURAL:$1|1 celita kategorio|$1 celita kategorii}}:",
        "permissionserrors": "Eroro permisal",
        "permissionserrorstext-withaction": "Vu ne darfas $2, pro la {{PLURAL:$1|kauzo|kauzi}} sequanta:",
-       "recreate-moveddeleted-warn": "<strong>Atencez: Vu rikreos pagino qua antee efacesis.</strong>\n\nVu bezonas konsiderar se esas konvenanta durar lua redakto, o ne.\nPor konveno, la motivo dil antea efaco montresas hike:",
-       "moveddeleted-notice": "Ica pagino efacabis.\nL'efaco-registraro e la movo-registraro di la pagino povas videsar sequante, por konsulto.",
+       "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-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": "Pages using invalid self-closed HTML tags",
+       "deprecated-self-close-category": "Pagini qui uzas nevalida etiketi HTML por klozajo",
        "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.",
        "rcfilters-other-review-tools": "Altra instrumenti por revizo",
        "rcfilters-activefilters": "Agiva filtrili",
        "rcfilters-advancedfilters": "Rafinita filtrili",
+       "rcfilters-show-new-changes": "Videz la maxim recenta chanji",
        "rcfilters-search-placeholder": "Filtrar la modifikuri (uzez la menuo o serchez segun la nomo dil filtrilo)",
        "rcfilters-filter-editsbyself-label": "Vua modifikuri",
        "rcfilters-filter-user-experience-level-unregistered-label": "Sen registro",
        "deletepage": "Efacar pagino",
        "confirm": "Konfirmar",
        "excontent": "La kontenajo esis: '$1'",
+       "excontentauthor": "la kontenajo esis: \"$1\", e l'unika redaktero esis \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|talk]])",
        "exbeforeblank": "La kontenajo ante efaco esis: '$1'",
        "delete-confirm": "Efacar \"$1\"",
        "delete-legend": "Efacar",
        "editcomment": "La rezumo di la redakto esis: <em>$1</em>.",
        "revertpage": "Desfacita redakti da [[Special:Contributions/$2|$2]] ([[User talk:$2|Debato]]) e rekuperita la lasta redakto da [[User:$1|$1]]",
        "rollback-success": "Desfacis redakti da $1;\nrestauris ad lasta versiono da $2.",
+       "sessionfailure": "Semblas ke eventis problemo kun vua sesiono di 'login';\nta agado abrogesis, quale presorgo kontre sequestro di sesiono ('hijacking').\nVoluntez risendar la formulario, plenigita.",
        "protectlogpage": "Protekto-registraro",
        "protectedarticle": "protektita \"[[$1]]\"",
        "modifiedarticleprotection": "la nivelo di protekto modifikesis a \"[[$1]]\"",
        "move-page": "Movar $1",
        "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!",
        "movenologintext": "Vu mustas esar registragita uzero ed [[Special:UserLogin|enirir]] por rinomizar pagino.",
        "newtitle": "Nova titulo:",
        "move-watch": "Surveyar ca pagino",
        "pageinfo-robot-index": "Permisita",
        "pageinfo-robot-noindex": "Interdiktata",
        "pageinfo-watchers": "Quanto di personi qui vidis ca pagino",
+       "pageinfo-visiting-watchers": "Quanto di viziteri qui vidis recenta redakturi",
        "pageinfo-few-watchers": "Min kam $1 {{PLURAL:$1|vidinto|vidinti}}",
        "pageinfo-redirects-name": "Quanto di ridirekti ad ica pagino",
        "pageinfo-subpages-name": "Quanto di subpagini en ica pagino",
index 6cd24ec..434a6a8 100644 (file)
        "expansion-depth-exceeded-category": "Þær síður þar sem farið er út fyrir leyfða dýpt útvíkkunar",
        "expansion-depth-exceeded-warning": "Síðan fer út fyrir leyfða dýpt útvíkkunar",
        "parser-unstrip-loop-warning": "\"Unstrip\" lykkja fannst",
-       "parser-unstrip-recursion-limit": "Farið út fyrir „unstrip“ endurkvæmnismörk ($1)",
+       "unstrip-depth-warning": "Farið út fyrir „unstrip“ endurkvæmnismörk ($1)",
        "converter-manual-rule-error": "Villa í reglu handvirks tungumálabreytis",
        "undo-success": "Það er hægt að afturkalla breytinguna.\nAthugaðu vel samanburðinn hér fyrir neðan til að sannreyna að það sé það sem þú vilt gera, vistaðu svo breytingarnar hér fyrir neðan til að ljúka afturköllun breytinganna.",
        "undo-failure": "Breytinguna var ekki hægt að taka tilbaka vegna breytinga í millitíðinni.",
index 621d4d2..d827833 100644 (file)
        "expansion-depth-exceeded-category-desc": "La pagina supera la profondità massima di espansione.",
        "expansion-depth-exceeded-warning": "Questa pagina ha superato la profondità di espansione",
        "parser-unstrip-loop-warning": "Rilevato ciclo di Unstrip",
-       "parser-unstrip-recursion-limit": "Superati i limiti di ricorsione di Unstrip ($1)",
+       "unstrip-depth-warning": "Superati i limiti di ricorsione di Unstrip ($1)",
        "converter-manual-rule-error": "Rilevato errore nella regola manuale di conversione della lingua",
        "undo-success": "Questa modifica può essere annullata.\nControlla le differenze mostrate sotto fra le due versioni per essere certo che il contenuto corrisponda a quanto desiderato, e quindi salvare le modifiche per completare la procedura di annullamento.",
        "undo-failure": "Impossibile annullare la modifica a causa di un conflitto con modifiche intermedie.",
index a9f1877..d20092c 100644 (file)
        "expansion-depth-exceeded-category-desc": "展開の深さが上限を超えたページ。",
        "expansion-depth-exceeded-warning": "ページが展開の深さ制限を超えました",
        "parser-unstrip-loop-warning": "unstrip のループを検出しました",
-       "parser-unstrip-recursion-limit": "unstrip の再帰 ($1) が上限を超えました",
+       "unstrip-depth-warning": "unstrip の再帰 ($1) が上限を超えました",
        "converter-manual-rule-error": "手動の言語変換規則でエラーを検出しました。",
        "undo-success": "この編集を取り消せます。\n下記の差分を確認して、本当に取り消していいか検証してください。よろしければ変更を保存して取り消しを完了してください。",
        "undo-failure": "中間の版での編集と競合したため、取り消せませんでした。",
index 2307512..48cef66 100644 (file)
        "expansion-depth-exceeded-category": "Kaca sing jeroné èkspansi wis punjul",
        "expansion-depth-exceeded-warning": "Kaca munculi jeroné èkspansi",
        "parser-unstrip-loop-warning": "Unstrip loop detected",
-       "parser-unstrip-recursion-limit": "Unstrip recursion limit exceeded ($1)",
+       "unstrip-depth-warning": "Unstrip recursion limit exceeded ($1)",
        "converter-manual-rule-error": "Masalah kapranggul ing aturan konvèrsi basa manual",
        "undo-success": "Besutan iki kena diwurungaké.\nTiliki bandhingan ngisor iki saperlu mesthèkaké yèn bener iki sing arep kolakoni, nuli simpen owahan ngisor iki kanggo ngiyai yèn besutané diwurungaké.",
        "undo-failure": "Besutan iki ora bisa dipulihaké amarga bisa cengkah besutan antara.",
index 12d4f00..930be78 100644 (file)
        "expansion-depth-exceeded-category-desc": "გვერდს აქვს გადაჭარბებული გაღების სიღრმის მაქსიმალურად დასაშვები რაოდენობა",
        "expansion-depth-exceeded-warning": "გვერდზე გადამეტებულია ჩადგმების ზღვარი",
        "parser-unstrip-loop-warning": "აღმოჩენილია ციკლური ბმული",
-       "parser-unstrip-recursion-limit": "გადამეტებულია რეკურსიის ზღვარი ($1)",
+       "unstrip-depth-warning": "გადამეტებულია რეკურსიის ზღვარი ($1)",
        "converter-manual-rule-error": "შეცდომა ენის ხელით გარდაქმნის წესში",
        "undo-success": "რედაქტირების გაუქმება შესაძლებელია. გთხოვთ შეამოწმოთ განსხვავება ქვევით, რათა დარწმუნდეთ, რომ ეს ის არის რაც თქვენ გსურთ, შემდეგ კი შეინახეთ ცვლილებები რათა დაასრულოთ რედაქტირების გაუქმება.",
        "undo-failure": "რედაქტირების გაუქმება შეუძლებელია კონფლიქტური შუალედური რედაქტირებების გამო.",
index 79e1c1a..657d7cb 100644 (file)
        "expansion-depth-exceeded-category-desc": "Asebter iɛedda talqayt n temɣer tafellayt.",
        "expansion-depth-exceeded-warning": "Isebtar yefelen lqay n uderrec",
        "parser-unstrip-loop-warning": "Tifin n tineddict ur nezmer ara an sentuter",
-       "parser-unstrip-recursion-limit": "Talast n usniles ur nezmer ara an sentuter tefel ($1)",
+       "unstrip-depth-warning": "Talast n usniles ur nezmer ara an sentuter tefel ($1)",
        "converter-manual-rule-error": "Tifin n unezri deg alugen awfus n uselket n tutlayt",
        "undo-success": "Tzemreḍ ad tessefsuḍ abeddil. Ssenqed asidmer akken ad tessneḍ ayen tebɣiḍ ad txdmeḍ d ṣṣeḥ, umbeɛd smekti ibeddlen u tkemmleḍ ad tessefsuḍ abeddil.",
        "undo-failure": "Ur yezmir ara ad issefu abeddel axaṭer yella amennuɣ abusari deg ubeddel.",
index 14b3f39..d21be5a 100644 (file)
        "expansion-depth-exceeded-category": "НапэкӀуэцӀым и зыубгъуэн Ӏувагъыр къехъу щытщ",
        "expansion-depth-exceeded-warning": "НапэкӀуэцӀып и зэфӀэгъэкӀыгъуэр къегъэхъуауэ щытщ",
        "parser-unstrip-loop-warning": "Зэрыдзэгъуэ зэхуэмыщӀа къыхэкӀащ",
-       "parser-unstrip-recursion-limit": "Рекурсым и зэфӀэгъэкӀыгъуэр къегъэхъуауэ щытщ ($1)",
+       "unstrip-depth-warning": "Рекурсым и зэфӀэгъэкӀыгъуэр къегъэхъуауэ щытщ ($1)",
        "undo-success": "Гъэтэрэзыгъуэр хахыжьыфынущ. Версиэхэм я зэгъэпшыгъуэ егъэкӀуэкӀ, узхуэныкъуэхэрамэ пщӀам еплъи «НапэкӀуэцӀыр итхэн»-ым текъузэ, зэхъуэкӀыгъуэхэр хэхьэным щхьэкӀэ.",
        "undo-failure": "Гъэтэрэзыгъуэр хэхыжа хъунукъым, гъэтэрэзыгъуэхэм я зэпхыгъуэр зэремыкӀуэкӀыфым щхьэкӀэ",
        "undo-norev": "Гъэтэрэзыгъуэр хэхыжа хъунукъым зэрщымыӀэм щхьэкӀэ иэ хэхыжагъыху щытщ.",
index 5c06c7c..95af0b1 100644 (file)
        "expansion-depth-exceeded-category-desc": "Жіктелім тереңдігі шегінен асқан бет.",
        "expansion-depth-exceeded-warning": "Жіктелім тереңдігі асып кеткен бет",
        "parser-unstrip-loop-warning": "Жабылмаған тег анықталды (<pre> осындай)",
-       "parser-unstrip-recursion-limit": "Unstrip рекурсия шегінен асты ($1)",
+       "unstrip-depth-warning": "Unstrip рекурсия шегінен асты ($1)",
        "converter-manual-rule-error": "Қолмен тілді түрлендіру ережесінде қате кездесті",
        "undo-success": "Бұл өңдемені жоққа шығарымақшысыз. Алдымен алдын-ала төмендегі салыстыруды тексеріп шығыңыз да бетті сақтаңыз.",
        "undo-failure": "Бұл өңдеме жоққа шығарылмайды, себебі арада қақтығысты өңдемелер бар.",
index 7812d03..eeb13e6 100644 (file)
@@ -68,7 +68,8 @@
                        "Sukjong0406",
                        "Garam",
                        "렌즈",
-                       "CYAN"
+                       "CYAN",
+                       "Nuevo Paso"
                ]
        },
        "tog-underline": "링크에 밑줄:",
        "userinvalidconfigtitle": "<strong>경고:</strong> \"$1\" 스킨은 없습니다.\n.css와 .js 문서의 제목은 {{ns:user}}:Foo/vector.css 처럼 소문자로 써야 합니다. {{ns:user}}:Foo/Vector.css 와 같이 대문자로 쓸 경우 작동하지 않습니다.",
        "updated": "(바뀜)",
        "note": "<strong>참고:</strong>",
-       "previewnote": "'''ì\9d´ í\99\94ë©´ì\9d\80 ë¯¸ë¦¬ ë³´ê¸°ì\9e\85ë\8b\88ë\8b¤.'''\ní\8e¸ì§\91í\95\9c ë\82´ì\9a©ì\9d\80 ì\95\84ì§\81 ì \80ì\9e¥í\95\98ì§\80 ì\95\8aì\95\98ì\8aµë\8b\88ë\8b¤!",
+       "previewnote": "'''ì§\80ê¸\88 ë³´ê³  ì\9e\88ë\8a\94 í\99\94ë©´ì\9d\80 ë¯¸ë¦¬ ë³´ê¸°ì\9e\85ë\8b\88ë\8b¤.''' í\8e¸ì§\91í\95\9c ë\82´ì\9a©ì\9d\80 ì\95\84ì§\81 ì \80ì\9e¥ë\90\98ì§\80 ì\95\8aì\95\98ì\8aµë\8b\88ë\8b¤!",
        "continue-editing": "편집 영역으로 가기",
        "previewconflict": "이 미리 보기는 저장할 때의 모습으로, 위쪽 편집 영역의 텍스트를 반영합니다.",
        "session_fail_preview": "세션 데이터가 없어져 편집을 저장하지 못했습니다.\n\n로그아웃되었는지도 모릅니다. <strong>아직 로그인 상태인지 확인하고 다시 시도해주세요</strong>.\n다시 시도해도 되지 않으면 [[Special:UserLogout|로그아웃]]한 다음 다시 로그인하세요. 그리고 브라우저 설정에서 쿠키 사용을 허용하는지 확인하세요.",
        "expansion-depth-exceeded-category-desc": "최대 확장 깊이를 초과하는 문서입니다.",
        "expansion-depth-exceeded-warning": "문서가 확장 깊이를 초과하였습니다",
        "parser-unstrip-loop-warning": "Unstrip의 반복을 감지했습니다",
-       "parser-unstrip-recursion-limit": "Unstrip의 재귀 한도를 초과했습니다 ($1)",
+       "unstrip-depth-warning": "Unstrip의 재귀 한도를 초과했습니다 ($1)",
        "converter-manual-rule-error": "언어 변환 규칙을 수동으로 지정하는 도중 오류",
        "undo-success": "편집을 되돌릴 수 있습니다.\n이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 저장해주세요.",
        "undo-failure": "중간의 다른 편집과 충돌하여 이 편집을 되돌릴 수 없습니다.",
index 0ad036c..dbed1d8 100644 (file)
        "expansion-depth-exceeded-category": "Кериуню теренлиги оздурулгъан бетле",
        "expansion-depth-exceeded-warning": "Бетде ичине салыныуну чеги оздурулгъанды",
        "parser-unstrip-loop-warning": "Джабылмагъан pre табылды",
-       "parser-unstrip-recursion-limit": "Рекурсияны чеги ($1) оздурулду",
+       "unstrip-depth-warning": "Рекурсияны чеги ($1) оздурулду",
        "converter-manual-rule-error": "Тилни башха тюрлю этиуню къол джоругъунда халат",
        "undo-success": "Бу тюрлениу ызына алыныргъа боллукъду. Тилейбиз, версияланы тенглешдириуюн осмакълагъыз, керти да бу тюрлендириулени этерге излегенигизден ишексиз болугъуз, сора, тюрлениуле къабыл этилир ючюн, «Бетни къош» деген тиекден басыгъыз.",
        "undo-failure": "Бир-бирине келишмегени себебли, тюрлениу ызына алынамады.",
index 5c91541..68897b1 100644 (file)
        "expansion-depth-exceeded-category-desc": "Dat heh es de Saachjropp för Sigge, woh zoh vill automattesch ennjeföhsch weed.",
        "expansion-depth-exceeded-warning": "En heh di Sigg weed zoh vill automattesch ennjeföhsch.",
        "parser-unstrip-loop-warning": "Ene Befähl em Täx betrek sesch op sesch sällefs.",
-       "parser-unstrip-recursion-limit": "Ene Befähl em Täx es mieh wi {{PLURAL:$1|eijmohl|$1 Mohl|jaa nit}} met  sesch sellef verschachtelt.",
+       "unstrip-depth-warning": "Ene Befähl em Täx es mieh wi {{PLURAL:$1|eijmohl|$1 Mohl|jaa nit}} met  sesch sellef verschachtelt.",
        "converter-manual-rule-error": "Doh es ene Fähler en ene händesche Önwandelongsrääjel zwesche de Schprohche.",
        "undo-success": "De Änderong könnte mer zeröck nämme. Belohr Der de Ungerscheide un dann donn di Sigg avspeijschere, wann De dängks, et es en Ohdenong esu.",
        "undo-failure": "Dat kunnt mer nit zeröck nämme, dä Afschnedd wood enzwesche ald widder beärbeidt.",
index 1554705..fe009cb 100644 (file)
        "redirectedfrom": "(Ji $1 hate beralîkirin)",
        "redirectpagesub": "Rûpelê beralî bike",
        "redirectto": "Beraliyê vir bike:",
-       "lastmodifiedat": "Ev rûpel cara dawî $1, seet li $2an de hate guherandin.",
+       "lastmodifiedat": "Ev rûpel cara dawî $1, seet li $2an de hatiye guherandin.",
        "viewcount": "Ev rûpel {{PLURAL:$1|carekê|caran}} tê xwestin.",
        "protectedpage": "Rûpela parastî",
        "jumpto": "Here cem:",
        "searchsuggest-search": "Li ser {{SITENAME}} bigere",
        "searchsuggest-containing": "dihundirîne...",
        "api-error-unknownerror": "Çewtiya nenas: \"$1\".",
-       "duration-days": "$1 {{PLURAL:$1|roj|roj}}",
+       "duration-days": "$1 {{PLURAL:$1|roj|rojan}}",
        "duration-years": "$1 {{PLURAL:$1|sal}}",
        "duration-centuries": "$1 {{PLURAL:$1|sedsal}}",
        "expand_templates_output": "Encam",
index 75b6996..ef6e8ab 100644 (file)
@@ -5,6 +5,7 @@
                        "ArslanX"
                ]
        },
+       "underline-never": "Гьеч бир де",
        "sunday": "Къаттыгюн",
        "monday": "Итнигюн",
        "tuesday": "Талатгюн",
        "oct": "Бай",
        "nov": "Май",
        "dec": "Тун",
+       "january-date": "Аювятгъан $1",
+       "february-date": "Чилле $1",
+       "march-date": "Оьрткий $1",
+       "april-date": "Яйсан $1",
+       "may-date": "Гюлжан $1",
+       "june-date": "Кюржан $1",
+       "july-date": "Индыр $1",
+       "august-date": "Туршу $1",
+       "september-date": "Къочкъар $1",
+       "october-date": "Байсан $1",
+       "november-date": "Маййилик $1",
+       "december-date": "Тунлу $1",
        "pagecategories": "{{PLURAL:$1|Категория|Категориялар}}‎",
        "category_header": "\"$1\" категориядан сагьифалар",
        "subcategories": "Субкатегориялар",
@@ -62,7 +75,7 @@
        "category-empty": "\"Бу категория буссагьат бош.\"",
        "hidden-categories": "{{PLURAL:$1|Яшырылгъан категория|Яшырылгъан категориялар}}‎",
        "category-subcat-count": "{{PLURAL:$2|Бу категорияда тек сонггъу гелеген тюпкатегориясы бар.|Бу категорияда {{PLURAL:$1|тюпкатегория|$1 тюпкатегориялар}} бар, жамда $2 тюпкатегориядан.}}",
-       "category-article-count": "{{PLURAL:$2|Бу категорияда янгыз гелеген бир сагьифа бар.|Бу категорияда бар $2 сагьифаны {{PLURAL:$1|сагьифасы}} гёрсетилген.}}",
+       "category-article-count": "{{PLURAL:$2|Бу категорияда янгыз гелеген бир сагьифа бар.|Бу категориядагъы $2 {{PLURAL:$1|сагьифасы}} гёрсетилген.}}",
        "category-file-count": "{{PLURAL:$2|Бу категорияда бир тек сонггъу гелеген сапламы бар.|Сонггъу гелеген {{PLURAL:$1|саплам|$1 сапламлар}}{{PLURAL:$2|категориядадыр|категориядадырлар}}}}.",
        "listingcontinuesabbrev": "давам",
        "noindex-category": "Индексленмейген сагьифалар",
        "about": "Сыпатлав",
        "newwindow": "(янгы терезеде ачыла)",
        "cancel": "Гери этмек",
+       "moredotdotdot": "Артыкъ...",
+       "mypage": "Сагьифа",
        "mytalk": "Сёйлешив",
+       "anontalk": "Сёйлешив",
        "navigation": "Навигация",
        "and": "&#32;ва",
+       "faq": "КЧС",
+       "actions": "Гьаракатлар",
        "namespaces": "Атлар аралыгъы",
        "variants": "Тюрлер",
        "navigation-heading": "Навигация менюсю",
+       "errorpagetitle": "Хата",
        "returnto": "$1 сагьифагъа къайтмакъ",
        "tagline": "{{SITENAME}}‎ проектден",
        "help": "Кёмек",
        "search": "Излев",
        "searchbutton": "Излев",
+       "go": "Гёчмек",
        "searcharticle": "Гёчмек",
        "history": "Сагьифа тарихы",
        "history_short": "Тарих",
+       "history_small": "тарих",
        "printableversion": "Басмалы версиясы",
        "permalink": "Даимги байланыв",
+       "print": "Басмакъ",
        "view": "Къарав",
        "view-foreign": "$1 сайтында къарамакъ",
        "edit": "Тюзлемек",
        "create": "Яратмакъ",
        "create-local": "Ерли сыпатлавун тюзлемек",
        "delete": "Тайдырмакъ",
+       "protect": "Къорумакъ",
+       "protect_change": "алышдырмакъ",
        "newpage": "Янгы сагьифа",
        "talkpagelinktext": "сёйлешив",
+       "specialpage": "Хас сагьифа",
        "personaltools": "Энчили къураллар",
        "talk": "Сёйлешив",
        "views": "Къаравлар",
        "toolbox": "Къураллар",
+       "imagepage": "Саплам сагьифасына къарамакъ",
+       "mediawikipage": "Мактупну сагьифасына къарамакъ",
+       "templatepage": "Къалипны сагьифасына къарамакъ",
+       "viewhelppage": "Кёмек сагьифасына къарамакъ",
+       "viewtalkpage": "Сёйлешивюне къарамакъ",
        "otherlanguages": "Башгъа тиллерде",
        "redirectedfrom": "($1 бетинден бакъдырылгъан)‎",
        "redirectpagesub": "Ёллав сагьифа",
        "redirectto": "Ёллав мунда:",
        "lastmodifiedat": "Бу сагьифаны ахырынчы тюзлевлер болгъан: $1, $2.",
+       "protectedpage": "Къорулгъан сагьифа",
        "jumpto": "Мунда гёчмек:",
        "jumptonavigation": "навигация",
        "jumptosearch": "излев",
+       "poolcounter-usage-error": "Къоллав хата: $1",
        "aboutsite": "{{SITENAME}} гьакъында",
        "aboutpage": "Project:Сыпатлав",
        "copyright": "Ичделиги $1 лисензиягъа гёре гиришли (башгъасы мекенленмеген буса).",
        "disclaimers": "Жаваплылыкъдан къайтыв",
        "disclaimerpage": "Project:Умуми жаваплылыкъдан къайтыву",
        "edithelp": "Тюзлев гьакъында кёмек",
+       "helppage-top-gethelp": "Кёмек",
        "mainpage": "Баш Сагьифа",
        "mainpage-description": "Баш сагьифа",
        "portal": "Бирлешив портал",
        "portal-url": "Project:Бирлешив портал",
        "privacy": "Энчилилик ёругъу",
        "privacypage": "Project:Конфиденциаллыкъ сиясаты",
+       "ok": "OK",
        "retrievedfrom": "Чыкъмагъы — «$1»",
        "youhavenewmessages": "{{PLURAL:$3|Сен алдынг}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$3|Башгъа къоллавчудан|$3 къоллавчулардан}} ($2) $1 {{PLURAL:$4|алдынг}}.",
-       "newmessageslinkplural": "{{PLURAL:$1|янгы мактуп|999=янгы мактуп}}",
+       "newmessageslinkplural": "{{PLURAL:$1|янгы мактуп|999=янгы мактуплар}}",
        "newmessagesdifflinkplural": "last {{PLURAL:$1|алышыныв|999=алышынывлар}}",
+       "youhavenewmessagesmulti": "Сен мунда $1 янгы мактуп алдынг",
        "editsection": "тюзлемек",
        "editold": "тюзлемек",
        "viewsourceold": "кюрчю кодуна къарамакъ",
        "viewsourcelink": "кюрчю кодуна къарамакъ",
        "editsectionhint": "Бёлмени тюзлемек: $1",
        "toc": "Ичделик",
+       "showtoc": "гёрсетмек",
+       "hidetoc": "яшырмакъ",
+       "collapsible-collapse": "чырмамакъ",
+       "collapsible-expand": "генглешдирмек",
+       "confirmable-confirm": "{{GENDER:$1|сен}} аминмисен?",
+       "confirmable-yes": "Дюр",
+       "confirmable-no": "Ёкъ",
+       "feedlinks": "Агъыш",
        "site-atom-feed": "$1 Atom агъышы",
        "page-atom-feed": "\"$1\" Atom агъышы",
        "red-link-title": "$1 (олай сагьифасы ёкъдур)",
        "nstab-image": "Саплам",
        "nstab-mediawiki": "Мактуп",
        "nstab-template": "Къалип",
+       "nstab-help": "Кёмек сагьифа",
        "nstab-category": "Категория",
        "mainpage-nstab": "Баш сагьифа",
        "nosuchspecialpage": "Олай хас сагьифасы ёкъдур",
        "nospecialpagetext": "<strong>Сен талап этген хас сагьифа ёкъ.</strong>\n\nДурус хас сагьифалар булан тизме мунда: [[Special:SpecialPages|{{int:specialpages}}]].",
+       "error": "Хата",
+       "databaseerror-function": "Функция: $1",
+       "databaseerror-error": "Хата: $1",
+       "internalerror": "Ичдеги хата",
        "badtitle": "Къыйышмайгъан ат",
        "badtitletext": "Чакъырылгъан сагьифаны аты бузукъ эди, яда бош, яда тил-ара яда вики-ара байланывлары янгылыш кюйде берилген эди.\nБалики, атында бир-эки ярамайгъан гьарп берилген эди.",
        "viewsource": "Кюрчю кодуна къарамакъ",
        "nextrevision": "Сонггъу тюрю →",
        "currentrevisionlink": "Ахырынчы тюрю",
        "cur": "гьал.",
-       "last": "алкъ.",
+       "last": "ингкъ.",
        "histlegend": "Тюзлевлерден сайлав: тенглешдирмеге сюеген бары тюрлерин белгилеп '''{{int:compare-submit}}''' бас.<br />\nАчыкълавлар: '''({{int:cur}})''' — гьалиги тюрюнден башгъалыкъ; '''({{int:last}})''' — алдагъы тюрюнден башгъалыкъ; '''{{int:minoreditletter}}''' — увакъ тюзелтив.",
        "history-fieldset-title": "Тюзлевлеге излев",
        "histfirst": "инг эсгилер",
        "allpages-hide-redirects": "Ёллавланы яшырмакъ",
        "categories": "Категориялар",
        "listgrouprights-members": "(ортакъчы тизмеси)",
+       "trackingcategories-name": "Мактупну аты",
        "emailuser": "Ортакъчыгъа мактуб",
+       "emailmessage": "Мактуп:",
+       "emailccme": "Мактупну копиясын магъа e-mail таба йибермек.",
+       "usermessage-summary": "Систем мактуп язмакъ.",
        "usermessage-editor": "Ёрукъ йиберив",
        "watchlist": "Гьызарлав сиягьы",
        "mywatchlist": "Гьызарлав сиягьы",
        "proxyblocker": "Прокси къамаву",
        "movelogpage": "Ат алышдырыв журналы",
        "export": "Сагьифаланы тышдан алыв",
+       "allmessages": "Систем мактуплар",
        "thumbnail-more": "Уллулашдырмакъ",
        "importlogpage": "Импорт гюнделиги",
        "tooltip-pt-userpage": "{{GENDER:|Сени}} къоллавчу сагьифанг",
        "logentry-newusers-autocreate": "$1 ортакъчыны гьисабы оьзлюгюнден {{GENDER:$2|яратылды}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|юклеген}} $3",
        "logentry-upload-overwrite": "$1 буну $3 янгы тюрюн {{GENDER:$2|юклеген}}",
+       "feedback-message": "Мактуп:",
        "searchsuggest-search": "{{SITENAME}} ичинде излемек",
        "duration-days": "$1 {{PLURAL:$1|гюн}}",
        "randomrootpage": "Хапарсыз тамур сагьифасы"
index daeb9d6..99037d4 100644 (file)
        "expansion-depth-exceeded-category-desc": "La paje esede la profondia masima de estende.",
        "expansion-depth-exceeded-warning": "La paje ia esede la profondia de estende",
        "parser-unstrip-loop-warning": "Sicle de unstrip() detetada",
-       "parser-unstrip-recursion-limit": "Esede de la recorsa masima de unstrip() ($1)",
+       "unstrip-depth-warning": "Esede de la recorsa masima de unstrip() ($1)",
        "converter-manual-rule-error": "Era detetada en regula nonautomata de converti de lingua",
        "undo-success": "La edita pote es desfada.\nPer favore, esamina la compara a su per serti ce tu vole fa esta, e alora fisa la cambias a su per fini desfa la edita.",
        "undo-failure": "La edita no pote es desfada par causa de editas interveninte cual contradise lo.",
index 85e6a98..ceb8d95 100644 (file)
        "botpasswords-insert-failed": "'t Touveuge vanne botnaam \"$1\" is mislök. Is dae mesjiens al tougeveug?",
        "botpasswords-update-failed": "'t Biewirke vanne botnaam \"$1\" is mislök. Is dae mesjiens eweggesjaf?",
        "botpasswords-created-title": "Botwachwaord aangemaak",
-       "botpasswords-created-body": "'t Botwachwaord veure botnaam \"$1\" van gebroeker \"$2\" is gemaak.",
+       "botpasswords-created-body": "'t Botwachwaord veure botnaam \"$1\" van {{GENDER:$2|gebroeker}} \"$2\" is gemaak.",
        "botpasswords-updated-title": "Botwachwaord biegewirk",
-       "botpasswords-updated-body": "'t Botwachwaord veur de botnaam \"$1\" van gebroeker \"$2\" is biegewirk.",
+       "botpasswords-updated-body": "'t Botwachwaord veur de botnaam \"$1\" van {{GENDER:$2|gebroeker}} \"$2\" is biegewirk.",
        "botpasswords-deleted-title": "Botwachwaord eweggesjaf",
-       "botpasswords-deleted-body": "'t Botwachwaord veure botnaam \"$1\" vanne gebroeker \"$2\" is eweggesjaf.",
+       "botpasswords-deleted-body": "'t Botwachwaord veure botnaam \"$1\" vanne {{GENDER:$2|gebroeker}} \"$2\" is eweggesjaf.",
        "botpasswords-newpassword": "'t Nuuj wachwaord veur aan te melje mit <strong>$1</strong> is <strong>$2</strong>. <em>Bewaar dit goed voor toekomstig gebruik.</em> <br> (Veur aaj bots die vereisje det de aameljnaam 'tzelfde is es d'n eventuele gebroekersnaam, kan ouch <strong>$3</strong> es gebroekersnaam en <strong>$4</strong> es wachwaord waere gebroek.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider is neet besjikbaar.",
        "botpasswords-restriction-failed": "Botwachwaordbepirkinge verkómme aanmelje.",
        "postedit-confirmation-created": "De pagina is aangemaak gewaore.",
        "postedit-confirmation-restored": "De pagina is herstèldj gewaore.",
        "postedit-confirmation-saved": "Dien bewirking is opgeslage gewaore.",
+       "postedit-confirmation-published": "Dien bewirking is opgeslage.",
        "edit-already-exists": "De pagina is neet aangemaak.\nZie besjteit al.",
        "defaultmessagetext": "Obligaten teks",
        "content-failed-to-parse": "'t Waas neet meugelik d'n inhawd van 't MIME-typ $2 veur 't model $1 te verwirke: $3.",
        "expansion-depth-exceeded-category-desc": "De pagina geit euver de maximaal oetbreijingsdeepdje.",
        "expansion-depth-exceeded-warning": "De paasj haet te väöl sjablone",
        "parser-unstrip-loop-warning": "Unstriplus gevónje",
-       "parser-unstrip-recursion-limit": "Unstriprecursielimiet te väöl ($1)",
+       "unstrip-depth-warning": "Unstriprecursielimiet te väöl ($1)",
        "converter-manual-rule-error": "'n Fout is óntdèk gewaore in 'ne handjmaesig tougeveudje spraokómzèttingsregel",
        "undo-success": "Hiej onger stuit de teks wo in de verangering ongedaon gemaak is. Controleer veur 't opslaon of 't resultaot gewins is.",
        "undo-failure": "De verangering kòs neet ongedaon gemaak waere waeges angere striedige verangeringe.",
        "diff-multi-sameuser": "({{PLURAL:$1|Ein tösseligkendje versie|$1 tösseligkendje versies}} door dezelfdje gebroeker neet getoeandj)",
        "diff-multi-otherusers": "({{PLURAL:$1|Ein tösseligkendje versie|$1 tösseligkendje versies}} door {{PLURAL:$2|einen angere gebroeker|$2 gebroekers}} neet getuind)",
        "diff-multi-manyusers": "($1 tösseligkende versies door mier es $2 gebroekers waere neet waergaeve)",
+       "diff-paragraph-moved-tonew": "Dees paragraaf is verplaats wore. Klik veur nao 'n nuuj lokaasje te springe.",
+       "diff-paragraph-moved-toold": "Dees paragraaf is verplaats wore. Klik veur nao de aaj lokaasje te springe.",
        "searchresults": "Zeukresultate",
        "searchresults-title": "Zeukresultate veur \"$1\"",
        "titlematches": "Overeinkoms mèt volgende titels",
        "timezoneregion-europe": "Europa",
        "timezoneregion-indian": "Indische Oceaan",
        "timezoneregion-pacific": "Stille Oceaan",
-       "allowemail": "E-mail van anger gebroekers toesjtaon",
+       "allowemail": "Stank anger gebroekers toe mich te e-maile",
+       "email-allow-new-users-label": "Stank e-mails van kaesnuuj gebroekers toe",
+       "email-blacklist-label": "Verbeej dees gebroekers mich te e-maile:",
        "prefs-searchoptions": "Zeuke",
        "prefs-namespaces": "Naamruimte",
        "default": "sjtandaard",
        "right-unblockself": "Óntblok eige gebroeker",
        "right-protect": "Beveiligingsniveaus aanpasse",
        "right-editprotected": "Beveiligde pazjena's bewirke",
+       "right-editsemiprotected": "Bewirk pagina's die zint beveilig es \"{{int:protect-level-autoconfirmed}}\"",
+       "right-editcontentmodel": "Bewirk 't pagina-inhawdmodel",
        "right-editinterface": "De gebroekersinterface bewerke",
        "right-editusercss": "De CSS-bestande van angere gebroekers bewerke",
        "right-edituserjs": "De JS-bestande van angere gebroekers bewerke",
+       "right-editmyusercss": "Bewirk dien eige CSS-pagina's",
+       "right-editmyuserjs": "Bewirk dien eige JavaScrippagina's",
        "right-viewmywatchlist": "Betrach dien eige volglies",
+       "right-editmywatchlist": "Bewirk dien eige volglies. Via sommige hanjelinge kinne nag ummer pagina's waere tougeveug, zelfs zónger dees beveugheid.",
+       "right-viewmyprivateinfo": "Betrach dien eige privégegaeves (wie e-mailadres, echte naam)",
+       "right-editmyprivateinfo": "Bewirk dien eige privégegaeves (wie e-mailadres, echte naam)",
        "right-editmyoptions": "Bewirk dien eige veurkäöre",
        "right-rollback": "Snel de letste bewerking(e) van 'n gebroeker van 'n pagina terugdraaie",
        "right-markbotedits": "Teruggedraaide bewerkinge markere es botbewerkinge",
        "right-siteadmin": "De database blokkere en weer vriegaeve",
        "right-override-export-depth": "Export paazjes midin geslinkdje paazjes mit 'n deepdje ven 5",
        "right-sendemail": "Versjik e-mail aan anger gebroekers",
+       "right-managechangetags": "Maak en (de)aktiveer [[Special:Tags|labels]]",
+       "right-applychangetags": "Wies [[Special:Tags|labels]] tou aan bewirkinge",
+       "right-deletechangetags": "Sjaf [[Special:Tags|labels]] eweg van de database",
        "grant-generic": "Rechtegroep \"$1\"",
        "grant-group-page-interaction": "Wirk mit pagina's",
        "grant-group-file-interaction": "Wirk mit media",
        "grant-createaccount": "Maak gebroekers aan",
        "grant-createeditmovepage": "Maak, bewirk en verplaats pagina's",
        "grant-delete": "Wösj pagina's, bewirkinge en logbookregele",
+       "grant-editinterface": "Bewirk de MediaWiki-naamruumde en CSS/JavaScrip van gebroekers",
        "grant-editmycssjs": "Bewirk diene CSS/JavaScript",
        "grant-editmyoptions": "Bewirk dien veurkäöre",
        "grant-editmywatchlist": "Bewirk dien volglies",
        "grant-editpage": "Bewirk bestäöndje pagina's",
        "grant-editprotected": "Bewirk besjurmde pagina's",
+       "grant-highvolume": "Maak väöl bewirkinge in korten tied",
+       "grant-oversight": "Verstaek gebroekers en versies",
+       "grant-patrol": "Controleer verangeringe aan pagina's",
+       "grant-privateinfo": "Betrach perseunlike gegaeves",
+       "grant-protect": "Besjirm en gaef pagina's vrie",
+       "grant-rollback": "Drej bewirkinge aan pagina's trök",
+       "grant-sendemail": "Versjik e-mail aan anger gebroekers",
+       "grant-uploadeditmovefile": "Upload, vervang en verplaats bestenj",
+       "grant-uploadfile": "Upload nuuj bestenj",
        "grant-basic": "Basisrechte",
+       "grant-viewdeleted": "Betrach gewösjde bestenj en pagina's",
+       "grant-viewmywatchlist": "Betrach dien volglies",
+       "grant-viewrestrictedlogs": "Betrach vertroewelike logbookbestenj",
        "newuserlogpage": "Logbook nuuj gebroekers",
        "newuserlogpagetext": "Hiej ónger saton de nuuj ingesjreve gebroekers.",
        "rightslog": "Gebroekersrechtelogbook",
        "action-read": "dees pagina te bekieke",
        "action-edit": "dees pagina te bewirke",
        "action-createpage": "pagina's aan te make",
-       "action-createtalk": "euverlèkpagina's aan te make",
+       "action-createtalk": "dees euverlèkpagina aan te make",
        "action-createaccount": "deze gebroeker aan te make",
+       "action-autocreateaccount": "dezen externe gebroek autematis aan te make",
+       "action-history": "de gesjiedenis van dees pagina te betrachte",
        "action-minoredit": "deze bewirking es klein te markere",
        "action-move": "deze pagina te verplaatse",
        "action-move-subpages": "dees pagina en biebehurende subpagina's te verplaatse",
        "action-move-rootuserpages": "gebroekerspagina's van 't hoegste niveau te verplaatse",
+       "action-move-categorypages": "categorieje te versjuve",
        "action-movefile": "dit bestandj te hernömme",
        "action-upload": "dit besjtandj te uploade",
        "action-reupload": "dit besjtaond besjtandj te euversjrieve",
        "action-upload_by_url": "dit besjtandj vanaaf 'ne URL te uploade",
        "action-writeapi": "via de API te bewirke",
        "action-delete": "dees pagina eweg te sjaffe",
-       "action-deleterevision": "dees versie eweg te sjaffe",
+       "action-deleterevision": "versies eweg te sjaffe",
        "action-deletelogentry": "logbeukregels eweg te sjaffe",
-       "action-deletedhistory": "de eweggesjafte versies van dees pagina te bekieke",
+       "action-deletedhistory": "de eweggesjafde versies van 'n pagina te bekieke",
+       "action-deletedtext": "de eweggesjafde versieteks te betrachte",
        "action-browsearchive": "eweggesjafte pagina's te zeuke",
        "action-undelete": "dees pagina trök te zètte",
        "action-suppressrevision": "dees verborge versie te betrachte en trök te plaatse",
        "recentchanges-legend": "Opties veur recènte verangeringe",
        "recentchanges-summary": "Volg de recènste bewirkinge op deze wiki op dees pagina.",
        "recentchanges-noresult": "Gein verangeringe in dees periood kómme euverein mit de criteria.",
+       "recentchanges-timeout": "Dees zeukopdrach kos te väöl tied. Doe kins 't oppernuuj perbere mit anger zeukparamaeters.",
+       "recentchanges-network": "Door 'n technische fout kinne gein rizzeltaote waere gelaje. Doe kins perbere de pagina te vernuje.",
+       "recentchanges-notargetpage": "Veur hiebaove 'ne paginanaam in veur verwantje verangeringe veur dees pagina te zeen.",
        "recentchanges-feed-description": "Volg de meis recente bewerkinge in deze wiki via deze feed.",
        "recentchanges-label-newpage": "Mit dees verangering is 'n nuuj pagina aangemaak",
        "recentchanges-label-minor": "Dit is 'n klein bewirking",
        "rcfilters-group-results-by-page": "Resultate per pagina groepere",
        "rcfilters-activefilters": "Aktief filters",
        "rcfilters-advancedfilters": "Geavanceerde filters",
-       "rcfilters-limit-title": "Te toeane verangeringe",
+       "rcfilters-limit-title": "Te toeane rizzeltaote",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|verangering|verangeringe}}, $2",
+       "rcfilters-date-popup-title": "Te doorzeuke tiedsfraem",
        "rcfilters-days-title": "Recènte daag",
        "rcfilters-hours-title": "Recènte oere",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|daag}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|oer}}",
        "rcfilters-highlighted-filters-list": "Oetgeleech: $1",
        "rcfilters-quickfilters": "Opgesjlage filters",
-       "rcfilters-quickfilters-placeholder-title": "Nag gein opgeslage links",
+       "rcfilters-quickfilters-placeholder-title": "Nag gein opgeslage filtjers",
        "rcfilters-savedqueries-defaultlabel": "Opgesjlage filters",
        "rcfilters-savedqueries-rename": "Herneum",
        "rcfilters-savedqueries-setdefault": "Stèl in es standerd",
        "rcfilters-highlightmenu-title": "Kees 'n kluuer",
        "rcfilters-highlightmenu-help": "Kees 'n kluuer veur dees eigesjappe oet te lichte",
        "rcfilters-filterlist-noresults": "Gein filters gevónje",
+       "rcfilters-filtergroup-authorship": "Sjriever van de biedraag",
+       "rcfilters-filter-editsbyself-label": "Verangeringe van dichzelf",
+       "rcfilters-filter-editsbyself-description": "Dien eige biedraag.",
+       "rcfilters-filter-editsbyother-label": "Verangeringe door angere",
+       "rcfilters-filter-editsbyother-description": "Alle verangere behauve die die det se zelf höbs gemaak.",
+       "rcfilters-filtergroup-userExpLevel": "Gebroekersregistrasie en -ervaring",
+       "rcfilters-filter-user-experience-level-registered-label": "Vasgelag",
+       "rcfilters-filter-user-experience-level-registered-description": "Aangemelde bewirkers.",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Neet-vasgelag",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Bewirkers die neet zeen aangemeld.",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Nujelinge",
        "rcfilters-filter-bots-label": "Bot",
        "rcfilters-filter-humans-label": "Minsjelik (geine bot)",
        "rcfilters-filter-watchlist-watched-label": "Op de volglies",
        "recentchangeslinked-feed": "Volg links",
        "recentchangeslinked-toolbox": "Volg links",
        "recentchangeslinked-title": "Verangeringe verwant mit \"$1\"",
-       "recentchangeslinked-summary": "Dees speciaal pagina tuint de lètste bewirkinge op pagina's die gelink waere vanaaf deze pagina. Pagina's die op [[Special:Watchlist|dien volglies]] staon waere '''vet''' weergegaeve.",
+       "recentchangeslinked-summary": "Veur 'n paginanaam in veur bewirkinge te zeen van pagina's wohaer vanaaf die pagina weurt verweze of die daohaer verwieze. (Veur lede van 'n categorie te zeen, veur den <kbd>Category:''Naam van categorie''</kbd> in.) Bewirkinge van pagina's op [[Special:Watchlist|dien volglies]] waere <strong>diek</strong> waergaove.",
        "recentchangeslinked-page": "Paginanaam:",
        "recentchangeslinked-to": "Verangeringe weergaeve nao de gelinkde pagina's",
        "recentchanges-page-added-to-category": "[[:$1]] aan categorie tougeveug gewaore",
        "feedback-subject": "Óngerwerp:",
        "feedback-submit": "Opsjlaon",
        "feedback-thanks": "Danke! Diene feedback is oppe pagina \"[$2 $1]\" geplaats.",
+       "feedback-thanks-title": "Danke!",
        "searchsuggest-search": "Doorzeuk {{SITENAME}}",
        "searchsuggest-containing": "bevat...",
        "api-error-badtoken": "Intern fout: toke is slech.",
index 0b7b526..61cdc9e 100644 (file)
        "expansion-depth-exceeded-category-desc": "A paggina a suppera a profonditæ mascima d'espanscion.",
        "expansion-depth-exceeded-warning": "Sta paggine a l'ha superòu a profonditæ d'espanscion",
        "parser-unstrip-loop-warning": "Rilevou ciclo de Unstrip",
-       "parser-unstrip-recursion-limit": "Superæ i limmiti de ricorscion de Unstrip ($1)",
+       "unstrip-depth-warning": "Superæ i limmiti de ricorscion de Unstrip ($1)",
        "converter-manual-rule-error": "Rilevou errô inta reggola manoâ de converscion da lengoa",
        "undo-success": "Questa modiffica a peu ese anullâ.\nControlla e differençe mostræ chì de sotta fra e doe verscioin pe ese seguo che-o contegnuo o corisponde a quante dexidiou, e quindi sarvâ e modiffiche pe completâ a proçedûa d'anullamento.",
        "undo-failure": "Imposcibbile anullâ a modiffica a caosa de un conflito con de modiffiche intermeddie.",
index 368a641..e2b0ded 100644 (file)
        "expansion-depth-exceeded-category-desc": "رده برای صفحاتی که در آنها از عمق گسترش فراتر رفته است.",
        "expansion-depth-exceeded-warning": "صفحه حداکثر عمق بسط دادن تجاوز کرد",
        "parser-unstrip-loop-warning": "حلقه در دستور unstrip پیدا شد",
-       "parser-unstrip-recursion-limit": "از حداکثر ارجاع در دستور unstrip تجاوز شد ($1)",
+       "unstrip-depth-warning": "از حداکثر ارجاع در دستور unstrip تجاوز شد ($1)",
        "converter-manual-rule-error": "خطا در قوانین مبدل دستی زبان",
        "undo-success": "این ویرایش را می‌توان خنثی کرد.\nلطفاً تفاوت زیر را بررسی کنید تا تأیید کنید که این چیزی است که می‌خواهید انجام دهید، سپس تغییرات زیر را ذخیره کنید تا خنثی‌سازی ویرایش را به پایان ببرید.",
        "undo-failure": "به علت تعارض با ویرایش‌های میانی، این ویرایش را نمی‌توان خنثی کرد.",
index c77099f..96aa274 100644 (file)
        "expansion-depth-exceeded-category-desc": "زیر دسه سی بلگه یایی که د ونو پی یا ووله بیین فره پئشکرد کرده.",
        "expansion-depth-exceeded-warning": "بلگه د پی یا ووله بیین پئشکرد کرد",
        "parser-unstrip-loop-warning": "گردوله د فرمونه Unstrip پیدا بیه",
-       "parser-unstrip-recursion-limit": "د بیشترونه د سرچشمه رئتن د دستور Unstrip واروتر رئتیته($1)",
+       "unstrip-depth-warning": "د بیشترونه د سرچشمه رئتن د دستور Unstrip واروتر رئتیته($1)",
        "converter-manual-rule-error": "خطا د قانون والرشتن دسی زون",
        "undo-success": "نبوئه ویرایشت نه انجومشیو بکیت.\nلطفا ای فرخی که ها د هار نه وارسی بکیت تا یه کاریه که میهات انجوم بئیت، و اوسه آلشتیا هار نه اماییه بکیت سی یه که خمثی کردن ویرایشت نه انجوم بئیت.",
        "undo-failure": "سی ری به ری بیئن ای ویرایشت وا ویرایشتیا مینجایی، نبوئه ای ویرایشت نه خومثی بکیت.",
index 38488e2..e0c77b3 100644 (file)
        "mar": "Kov",
        "apr": "Bal",
        "may": "Geg",
-       "jun": "Bir",
+       "jun": "Birž",
        "jul": "Lie",
        "aug": "Rgp",
        "sep": "Rgs",
        "userpage-userdoesnotexist": "Naudotojo paskyra „<nowiki>$1</nowiki>“ yra neužregistruota. Prašom patikrinti, ar jūs norite kurti/redaguoti šį puslapį.",
        "userpage-userdoesnotexist-view": "Naudotojo paskyra „$1“ neužregistruota.",
        "blocked-notice-logextract": "Šis naudotojas šiuo metu yra užblokuotas.\nŽemiau pateikiamas paskutinis blokavimo istorijos įrašas:",
-       "clearyourcache": "'''Dėmesio:''' Išsaugojus jums gali prireikti išvalyti jūsų naršyklės podėlį, kad pamatytumėte pokyčius.\n* '''Firefox / Safari:''' laikydami ''Shift'' pasirinkite ''Atsiųsti iš naujo'', arba paspauskite ''Ctrl-F5'' ar ''Ctrl-R'' (sistemoje Apple Mac ''Commandd-R'')\n* '''Google Chrome:''' spauskite ''Ctrl-Shift-R'' (sistemoje Apple Mac ''Command-Shift-R'')\n* '''Internet Explorer:''' laikydami ''Ctrl'' paspauskite ''Atnaujinti'', arba paspauskite ''Ctrl-F5''\n* '''Konqueror:''' tiesiog paspauskite ''Perkrauti'' mygtuką, arba paspauskite ''F5''\n* '''Opera''' pilnai išvalykite podėlį ''Priemonės→Nuostatos''.",
+       "clearyourcache": "<strong>Dėmesio:</strong> Išsaugojus jums gali prireikti išvalyti jūsų naršyklės podėlį, kad pamatytumėte pokyčius.\n* <strong>Firefox / Safari:</strong> Laikydami <em>Shift</em> pasirinkite <em>Perkrauti</em>, arba paspauskite <em>Ctrl-F5</em> ar <em>Ctrl-R</em> (sistemoje Apple Mac <em>⌘-R</em>)\n* <strong>Google Chrome:</strong> Spauskite <em>Ctrl-Shift-R</em> (sistemoje Apple Mac <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> Laikydami <em>Ctrl</em> paspauskite <em>Naujinti</em>, arba paspauskite <em>Ctrl-F5</em>\n* <strong>Opera:</strong> Eikite į <em>Meniu → Nuostatos</em> (sistemoje Apple Mac <em>Opera → Nustatymai</em>), tuomet <em>Privatumas ir sauga → išvalyti naršymo podėlį → išsaugotos talpyklos vaizdai ir failai</em>.",
        "usercssyoucanpreview": "'''Patarimas:''' Naudokite „{{int:showpreview}}“ mygtuką, kad išmėgintumėte savo naująjį CSS prieš išsaugant.",
        "userjsyoucanpreview": "'''Patarimas:''' Naudokite „{{int:showpreview}}“ mygtuką, kad išmėgintumėte savo naująjį JS prieš išsaugant.",
        "usercsspreview": "'''Nepamirškite, kad jūs tik peržiūrit savo naudotojo CSS, jis dar nebuvo išsaugotas!'''",
        "expansion-depth-exceeded-category-desc": "Puslapis viršija didžiausią plėtros gylį.",
        "expansion-depth-exceeded-warning": "Puslapis, viršijantis didžiausią plėtros gylį",
        "parser-unstrip-loop-warning": "Rastas neuždarytas ciklas",
-       "parser-unstrip-recursion-limit": "Unstrip rekursijos limitas viršytas ($1)",
+       "unstrip-depth-warning": "Unstrip rekursijos limitas viršytas ($1)",
        "converter-manual-rule-error": "Rankinėje kalbos pertvarkymo taisyklėje rasta klaida",
        "undo-success": "Keitimas gali būti atšauktas. Prašome patikrinti palyginimą, esantį žemiau, kad patvirtintumėte, kad jūs tai ir norite padaryti, ir tada išsaugokite pakeitimus, esančius žemiau, kad užbaigtumėte keitimo atšaukimą.",
        "undo-failure": "Keitimas negali būti atšauktas dėl konfliktuojančių tarpinių keitimų.",
        "searchall": "visi",
        "showingresults": "Žemiau rodoma iki '''$1''' {{PLURAL:$1|rezultato|rezultatų|rezultatų}} pradedant #'''$2'''.",
        "showingresultsinrange": "Žemiau rodoma iki {{PLURAL:$1|<strong>1</strong> gavinio|<strong>$1</strong> gavinių}} imtyje nuo <strong>$2</strong> iki <strong>$3</strong>.",
-       "search-showingresults": "{{PLURAL:$4|Davinys <strong>$1</strong> iš <strong>$3</strong>|Daviniai <strong>$1 - $2</strong> iš <strong>$3</strong>}}",
+       "search-showingresults": "{{PLURAL:$4|Rezultatas <strong>$1</strong> iš <strong>$3</strong>|Rezultatai <strong>$1 - $2</strong> iš <strong>$3</strong>}}",
        "search-nonefound": "Nėra rezultatų, atitinkančių užklausą.",
        "search-nonefound-thiswiki": "Nėra rezultatų atitinkančių užklausą šiame tinklapyje.",
        "powersearch-legend": "Išplėstinė paieška",
        "recentchangeslinked-feed": "Susiję keitimai",
        "recentchangeslinked-toolbox": "Susiję keitimai",
        "recentchangeslinked-title": "Su „$1“ susiję keitimai",
-       "recentchangeslinked-summary": "Įveskite puslapio pavadinimą, jei norite žiūrėti keitimus, atliktus puslapiuose, į kuriuos yra nuoroda į arba iš nurodyto puslapio. (Jei norite žiūrėti nurodytos kategorijos narius, įveskite Kategorija:Kategorijos pavadinimas). Puslapiai iš jūsų [[Special:Watchlist|stebimųjų sąrašo]] yra <strong>paryškinti</strong>.",
+       "recentchangeslinked-summary": "Įveskite puslapio pavadinimą, jei norite matyti keitimus, atliktus puslapiuose, į kuriuos yra nuoroda į arba iš nurodyto puslapio. (Jei norite ieškoti nurodytos kategorijos narius, įveskite Kategorija:Kategorijos pavadinimas). Puslapiai iš jūsų [[Special:Watchlist|stebimųjų sąrašo]] yra <strong>paryškinti</strong>.",
        "recentchangeslinked-page": "Puslapio pavadinimas:",
        "recentchangeslinked-to": "Rodyti su duotuoju puslapiu susijusių puslapių pakeitimus",
        "recentchanges-page-added-to-category": "[[:$1]] pridėta prie kategorijos",
index f56d350..4b94f2e 100644 (file)
        "timezoneregion-indian": "Indijas okeāns",
        "timezoneregion-pacific": "Klusais okeāns",
        "allowemail": "Atļaut citiem dalībniekiem sūtīt man e-pastus",
+       "email-allow-new-users-label": "Atļaut e-pastus no ļoti jauniem dalībniekiem",
        "email-blacklist-label": "Aizliegt šiem dalībniekiem man sūtīt e-pastus:",
        "prefs-searchoptions": "Meklēšana",
        "prefs-namespaces": "Vārdtelpas",
index 8cc626b..b66f1a0 100644 (file)
        "expansion-depth-exceeded-category-desc": "ई पृष्ठ अधिकतम रुपमे विस्तार गहिराई पार केनए अछि",
        "expansion-depth-exceeded-warning": "पन्ना विस्तार गहिराई पार केनए अछि",
        "parser-unstrip-loop-warning": "Unstrip लूप पाओल गेल",
-       "parser-unstrip-recursion-limit": "Unstrip पुनरावर्तन सीमा पार कइर गेल($1)",
+       "unstrip-depth-warning": "Unstrip पुनरावर्तन सीमा पार कइर गेल($1)",
        "converter-manual-rule-error": "म्यानुअल भाषा परिवर्तन नियममे त्रुटि",
        "undo-success": "ई सम्पादन पूर्ववत बदलल जा सकैए।\nकृपा क' नीचाँक तुलनाक जाँच करू ई देखैले जे ई वएह भेल अछि जे अहाँ चाहै छलहुँ, आ तखन सम्पादन ख़तम करबा लेल नीचाँक परिवर्तन सुरक्षित करू ।",
        "undo-failure": "मध्यवर्ती विरोधी सम्पादनक कारण ऐ सम्पादनकेँ खतम नै कएल जा सकैए।",
index f626f0c..0e92f0c 100644 (file)
        "expansion-depth-exceeded-category-desc": "Sokajy ho an'ny pejy ahitana halalim-piitarana mihoatra.",
        "expansion-depth-exceeded-warning": "Pejy manana halalim-panitarana mihoatra",
        "parser-unstrip-loop-warning": "Nahitana tondro mifolaka tsy azo vahana",
-       "parser-unstrip-recursion-limit": "Tafahoatra ny fetra avo ny fetra recursion ($1)",
+       "unstrip-depth-warning": "Tafahoatra ny fetra avo ny fetra recursion ($1)",
        "converter-manual-rule-error": "Nahitana hadisoana ao amin'ny fepetra famadihana tanana ny fiteny.",
        "undo-success": "Ho voafafa io fanovana io. Marino tsara ny fanovana eo ambany, ary tehirizo rehefa vita.",
        "undo-failure": "Tsy afaka esorina io fanovàna io : mety tsy miraikitra amin'ny fanovàna misy eo ampivoaniny ra esorina",
index d525160..ba766d6 100644 (file)
        "expansion-depth-exceeded-category": "Laman dima kadalaman ekspansi lah talampau",
        "expansion-depth-exceeded-warning": "Laman kadalaman ekspansi lah talampau",
        "parser-unstrip-loop-warning": "Unstrip loop detected",
-       "parser-unstrip-recursion-limit": "Unstrip recursion limit exceeded ($1)",
+       "unstrip-depth-warning": "Unstrip recursion limit exceeded ($1)",
        "converter-manual-rule-error": "Kasalahan tadeteksi di aturan manual konversi bahaso",
        "undo-success": "Suntiangan ko dapek dibatalan. \nTolong cek pabedoan di bawah untuak mayakinkan bahwa bana nan tu Sanak nio buek, lalu simpan parubahan tasabuik untuak manyalasaikan pambatalan suntiangan.",
        "undo-failure": "Suntiangan ko indak dapek dibatalan dek konflik panyuntiangan antaro.",
index a1f615a..18f0925 100644 (file)
        "expansion-depth-exceeded-category-desc": "Страницата ја надминува најголемата дозволена продорност на проширувањето.",
        "expansion-depth-exceeded-warning": "Страницата ја надмина длабочината на проширувањето",
        "parser-unstrip-loop-warning": "Утврдена е јамка",
-       "parser-unstrip-recursion-limit": "Пречекорена е границата на рекурзија ($1)",
+       "unstrip-depth-warning": "Пречекорена е границата на рекурзија ($1)",
        "converter-manual-rule-error": "Пронајдов грешка во правилото за рачно претворање на јазик",
        "undo-success": "Уредувањето може да се откаже.\nВе молиме споредете ги промените со претходната верзија за да проверите дали тоа е сигурно она што сакате да го направите, а потоа зачувајте ги промените за да го завршите откажувањето на претходното уредување.",
        "undo-failure": "Уредувањето не можеше да се откаже заради меѓувремени спротиставени уредувања.",
index 1706d9d..a3fcbec 100644 (file)
        "expansion-depth-exceeded-category-desc": "താളിലെ വികസന ആഴം അധികരിച്ചിരിക്കുന്നു.",
        "expansion-depth-exceeded-warning": "താളിന്റെ വികസന ആഴം അധികരിച്ചിരിക്കുന്നു",
        "parser-unstrip-loop-warning": "അൺസ്ട്രിപ്പ് (Unstrip) പാഴ്സർ ഫങ്ഷനിൽ കുരുക്ക് കണ്ടെത്തി",
-       "parser-unstrip-recursion-limit": "അൺസ്ട്രിപ്പ് (Unstrip) പാഴ്സർ ഫങ്ഷന്റെ പുനരാവർത്തന പരിധി അധികരിച്ചിരിക്കുന്നു ($1)",
+       "unstrip-depth-warning": "അൺസ്ട്രിപ്പ് (Unstrip) പാഴ്സർ ഫങ്ഷന്റെ പുനരാവർത്തന പരിധി അധികരിച്ചിരിക്കുന്നു ($1)",
        "converter-manual-rule-error": "മാനുഷികമായുള്ള ഭാഷാ പരിവർത്തന നിയമത്തിൽ പിഴവ് കണ്ടെത്തി",
        "undo-success": "ഈ തിരുത്ത് താങ്കൾക്ക് തിരസ്ക്കരിക്കാവുന്നതാണ്‌. താഴെ കൊടുത്തിരിക്കുന്ന പതിപ്പുകൾ തമ്മിലുള്ള താരതമ്യം ഒന്നുകൂടി പരിശോധിച്ച് ഈ പ്രവൃത്തി ചെയ്യണോ എന്ന് ഒന്നുകൂടി ഉറപ്പാക്കുക. ഉറപ്പാണെങ്കിൽ തിരുത്ത് തിരസ്ക്കരിക്കുവാൻ താൾ സേവ് ചെയ്യുക.",
        "undo-failure": "ഇടയ്ക്കുള്ള തിരുത്തുകൾ തമ്മിൽ സമരസപ്പെടാത്തതു കാരണം ഈ തിരുത്ത് തിരസ്ക്കരിക്കുവാനാവില്ല.",
        "prefs-editor": "എഡിറ്റർ",
        "prefs-preview": "എങ്ങനെയുണ്ടെന്ന് കാണൽ",
        "prefs-advancedrc": "വിപുലമായ ഉപാധികൾ",
+       "prefs-opt-out": "പുതുക്കലുകൾ ഒഴിവാക്കുക",
        "prefs-advancedrendering": "വിപുലമായ ഉപാധികൾ",
        "prefs-advancedsearchoptions": "വിപുലമായ ഉപാധികൾ",
        "prefs-advancedwatchlist": "വിപുലമായ ഉപാധികൾ",
        "rcfilters-watchlist-markseen-button": "എല്ലാ മാറ്റങ്ങളും കണ്ടതായി അടയാളപ്പെടുത്തുക",
        "rcfilters-watchlist-edit-watchlist-button": "താങ്കൾ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടിക തിരുത്തുക",
        "rcfilters-watchlist-showupdated": "മാറ്റങ്ങൾ ഉണ്ടായ ശേഷം താങ്കൾ സന്ദർശിക്കാത്ത താളുകളിലെ മാറ്റങ്ങൾ, തളിക അടയാളത്തോടൊപ്പം <strong>കടുപ്പിച്ച്</strong> കാണിച്ചിരിക്കുന്നു.",
+       "rcfilters-preference-label": "സമീപകാലമാറ്റങ്ങളുടെ പുതുക്കിയ പതിപ്പ് പ്രദർശിപ്പിക്കേണ്ട",
+       "rcfilters-preference-help": "സമ്പർക്കമുഖത്തിൽ 2017 വരുത്തിയ രൂപകല്പനാമാറ്റങ്ങളും അതോടൊപ്പവും പിന്നീടും ചേർത്ത എല്ലാ ഉപകരണങ്ങളും ഒഴിവാക്കുക.",
+       "rcfilters-filter-showlinkedfrom-label": "കണ്ണി ചേർക്കപ്പെട്ട താളുകളിലെ മാറ്റങ്ങൾ കാണിക്കുക",
+       "rcfilters-filter-showlinkedfrom-option-label": "തിരഞ്ഞെടുത്ത താളിൽ <strong>കണ്ണി ചേർക്കപ്പെട്ട താളുകൾ</strong>",
        "rcnotefrom": "<strong>$3, $4</strong> മുതലുള്ള {{PLURAL:$5|മാറ്റം|മാറ്റങ്ങൾ}} ആണ് താഴെയുള്ളത്  (<strong>$1</strong> എണ്ണം വരെ കൊടുക്കുന്നതാണ്).",
        "rclistfromreset": "തീയതി എടുത്തത് പുനഃസജ്ജീകരിക്കുക",
        "rclistfrom": "$3 $2 മുതലുള്ള മാറ്റങ്ങൾ പ്രദർശിപ്പിക്കുക",
index a816be1..6e8d930 100644 (file)
@@ -51,7 +51,8 @@
                        "Suyog",
                        "Matma Rex",
                        "Tiven2240",
-                       "Sureshkhole"
+                       "Sureshkhole",
+                       "Pushkar Ekbote"
                ]
        },
        "tog-underline": "दुव्यांचे अधोरेखन:",
        "may": "मे",
        "jun": "जून",
        "jul": "जुलै",
-       "aug": "ऑग.",
-       "sep": "सप्टें.",
-       "oct": "ऑक्टो.",
-       "nov": "नोव्हें.",
-       "dec": "डिसें.",
+       "aug": "ऑगस्ट",
+       "sep": "सप्टेंबर",
+       "oct": "ऑक्टोबर",
+       "nov": "नोव्हेंबर",
+       "dec": "डिसेंबर",
        "january-date": "जानेवारी $1",
        "february-date": "फेब्रुवारी $1",
        "march-date": "मार्च $1",
        "copyright": "येथील मजकूर $1च्या अंतर्गत उपलब्ध आहे जोपर्यंत इतर नोंदी केलेल्या नाहीत.",
        "copyrightpage": "{{ns:project}}:प्रताधिकार",
        "currentevents": "सद्य घटना",
-       "currentevents-url": "Project:सद्य घटना",
+       "currentevents-url": "प्रकल्प:सद्य घटना",
        "disclaimers": "उत्तरदायित्वास नकार",
-       "disclaimerpage": "Project: सर्वसाधारण उत्तरदायकत्वास नकार",
+       "disclaimerpage": "प्रकल्प : सर्वसाधारण उत्तरदायकत्वास नकार",
        "edithelp": "संपादन साहाय्य",
        "helppage-top-gethelp": "साहाय्य",
        "mainpage": "मुखपृष्ठ",
        "mainpage-description": "मुखपृष्ठ",
        "policy-url": "Project:नीती",
        "portal": "समाज मुखपृष्ठ",
-       "portal-url": "Project:समाज मुखपृष्ठ",
+       "portal-url": "प्रकल्प:समाज मुखपृष्ठ",
        "privacy": "गुप्तता नीती",
-       "privacypage": "Project:गुप्तता नीती",
+       "privacypage": "प्रकल्प:गुप्तता नीती",
        "badaccess": "परवानगी त्रुटी",
        "badaccess-group0": "आपण विनंती केलेल्या क्रियेच्या पूर्ततेचे तुम्हाला अधिकार नाहीत.",
        "badaccess-groups": "आपण विनीत केलेली कृती खालील {{PLURAL:$2|समूहासाठी|पैकी एका समूहासाठी}} मर्यादित आहे: $1.",
        "hidetoc": "लपवा",
        "collapsible-collapse": "निपात करा",
        "collapsible-expand": "विस्तार",
-       "confirmable-confirm": "{{GENDER:$1|आपणास}}खात्री आहे काय?",
+       "confirmable-confirm": "{{लिंगभाव:$1|आपणास}}खात्री आहे काय?",
        "confirmable-yes": "होय",
        "confirmable-no": "नाही",
        "thisisdeleted": "$1चे अवलोकन किंवा पुनर्स्थापन करायचे ?",
        "viewdeleted": " $1चे अवलोकन करायचे?",
        "restorelink": "{{PLURAL:$1|एक वगळलेले संपादन|$1 वगळलेली संपादने}}",
        "feedlinks": "रसद (फिड) :",
-       "feed-invalid": "à¤\85यà¥\8bà¤\97à¥\8dय à¤°à¤¸à¤¦ à¤¨à¥\8bà¤\82दणà¥\80 (Invalid subscription feed type).",
+       "feed-invalid": "à¤\85यà¥\8bà¤\97à¥\8dय à¤¨à¥\8bà¤\82दणà¥\80 à¤ªà¥\8dरà¤\95ार",
        "feed-unavailable": "सिंडीकेशन रसद उपलब्ध नाहीत",
        "site-rss-feed": "$1 आरएसएस रसद",
        "site-atom-feed": "$1 अॅटम रसद (Atom Feed)",
        "expansion-depth-exceeded-category-desc": "या पानाने उच्चतम प्रसरण-खोली(expansion depth) मर्यादा पार केली.",
        "expansion-depth-exceeded-warning": "लेखाने विस्तार-तळ(एक्सपांशन डेप्थ) पार केला",
        "parser-unstrip-loop-warning": "'अनस्ट्रिप'(अरोखीत) वलय(लुप) आढळले",
-       "parser-unstrip-recursion-limit": "'अनस्ट्रिप'(अरोखीत) आवर्तन मर्यादा पार झाली ($1)",
+       "unstrip-depth-warning": "'अनस्ट्रिप'(अरोखीत) आवर्तन मर्यादा पार झाली ($1)",
        "converter-manual-rule-error": "निदेशपुस्तिकेच्या भाषा अनुरुपण नियमामध्ये त्रुटी आढळली",
        "undo-success": "संपादन परतवले जाऊ शकते.कृपया, आपण नेमके हेच करू इच्छिता तर ते खाली दिलेली तुलना पाहू निश्चित करा,आणि नंतर संपादन परतवण्याचे काम पूर्ण करण्याकरिता इच्छित बदल जतन करा.",
        "undo-failure": "विसंवादी आंतरवर्ती संपादने झाल्यामुळे आपण हे संपादन परतवू शकत नाही.",
index 334e350..cff3601 100644 (file)
        "expansion-depth-exceeded-category-desc": "Laman telah melebihi kedalaman peluasan maksimum.",
        "expansion-depth-exceeded-warning": "Laman terlebih dalam peluasan",
        "parser-unstrip-loop-warning": "Gelung unstrip dikesan",
-       "parser-unstrip-recursion-limit": "Had rekursi unstrip dilampaui ($1)",
+       "unstrip-depth-warning": "Had rekursi unstrip dilampaui ($1)",
        "converter-manual-rule-error": "Ralat dikesan dalam aturan penukaran bahasa manual",
        "undo-success": "Suntingan ini boleh dibatalkan. Sila semak perbandingan di bawah untuk mengesahkan bahawa anda betul-betul mahu melakukan tindakan ini, kemudian simpan perubahan tersebut.",
        "undo-failure": "Suntingan tersebut tidak boleh dibatalkan kerana terdapat suntingan pertengahan yang bercanggah.",
index d7050d8..516b4fc 100644 (file)
        "category-file-count-limited": "Nesta catadorie hai {{PLURAL:$1|un fexeiro|$1 fexeiros}}.",
        "listingcontinuesabbrev": "cunt.",
        "index-category": "Páiginas ourganizadas an índece",
-       "noindex-category": "Páiginas nun ourganizadas an índece",
+       "noindex-category": "Páiginas nó ourganizadas an índece",
        "broken-file-category": "Páiginas cun lhigaçones scachadas pa fexeiros",
        "about": "Subre",
        "article": "Páigina de cuntenido",
index 00975fd..5d05688 100644 (file)
        "expansion-depth-exceeded-category-desc": "Sta paggena appassa 'o lemmeto d'espansione.",
        "expansion-depth-exceeded-warning": "Sta paggena ha appassato 'o lemmeto 'e futo 'e spansione",
        "parser-unstrip-loop-warning": "Scummigliato aniello Unstrip",
-       "parser-unstrip-recursion-limit": "Appassato 'o lémmeto 'e ricurzione d' Unstrip ($1)",
+       "unstrip-depth-warning": "Appassato 'o lémmeto 'e ricurzione d' Unstrip ($1)",
        "converter-manual-rule-error": "È stato scummigliato n'errore dint'a regola manuale 'e converziona 'e lengua",
        "undo-success": "'O cagnamiento se può annullà.\nPe' piacere vedete 'e differenze mmustate nfra 'e verziune pe' te ffà capace ca 'e cuntenute songo bbuone, e astipate 'e cagnamiente ccà abbascio pe' fernì e accussì turnà arreto.",
        "undo-failure": "Nun se può fà turnà arreto 'o cagnamiento pecché ce sta nu conflitto ch' 'e cagnamiente intermedie.",
index fe826a2..9a00b9c 100644 (file)
        "expansion-depth-exceeded-category-desc": "Siden overskrider maksimal utvidingsdybde.",
        "expansion-depth-exceeded-warning": "Sida har overskredet ekspansjonsdybden",
        "parser-unstrip-loop-warning": "«Unstrip»-loop påvist",
-       "parser-unstrip-recursion-limit": "Rekursjonsgrense for taggfjerning overskredet ($1)",
+       "unstrip-depth-warning": "Rekursjonsgrense for taggfjerning overskredet ($1)",
        "converter-manual-rule-error": "En feil ble oppdaget i en manuell språkkonverteringsregel",
        "undo-success": "Redigeringen kan omgjøres. Sjekk sammenligningen under for å bekrefte at du vil gjøre dette, og lagre endringene for å fullføre omgjøringen.",
        "undo-failure": "Redigeringen kunne ikke omgjøres på grunn av konflikterende etterfølgende redigeringer.",
index c900dbc..2e4bc59 100644 (file)
        "expansion-depth-exceeded-category": "Ziejen waor de expansiediepte overschrejen is",
        "expansion-depth-exceeded-warning": "Op disse zied staon te veule mallen",
        "parser-unstrip-loop-warning": "Der is n \"unstrip\"-lusse evunnen",
-       "parser-unstrip-recursion-limit": "De rekursielimiet ($1) veur \"unstrip\" is overschrejen",
+       "unstrip-depth-warning": "De rekursielimiet ($1) veur \"unstrip\" is overschrejen",
        "converter-manual-rule-error": "Der is n fout evunnen in n haandmaotig in-evoegden taalkonversieregel.",
        "undo-success": "De bewarking kan weerummedreid wörden. Kiek de vergelieking hieronder nao um der wisse van de ween dat alles goed is, en slao de de zied op um de bewarking weerumme te dreien.",
        "undo-failure": "De wieziging kon niet weerummedreid wörden umdat t ondertussen awweer ewiezigd is.",
index cc780da..6d833e0 100644 (file)
        "expansion-depth-exceeded-category-desc": "यस पृष्ठले उच्चतम विस्तार सिमा नाघेको छ ।",
        "expansion-depth-exceeded-warning": "पृष्ठले विस्तार सिमालाई नाधेको छ",
        "parser-unstrip-loop-warning": "अनस्ट्रिप लुप देखिन्छ",
-       "parser-unstrip-recursion-limit": "अन्स्ट्रिप पुनरावर्तन सिमा पार गरियो ($1)",
+       "unstrip-depth-warning": "अन्स्ट्रिप पुनरावर्तन सिमा पार गरियो ($1)",
        "converter-manual-rule-error": "म्यानुअल भाषा अनुवाद सिध्दान्तमा समस्या देखियो",
        "undo-success": "सम्पादन उल्टाउन सकिन्छ।\nतपाईंले चाहेको कार्य गर्न कृपया तल दिएको तुलना जाँच गर्नुहोस्, र गरिएको सम्पादनलाई  अघिकै अवस्थामा लैजाने कार्य सम्पन्न गर्न तल गएर संग्रह  गर्नुहोस्।",
        "undo-failure": "सम्पादनमा अन्तर्द्वन्द्वको कारण सम्पादन रद्द गर्न सकिन्न।",
        "editusergroup": "प्रयोगकर्ता समूह सम्पादन गर्नुहोस्",
        "editinguser": "प्रयोगकर्ता '''[[User:$1|$1]]''' $2 को अधिकार परिवर्तन गर्ने\n{{GENDER:$1|प्रयोगकर्ता}}को प्रयोगकर्ता अधिकार परिवर्तन हुँदैछ <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "प्रयोगकर्ता समूह सम्पादन गर्नुहोस्",
+       "userrights-viewusergroup": "{{GENDER:$1|प्रयोगकर्ता}} समूहहरू हेर्नुहोस्।",
        "saveusergroups": "प्रयोगकर्ता समूहरू संग्रह गर्नुहोस्",
        "userrights-groupsmember": "को सदस्य:",
        "userrights-groupsmember-auto": "अंतर्निहित सदस्य:",
        "grant-createeditmovepage": "पृष्ठहरूमा परिवर्तन गर्नुहोस्",
        "grant-editmycssjs": "तपाईंको प्रयोगकर्ता CSS/JavaScript सम्पादन गर्नुहोस्",
        "grant-editmyoptions": "तपाईंको प्रयोगकर्ता अभिरूचीहरूलाई सम्पादन गर्नुहोस्",
+       "grant-sendemail": "अन्य प्रयोगकर्ताहरूलाई इमेल पठाउने",
        "grant-viewdeleted": "मेटाइएका फाइल तथा पृष्ठहरू हेर्ने",
        "newuserlogpage": "प्रयोगकर्ता श्रृजना लग",
        "newuserlogpagetext": "यो प्रयोगकर्ता सिर्जनाको लग हो ।",
        "recentchanges-legend-plusminus": "(''±१२३'')",
        "recentchanges-submit": "देखाउनुहोस्",
        "rcfilters-tag-remove": "'$1' हटाउनुहोस्",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|दिन|दिनहरू}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|घण्टा|घण्टाहरू}}",
+       "rcfilters-savedqueries-setdefault": "पूर्वनिर्धारितको रुपमा सेट गर्नुहोस्",
+       "rcfilters-savedqueries-remove": "हटाउनुहोस्",
+       "rcfilters-savedqueries-new-name-label": "नाम",
+       "rcfilters-savedqueries-cancel-label": "रद्द गर्नुहोस्",
        "rcfilters-show-new-changes": "नवीनतम परिवर्तनहरू हेर्नुहोस्",
+       "rcfilters-filterlist-title": "फिल्टरहरू",
+       "rcfilters-filter-bots-label": "बोट",
+       "rcfilters-filter-minor-label": "सामान्य सम्पादनहरू",
        "rcfilters-filter-watchlistactivity-unseen-label": "नहेरिएका परिवर्तनहरू",
        "rcfilters-filter-watchlistactivity-seen-label": "हेरिएका परिवर्तनहरू",
+       "rcfilters-filter-lastrevision-label": "हालको संस्करण",
        "rcnotefrom": "तल <strong>$2</strong> देखि (<strong>$1</strong> सम्म) {{PLURAL:$5|भएका परिवर्तनहरू देखाइएको छ|भएका परिवर्तनहरू देखाइन्छ}}।",
        "rclistfrom": "$3 $2 देखिका नयाँ परिवर्तनहरू देखाउनु",
        "rcshowhideminor": "$1 सामान्य सम्पादन",
        "watchthisupload": "यो पृष्ठ निगरानी गर्नुहोस्",
        "filewasdeleted": "यस नामको एक फाइल पहिले पनि अपलोड गरे पछि हटाई सकिएको छ।\nपुनः अपलोड गर्नु पूर्व तपाईं $1 लाई राम्रोसँग जाँच गर्नुहोला।",
        "filename-bad-prefix": "तपाईं जुन फाइल अपलोड गर्दै हुनुहुन्छ त्यसको नाम <strong>\"$1\"</strong>बाट शुरू हुन्छ, जुन डिजिटल क्यामराद्वारा दिइएको नाम हो।\nकृपया यस फाइलको लागि कुनै दोश्रो अधिक जानकारीयुक्त नाम छान्नुहोस्।",
+       "filename-prefix-blacklist": " #<!-- leave this line exactly as it is --> <pre>\n# Syntax is as follows:\n#   * Everything from a \"#\" character to the end of the line is a comment\n#   * Every non-blank line is a prefix for typical filenames assigned automatically by digital cameras\nCIMG # Casio\nDSC_ # Nikon\nDSCF # Fuji\nDSCN # Nikon\nDUW # some mobile phones\nIMG # generic\nJD # Jenoptik\nMGP # Pentax\nPICT # misc.\n #</pre> <!-- leave this line exactly as it is -->",
        "upload-proto-error": "दूषित प्रोटोकल",
        "upload-proto-error-text": "दुर उर्ध्वभरण ठेगाना URLs  <code>http://</code> or <code>ftp://</code> बाट सुरु भएको हुनु पर्छ ।",
        "upload-file-error": "आन्तरिक त्रुटि",
        "upload-copy-upload-invalid-domain": "यस डोमेनबाट अपलोडहरूको प्रतिलिपि गर्न सकिदैन् ।",
        "upload-dialog-title": "फाइल अपलोड गर्ने",
        "upload-dialog-button-cancel": "रद्द गर्ने",
+       "upload-dialog-button-back": "पछाडि",
        "upload-dialog-button-done": "सकियो",
        "upload-dialog-button-save": "सङ्ग्रह गर्ने",
        "upload-dialog-button-upload": "अपलोड गर्ने",
        "apihelp-no-such-module": "मोड्युल \"$1\" भेटिएन ।",
        "apisandbox-submit": "अनुरोध गर्ने",
        "apisandbox-reset": "हटाउने",
+       "apisandbox-retry": "पुनः प्रयास गर्नुहोस्",
        "apisandbox-examples": "उदाहरण",
        "apisandbox-results": "परिणाम",
        "apisandbox-request-url-label": "अनुरोध युआरयल:",
        "apisandbox-request-time": "अनुरोधको समयावधी: $1",
+       "apisandbox-continue-clear": "खाली गर्नुहोस्",
        "booksources": "किताबका श्रोतहरु",
        "booksources-search-legend": "किताबका श्रोतहरु खोज्ने",
        "booksources-search": "खोज",
        "listgrouprights-namespaceprotection-header": "नामपद रोक",
        "listgrouprights-namespaceprotection-namespace": "नामपद",
        "listgrouprights-namespaceprotection-restrictedto": "प्रयोगकर्तालाई सम्पादन गर्ने अधिकार(हरू) दिने",
+       "listgrants-rights": "अधिकारहरू",
        "trackingcategories": "श्रेणीहरू पछ्याउने",
        "trackingcategories-summary": "यस पृष्ठमा ती जोडिने श्रेणिहरूको सूची भेट्दछ जुन स्वतः रूपले मिडियाविकी सफ्टवेयरद्वारा बनाइने गरिन्छ। उनीहरूको नाम सम्बन्धित प्रणाली सन्देशलाई परिवर्तनले {{ns:8}} नामस्थानमा परिवर्तन गर्न सकिन्छ।",
        "trackingcategories-msg": "श्रेणी पछ्याउने",
        "enotif_lastdiff": "यस परिवर्तनको निम्ति यो $1 हेर्नुहोस्",
        "enotif_anon_editor": "अज्ञात  प्रयोगकर्ता  $1",
        "enotif_body": "प्रिय $WATCHINGUSERNAME,\n\n\n{{SITENAME}}को पृष्ठ $PAGETITLE  $PAGEEDITDATE को दिन $PAGEEDITORद्वारा $CHANGEDORCREATED, \nहालको संशोधनको निम्ति हेर्नुहोस्  $PAGETITLE_URL ।\n\n$NEWPAGE\n\nसम्पादकको सारांश: $PAGESUMMARY $PAGEMINOREDIT\n\nसम्पादकसित सम्पर्क राख्नुहोस्:\nमेल: $PAGEEDITOR_EMAIL\nविकि: $PAGEEDITOR_WIKI\n\nतपाईं यस पृष्ठमा नगएसम्म अब उसो कुनै परिवर्तन भएका खण्डमा कुनै सूचना दिनेछैन।\nतपाईंका सम्पूर्ण निगरानी पृष्ठहरूको लागि तपाईंले सूचना पताकालाई निगरानी सूचीमा पुनर्बहाली गर्न सक्नुहुन्छ। \n\n             तपाईंको मित्र {{SITENAME}} सूचना प्रणाली\n--\nइमेल सूचना व्यवस्था परिवर्तन गर्न, जानुहोस्\n{{canonicalurl:{{#special:Preferences}}}}\n\nनिगरानी सूची व्यवस्थित गर्न, जानुहोस्\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nनिगरानी सूची मेट्न, जानुहोस्\n$UNWATCHURL\n\nप्रतिक्रिया र अन्य सहयोगको निम्ति:\n$HELPPAGE",
+       "enotif_minoredit": "यो सानो सम्पादन हो",
        "created": "बनाइएको",
        "changed": "परिवर्तन भइसकेको",
        "deletepage": "पृष्ठ मेट्नुहोस्",
        "sessionfailure": "यस्तो लाग्दैछ कि तपाईंको लगइन सत्रसँग कुनै समस्या छ। सत्र अपहरणबाट बचाउन को लागि सावधानीको रूपमा तपाईंको यो क्रियाकलाप रद्द गरिएको छ। कृपया पछाडी जानुहोस र पृष्ठलाई पुनः लोड गर्नुहोस्, अनि फेरी प्रयास गर्नुहोला।",
        "changecontentmodel-title-label": "पाना शीर्षक",
        "changecontentmodel-reason-label": "कारण:",
+       "changecontentmodel-submit": "परिवर्तन गर्नुहोस्",
        "logentry-contentmodel-change-revertlink": "पहिलेको रुपमा फर्काउने",
        "logentry-contentmodel-change-revert": "पहिलेको रुपमा फर्काउने",
        "protectlogpage": "सुरक्षण लग",
        "undelete-search-title": "मेटिएका पृष्ठहरू खोज्नुहोस्",
        "undelete-search-box": "मेटिएका पृष्ठहरू खोज्नुहोस्",
        "undelete-search-prefix": "बाट सुरु हुने  पृष्ठहरू देखाउनुहोस :",
+       "undelete-search-full": "पृष्ठमा निम्न भएको शीर्षक देखाउनुहोस्:",
        "undelete-search-submit": "खोजी गर्नुहोस्",
        "undelete-no-results": "मेटिएका पृष्ठहरूको अभिलेखमा कुनै पनि मिल्दो पृष्ठहरू भेटिएन ।",
        "undelete-filename-mismatch": " $1 समय छाप भएको मेटिएको संस्करण पुन: स्थापना गर्न सकिएन : फाइलनाम अमिल्दो",
        "unblocked-id": "$1 रोक हटाइएको छ",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] खुला भएको छ ।",
        "blocklist": "निषेधित प्रयोगकर्ताहरू",
+       "autoblocklist-submit": "खोज्नुहोस्",
        "ipblocklist": "निषेधित प्रयोगकर्ताहरू",
        "ipblocklist-legend": "रोकलगाइएका प्रयोगकर्ताहरू खोज्नुहोस",
        "blocklist-userblocks": "खाता निषेधित  लुकाउने",
        "export-download": "सङ्ग्रह गर्ने",
        "export-templates": "ढाँचाहरू संलग्न गर्नुहोस्",
        "export-pagelinks": "जोडिएको पृष्ठलाई यस गहराईसम्म समाबेश गर्नेः",
+       "export-manual": "पृष्ठहरू आफैँ थप्नुहोस्:",
        "allmessages": "सिस्टम सन्देशहरू",
        "allmessagesname": "नाम",
        "allmessagesdefault": "डिफल्ट सन्देश पाठ",
        "pageinfo-length": "पृष्ठ लम्बाई (बाईटमा)",
        "pageinfo-article-id": "पृष्ठ परिचय",
        "pageinfo-language": "पृष्ठ सामग्रीको भाषा",
+       "pageinfo-language-change": "परिवर्तन",
        "pageinfo-content-model": "पृष्ठ सामाग्री नमुना",
+       "pageinfo-content-model-change": "परिवर्तन",
        "pageinfo-robot-policy": "रोबोटहरूद्वारा अनुक्रमणिका",
        "pageinfo-robot-index": "अनुमति भएको",
        "pageinfo-robot-noindex": "अनुमति नभएको",
        "pageinfo-category-pages": "पृष्ठहरूको संख्या",
        "pageinfo-category-subcats": "उपश्रेणीहरूको संख्या",
        "pageinfo-category-files": "फाइलहरूको संख्या",
+       "pageinfo-user-id": "प्रयोगकर्ता परिचय",
        "markaspatrolleddiff": "गस्ती गरिएको(patrolled) को रुपमा चिनो लगाउने",
        "markaspatrolledtext": "यस पृष्ठलाई गस्ती गरिएको(patrolled) को रुपमा चिनो लगाउने",
        "markedaspatrolled": "गस्ती गरिएको(patrolled) को रुपमा चिनो लगाइयो",
        "patrol-log-header": "गस्ती गरिएका संस्करणहरूको लग यस प्रकार रहेका छन् ।",
        "log-show-hide-patrol": "$1 निगरानी लग",
        "log-show-hide-tag": "$1 ट्याग लग",
+       "confirm-markpatrolled-button": "ठीक छ",
        "deletedrevision": "पुराना पुनरावलोकनहरू $1 मेटिए",
        "filedeleteerror-short": "$1 फाइल मेटाइमा भूल",
        "filedeleteerror-long": "निम्न फाइल मेट्ने क्रममा त्रुटी भयो:\n\n$1",
        "newimages-summary": "यस विशेष पृष्ठले अन्तिम उर्ध्वभरण गरिएका फाइलहरू देखाउँछ ।",
        "newimages-legend": "फिल्टर",
        "newimages-label": "फाइल अथवा (यसको एउटा अंश)को नाम:",
+       "newimages-newbies": "नयाँ खाताको योगदानहरू मात्र देखाउने",
        "newimages-showbots": "बोटहरूद्वारा गरिएको अपलोड देखाउने",
        "noimages": "हेर्नको लागि केही छैन.",
        "ilsubmit": "खोज्नुहोस्",
        "exif-xyresolution-c": "$1 प्रतिसेन्टिमिटरथोप्लाहरु(डिपिसी)",
        "exif-colorspace-65535": "स्तरिकरण नगरिएको",
        "exif-componentsconfiguration-0": "अस्तित्वमा छैन",
+       "exif-componentsconfiguration-4": "क",
+       "exif-componentsconfiguration-6": "ब",
        "exif-exposureprogram-0": "खुलाइएको छैन",
        "exif-exposureprogram-1": "स्वयं",
        "exif-exposureprogram-2": "साधारण कार्यक्रम",
        "confirm-watch-top": "के यस पृष्ठलाई निगरानी सुचीमा थप्ने हो ?",
        "confirm-unwatch-button": "ठीक",
        "confirm-unwatch-top": "के यो पृष्ठलाई निगरानी सुचीबाट हटाउने हो ?",
+       "confirm-rollback-button": "ठीक छ",
        "semicolon-separator": ";&#32;",
        "comma-separator": ",&#32;",
        "colon-separator": ":&#32;",
        "tag-filter": "[[Special:Tags|पुच्छर]] फिल्टर:",
        "tag-filter-submit": "फिल्टर",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|ट्याग|ट्यागहरू}}]]: $2)",
+       "tag-mw-undo": "अन्डू गर्नुहोस्",
        "tags-title": "ट्यागहरु",
        "tags-intro": "यो पृष्ठले ट्यागहरू सूचीकृत गर्छ जससँग यो सफ्टवेयरले चिनो लगाउन र सम्पादन गर्न सक्छ र तिनका अर्थहरू ।",
        "tags-tag": "आन्तरिक ट्याग नाम",
        "compare-title-not-exists": "तपाईंले खुलाउनु भएको शिर्षक उपलब्ध छैन ।",
        "compare-revision-not-exists": "तपाईंले खुलाउनु भएको संस्करण उपलब्ध छैन ।",
        "diff-form": "भिन्नताहरू",
+       "permanentlink": "स्थायी लिङ्क",
        "dberr-problems": "क्षमा पाउँ! यो साइटमा तकनीकी गड़बड़ी आइपरेकोछ।",
        "dberr-again": "केही समय पर्खिएर पुन: लोड हुन दिनुहोस् ।",
        "dberr-info": "(डेटाबेस सर्भर: $1 सँग सम्पर्क स्थापित गर्न सकिएन)",
        "htmlform-cloner-create": "अरू जोड्ने",
        "htmlform-cloner-delete": "हटाउने",
        "htmlform-cloner-required": "कम्तिमा एउटामा आवश्यक छ ।",
+       "htmlform-user-not-exists": "'''$1''' अस्तित्वमा छैन ।",
        "logentry-delete-delete": "$1 द्वारा पृष्ठ $3 {{GENDER:$2|मेटाइयो}}",
        "logentry-delete-restore": "$1 {{GENDER:$2|पुनर्स्थापित}} पृष्ठ $3 ($4)",
        "logentry-delete-event": "$1 ले $3 पृष्ठको लग {{PLURAL:$5|प्रविष्टि|प्रविष्टिहरू}}को दृश्यता {{GENDER:$2|परिवर्तन गर्यो}}: $4",
        "pagelang-language": "भाषा",
        "pagelang-use-default": "पूर्वनिर्धारित भाषा प्रयोग गर्ने",
        "pagelang-select-lang": "भाषा छान्ने",
+       "pagelang-reason": "कारण",
        "pagelang-submit": "बुझाउने",
        "right-pagelang": "पृष्ठको भाषा परिवर्तन गर्ने",
        "action-pagelang": "यस पृष्ठको भाषा परिवर्तन गर्ने",
        "special-characters-title-minus": "घटाउने चिन्ह",
        "mw-widgets-titleinput-description-new-page": "हालसम्म पृष्ठ उपलब्ध छैन्",
        "mw-widgets-titleinput-description-redirect": "$1 मा जाने",
-       "randomrootpage": "यादृच्छिक शीर्ष पृष्ठ"
+       "randomrootpage": "यादृच्छिक शीर्ष पृष्ठ",
+       "log-action-filter-all": "सबै",
+       "log-action-filter-block-block": "रोक्ने",
+       "log-action-filter-block-unblock": "फुक्का गर्ने",
+       "authmanager-userdoesnotexist": "प्रयोगकर्ता खाता \"$1\" दर्ता गरिएको छैन।",
+       "authmanager-email-label": "ईमेल",
+       "authmanager-email-help": "इमेल ठेगाना",
+       "authprovider-resetpass-skip-label": "छोड्नुहोस्",
+       "edit-error-short": "त्रुटि: $1"
 }
index db1959d..c9b4443 100644 (file)
        "expansion-depth-exceeded-category-desc": "De pagina overschrijdt de maximale expansiediepte.",
        "expansion-depth-exceeded-warning": "De pagina bevat te veel sjablonen",
        "parser-unstrip-loop-warning": "Er is een \"unstrip\"-lus gedetecteerd",
-       "parser-unstrip-recursion-limit": "De recursielimiet ($1) voor \"unstrip\" is overschreden",
+       "unstrip-depth-warning": "De recursielimiet ($1) voor \"unstrip\" is overschreden",
        "converter-manual-rule-error": "Er is een fout gedetecteerd in een handmatig toegevoegde taalconversieregel.",
        "undo-success": "Deze bewerking kan ongedaan gemaakt worden.\nHieronder staat de tekst waarin de wijziging ongedaan is gemaakt.\nControleer voor het opslaan of het resultaat gewenst is.",
        "undo-failure": "De wijziging kan niet ongedaan gemaakt worden vanwege andere strijdige wijzigingen.",
index dbdefda..115a9e9 100644 (file)
        "nosuchusershort": "Det finst ikkje nokon brukar med brukarnamnet «$1». Sjekk at du har skrive rett.",
        "nouserspecified": "Du må oppgje eit brukarnamn.",
        "login-userblocked": "Denne brukaren er blokkert. Innlogging er ikkje tillate.",
-       "wrongpassword": "Du har oppgjeve eit ugyldig passord. Prøv om att.",
+       "wrongpassword": "Rangt brukarnamn eller passord vart oppgjeve. Prøv om att.",
        "wrongpasswordempty": "Du oppgav ikkje noko passord. Ver venleg og prøv igjen.",
        "passwordtooshort": "Passord må innehalda minst {{PLURAL:$1|eitt teikn|$1 teikn}}.",
        "passwordtoolong": "Passord kan ikkje vera lengre enn {{PLURAL:$1|eitt|$1}} teikn.",
        "expansion-depth-exceeded-category": "Sider der utvidingsdjupna er overskriden",
        "expansion-depth-exceeded-warning": "Sida har overskride utvidingsdjupna",
        "parser-unstrip-loop-warning": "Det vart oppdaga ei løkke i Unstrip-funksjonen",
-       "parser-unstrip-recursion-limit": "Rekursjonsgrensa for Unstrip-funksjonen er overskriden ($1)",
+       "unstrip-depth-warning": "Rekursjonsgrensa for Unstrip-funksjonen er overskriden ($1)",
        "converter-manual-rule-error": "Det vart oppdaga ein feil i ein manuell språkkonverteringsregel",
        "undo-success": "Endringa kan angrast.\nSjå på samanlikninga under for å stadfesta at dette er det du ynskjer å gjera. Deretter kan du lagra desse endringane for å fullføra angringa.",
        "undo-failure": "Endringa kunne ikkje attenderullast grunna konflikt med endringar som er gjorde i mellomtida.",
        "right-siteadmin": "Låse og låse opp databasen",
        "right-override-export-depth": "Eksporter sider inkludert lenkte sider til ei djupn på 5",
        "right-sendemail": "Senda e-post til andre brukarar",
+       "grant-group-high-volume": "Utføra høgvolumaktivitet",
        "grant-blockusers": "Blokkera og avblokkera brukarar",
        "grant-createaccount": "Oppretta kontoar",
        "grant-createeditmovepage": "Oppretta, endra og flytta sider",
        "grant-delete": "Sletta sider, versjonar og loggoppføringar",
        "grant-editinterface": "Gjera endringar i MediaWiki-namnerommet og i CSS/JavaScript for brukarkontoen",
+       "grant-highvolume": "Høgvolumendring",
        "grant-protect": "Verna og avverna sider",
        "grant-sendemail": "Senda e-post til andre brukarar",
        "grant-uploadeditmovefile": "Lasta opp, byta ut og flytta filer",
index 368623e..731c447 100644 (file)
        "expansion-depth-exceeded-category-desc": "La pagina depassa la prigondor d’espandiment maximala.",
        "expansion-depth-exceeded-warning": "Pagina depassant la prigondor d'espandiment",
        "parser-unstrip-loop-warning": "Bocla pas desmontabla detectada",
-       "parser-unstrip-recursion-limit": "Limit de recursion pas desmontable depassat ($1)",
+       "unstrip-depth-warning": "Limit de recursion pas desmontable depassat ($1)",
        "converter-manual-rule-error": "Error detectada dins la règla manuala de conversion de lenga",
        "undo-success": "Aquesta modificacion va èsser desfaita. Confirmatz los cambiaments (visibles en bas d'aquesta pagina), puèi salvatz se sètz d’acòrdi. Mercés de motivar l’anullacion dins la bóstia de resumit.",
        "undo-failure": "Aquesta modificacion a pas pogut èsser desfaita a causa de conflictes amb de modificacions intermediàrias.",
index 3d50f90..cfcc21d 100644 (file)
        "expansion-depth-exceeded-category-desc": "ଏହି ପୃଷ୍ଠାର ସର୍ବାଧିକ ଲମ୍ବା ହେବା ଠାରୁ ବଳିଗଲାଣି",
        "expansion-depth-exceeded-warning": "ପୃଷ୍ଠାଟି ବିସ୍ତ୍ରୁତ ଗଭୀରତାରୁ ଅଧିକ ହୋଇଗଲା",
        "parser-unstrip-loop-warning": "ଅଜଣା ଲୁପ ଜଣାପଡିଲା",
-       "parser-unstrip-recursion-limit": "ଅଜଣା ଚକ୍ରର ସୀମା ଅତ୍ୟଧିକ ହୋଇଗଲା ($1)",
+       "unstrip-depth-warning": "ଅଜଣା ଚକ୍ରର ସୀମା ଅତ୍ୟଧିକ ହୋଇଗଲା ($1)",
        "converter-manual-rule-error": "ଆପେ ଆପେ ଭାଷା ପରିବର୍ତ୍ତନ ନିଯମରେ ଭୁଲ ଅଛି",
        "undo-success": "ଏହି ସମ୍ପାଦନା ପଛକୁ ଫେରାଯାଇପାରିବ ନାହିଁ ।\nଦୟାକରି ତୁଳନା କରି ପରଖିନିଅନ୍ତୁ ଯେ ଆପଣ ଏହାହିଁ କରିବାକୁ ଚାହୁଁଥିଲେ, ଆଉ ସମ୍ପାଦନା ଶେଷ କରିବା ପାଇଁ ତଳେ ଥିବା ବଦଳ ସାଇତି ରଖନ୍ତୁ ।",
        "undo-failure": "ଏହି ସମ୍ପାଦନା ପଛକୁ ଫେରାଯାଇ ପାରିବ ନାହିଁ କାରଣ ମଝିରେ ଘଟିଥିବା ଅନେକ ଛୋଟ ଛୋଟ ବଦଳ ଅସୁବିଧା ତିଆରି କରୁଅଛି ।",
index 19f145f..ae68720 100644 (file)
@@ -95,7 +95,8 @@
                        "Sebek Adamowicz",
                        "Cholewka",
                        "Ankam",
-                       "Anwar2"
+                       "Anwar2",
+                       "Acamicamacaraca"
                ]
        },
        "tog-underline": "Podkreślenie linków:",
        "expansion-depth-exceeded-category-desc": "Strona przekracza maksymalną głębokość rozbudowy.",
        "expansion-depth-exceeded-warning": "Strona przekroczyła głębokość rozbudowy",
        "parser-unstrip-loop-warning": "Wykryto nieskończoną pętlę",
-       "parser-unstrip-recursion-limit": "Przekroczono maksymalną głębokość zagnieżdżania ($1)",
+       "unstrip-depth-warning": "Przekroczono maksymalną głębokość zagnieżdżania ($1)",
        "converter-manual-rule-error": "Błąd w językowych regułach konwersji",
        "undo-success": "Edycja może zostać wycofana. Porównaj ukazane poniżej różnice między wersjami, a następnie zapisz zmiany.",
        "undo-failure": "Edycja nie może zostać wycofana z powodu konfliktu z wersjami pośrednimi.",
index 3543a66..ffc4456 100644 (file)
        "expansion-depth-exceeded-category-desc": "La pàgina a l'ha passà la profondità d'espansion.",
        "expansion-depth-exceeded-warning": "La pàgina a l'ha sorpassà la profondità d'espansion",
        "parser-unstrip-loop-warning": "Trovà un sicl nen dësmontàbil",
-       "parser-unstrip-recursion-limit": "Sorpassà ël lìmit d'arcorensa nen dësmontàbil: $1",
+       "unstrip-depth-warning": "Sorpassà ël lìmit d'arcorensa nen dësmontàbil: $1",
        "converter-manual-rule-error": "Eror trovà ant la régola ëd conversion manual ëd la lenga",
        "undo-success": "Sta modìfica-sì as peul scancelesse. Për piasì, ch'a contròla ambelessì sota për esse sigur che a l'é pro lòn che a veul fé, e peuj ch'as salva lòn ch'a l'ha butà chiel/chila për finì dë scancelé la modìfica ch'a-i era.",
        "undo-failure": "Sta modìfica a l'é nen podusse scancelé për via che a-i son dle contradission antra version antrames.",
index 683ecf5..fe4db5a 100644 (file)
                        "Fitoschido"
                ]
        },
-       "tog-underline": "Link sublinhado:",
+       "tog-underline": "Ligação sublinhada:",
        "tog-hideminor": "Ocultar edições menores nas mudanças recentes",
        "tog-hidepatrolled": "Ocultar edições patrulhadas nas mudanças recentes",
        "tog-newpageshidepatrolled": "Ocultar páginas patrulhadas da lista de páginas novas",
        "tog-minordefault": "Marcar todas as edições como menores por padrão",
        "tog-previewontop": "Mostrar previsão antes da caixa de edição",
        "tog-previewonfirst": "Mostrar previsão na primeira edição",
-       "tog-enotifwatchlistpages": "Notificar-me por email quando uma página ou arquivo vigiado for alterado",
+       "tog-enotifwatchlistpages": "Notificar-me por e-mail quando uma página ou um arquivo vigiado for alterado",
        "tog-enotifusertalkpages": "Receber email quando minha página de discussão for editada",
-       "tog-enotifminoredits": "Notificar-me por email também sobre edições menores de páginas ou arquivos",
+       "tog-enotifminoredits": "Notificar-me por e-mail também sobre edições menores de páginas ou arquivos",
        "tog-enotifrevealaddr": "Revelar meu endereço de email nas mensagens de notificação",
        "tog-shownumberswatching": "Mostrar o número de usuários que estão vigiando",
        "tog-oldsig": "Assinatura atual:",
-       "tog-fancysig": "Tratar assinatura como wikitexto (sem link automático)",
+       "tog-fancysig": "Tratar assinatura como wikitexto (sem ligação automática)",
        "tog-uselivepreview": "Mostrar visualizações sem recarregar a página",
        "tog-forceeditsummary": "Avisar-me ao introduzir um sumário de edição vazio",
        "tog-watchlisthideown": "Ocultar as minhas edições da lista de páginas vigiadas",
        "tog-prefershttps": "Usar sempre uma conexão segura enquanto estiver conectado",
        "underline-always": "Sempre",
        "underline-never": "Nunca",
-       "underline-default": "Padrão do navegador/skin",
+       "underline-default": "Padrão do navegador/tema",
        "editfont-style": "Estilo da fonte da área de edição:",
        "editfont-monospace": "Fonte monoespaçada",
        "editfont-sansserif": "Fonte sem serifa",
        "expansion-depth-exceeded-category-desc": "A página excede a profundidade de expansão permitida.",
        "expansion-depth-exceeded-warning": "A página excedeu a profundidade de expansão",
        "parser-unstrip-loop-warning": "Foi detectado um ciclo infinito unstrip",
-       "parser-unstrip-recursion-limit": "Limite de recursão do unstrip excedido ($1)",
+       "unstrip-depth-warning": "Limite de recursão do unstrip excedido ($1)",
        "converter-manual-rule-error": "Erro detectado na regra de conversão de língua manual",
        "undo-success": "A edição pôde ser desfeita. Por gentileza, verifique o comparativo a seguir para se certificar de que é isto que deseja fazer, salvando as alterações após ter terminado de revisá-las.",
        "undo-failure": "A edição não pôde ser desfeita devido a alterações intermediárias conflitantes.",
        "savedrights": "Os grupos {{GENDER:$1|do usuário|da usuária}} $1 foram gravados.",
        "timezonelegend": "Fuso horário:",
        "localtime": "Horário local:",
-       "timezoneuseserverdefault": "Utilizar padrão do wiki ($1)",
-       "timezoneuseoffset": "Outro (especifique diferença horária)",
+       "timezoneuseserverdefault": "Utilizar padrão da wiki ($1)",
+       "timezoneuseoffset": "Outro (especificar desvio horário)",
        "servertime": "Horário do servidor:",
        "guesstimezone": "Preencher a partir do navegador",
        "timezoneregion-africa": "África",
        "group-membership-link-with-expiry": "$1 (até $2)",
        "prefs-registration": "Hora de registro:",
        "yourrealname": "Nome verdadeiro:",
-       "yourlanguage": "Língua:",
+       "yourlanguage": "Idioma:",
        "yourvariant": "Variante da língua de conteúdo:",
        "prefs-help-variant": "A sua variante preferida ou ortografia para mostrar no conteúdo das páginas deste wiki.",
        "yournick": "Nova assinatura:",
        "badsig": "Assinatura inválida; verifique o código HTML utilizado.",
        "badsiglength": "A sua assinatura é muito longa.\nEla deve ter menos de $1 {{PLURAL:$1|caractere|caracteres}}.",
        "yourgender": "Como você prefere ser descrito(a)?",
-       "gender-unknown": "Ao mencionar você, o software usará palavras do gênero neutro sempre que possível",
+       "gender-unknown": "Ao mencionar você, o ''software'' usará palavras do gênero neutro sempre que possível",
        "gender-male": "Ele é um usuário",
        "gender-female": "Ela é uma usuária",
-       "prefs-help-gender": "A configuração desta preferência é opcional.\nO software utiliza seu valor para tratá-lo(a) e mencioná-lo(a) a outros usando o gênero gramatical adequado.\nEsta informação será pública.",
+       "prefs-help-gender": "A configuração dessa preferência é opcional.\nO ''software'' utiliza seu valor para tratar e mencionar você a outros usando o gênero gramatical adequado.\nEssa informação será pública.",
        "email": "E-mail",
        "prefs-help-realname": "O fornecimento de seu nome verdadeiro é opcional.\nCaso decida fornecê-lo, este será utilizado para dar-lhe crédito pelo seu trabalho.",
        "prefs-help-email": "O endereço de correio eletrônico é opcional, mas será necessário para recriar sua senha caso esqueça a antiga.",
        "mw-widgets-titleinput-description-new-page": "a página ainda não existe",
        "mw-widgets-titleinput-description-redirect": "redirecionar para $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Adicionar uma categoria...",
-       "mw-widgets-usersmultiselect-placeholder": "Adicione mais...",
+       "mw-widgets-usersmultiselect-placeholder": "Adicionar mais…",
        "date-range-from": "Da data:",
        "date-range-to": "Para data:",
        "sessionmanager-tie": "Não é possível combinar vários tipos de autenticação de solicitação: $1.",
index 6340c76..30f0ba2 100644 (file)
        "expansion-depth-exceeded-category-desc": "A página excede a profundidade de expansão permitida.",
        "expansion-depth-exceeded-warning": "A página excedeu a profundidade de expansão",
        "parser-unstrip-loop-warning": "Foi detetado um ciclo infinito da função unstrip",
-       "parser-unstrip-recursion-limit": "Limite de recursão da função unstrip excedido ($1)",
+       "unstrip-depth-warning": "Limite de recursão da função unstrip excedido ($1)",
        "converter-manual-rule-error": "Erro detetado na regra de conversão de língua manual",
        "undo-success": "É possível desfazer a edição.\nVerifique a comparação abaixo, por favor, para se certificar de que corresponde ao que pretende fazer.\nDepois grave as alterações, para finalizar e desfazer a edição.",
        "undo-failure": "Não foi possível desfazer a edição por conflito com alterações intermédias.",
        "pageinfo-article-id": "ID da página",
        "pageinfo-language": "Língua do conteúdo da página",
        "pageinfo-language-change": "alterar",
-       "pageinfo-content-model": "Modelo de conteúdo de página",
+       "pageinfo-content-model": "Modelo de conteúdo da página",
        "pageinfo-content-model-change": "alterar",
        "pageinfo-robot-policy": "Indexação por robôs",
        "pageinfo-robot-index": "Permitida",
index f031c36..6849ba5 100644 (file)
        "expansion-depth-exceeded-category-desc": "Expansion depth exceeded category description. Shown on [[Special:TrackingCategories]].\n\nSee also:\n* {{msg-mw|Expansion-depth-exceeded-category}}",
        "expansion-depth-exceeded-warning": "Error message shown when a page exceeded the [[meta:Help:Expansion_depth|expansion depth limit]] of the preprocessor.\n\nParameters:\n* $1 - (Unused) the value of the depth limit\n* $2 - (Unused) the value of the max depth limit\nSee also:\n* {{msg-mw|Expansion-depth-exceeded-category}}",
        "parser-unstrip-loop-warning": "{{Doc-important|Do not translate function name <code>unstrip</code>.}}\nThis error is shown when a parser extension tag such as <code><nowiki><pre></nowiki></code> includes a reference to itself in its own output.\n\nThe reference must be to the exact same invocation of the tag at the same location in the source, merely writing <code><nowiki><pre><pre></pre></pre></nowiki></code> will not do it.\n\nThis is usually impossible and unlikely to happen by accident, so translation is not essential.\n\n\"Unstrip\" refers to the internal function of the parser, called \"unstrip\", which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above.\n\nSee also:\n*{{msg-mw|Parser-unstrip-recursion-limit}}",
-       "parser-unstrip-recursion-limit": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the recursion limit for nested parser extension tags is exceeded.\n\nThis warning may be encountered due to input text like <code><nowiki><ref><ref><ref>...</ref></ref></ref></nowiki></code>.\n\nParameters:\n* $1 - the depth limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call and which would enter an infinite loop in the situation above.\n\nSee also:\n* {{msg-mw|Parser-unstrip-loop-warning}}",
+       "unstrip-depth-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the recursion limit for nested parser extension tags is exceeded.\n\nThis warning may be encountered due to input text like <code><nowiki><ref><ref><ref>...</ref></ref></ref></nowiki></code>.\n\nParameters:\n* $1 - the depth limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n* {{msg-mw|Parser-unstrip-loop-warning}}",
+       "unstrip-depth-category": "This message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip recursion depth limit is exceeded.",
+       "unstrip-size-warning": "{{doc-important|Do not translate function name <code>unstrip</code>.}}\nThis message is shown when the maximum expansion size for nested parser extension tags is exceeded.\n\nParameters:\n* $1 - the size limit\n\n\"Unstrip\" refers to the internal function of the parser, called 'unstrip', which recursively puts the output of parser functions in the place of the parser function call.\n\nSee also:\n* {{msg-mw|Parser-unstrip-loop-warning}}",
+       "unstrip-size-category": "This message is used as the category name of a [[mw:Help:Tracking categories|tracking category]] in which pages are placed automatically if the unstrip expansion size limit is exceeded.",
        "converter-manual-rule-error": "Used as error message when a manual conversion rule for the [[mw:Language_converter|language converter]] has errors. For example it's not using the correct syntax, or not supplying text in all variants.",
        "undo-success": "Text on special page to confirm edit revert. You arrive on this page by clicking on the \"undo\" link on a revision history special page.\n\n{{Identical|Undo}}",
        "undo-failure": "Message appears if an attempt to revert an edit by clicking the \"undo\" link on the page history fails.\n\nSee also:\n* {{msg-mw|Undo-norev}}\n* {{msg-mw|Undo-nochange}}\n{{Identical|Undo}}",
        "limitreport-expansiondepth-value": "{{optional}}\nFormat for the \"Highest expansion depth\" row in the limit report table.\n\nParameters:\n* $1 - the depth\n* $2 - the maximum",
        "limitreport-expensivefunctioncount": "Label for the \"Expensive parser function count\" row in the limit report table",
        "limitreport-expensivefunctioncount-value": "{{optional}}\nFormat for the \"Expensive parser function count\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum",
+       "limitreport-unstrip-depth": "Label for the \"unstrip depth\" row in the limit report table. \"Unstrip\" is a MediaWiki function name and as such does not need to be translated.",
+       "limitreport-unstrip-depth-value": "{{optional}}\nFormat for the \"unstrip depth\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum",
+       "limitreport-unstrip-size": "Label for the \"unstrip size\" row in the limit report table. \"Unstrip\" is a MediaWiki function name and as such does not need to be translated.",
+       "limitreport-unstrip-size-value": "{{optional}}\nFormat for the \"unstrip size\" row in the limit report table.\n\nParameters:\n* $1 - the usage\n* $2 - the maximum",
        "expandtemplates": "{{doc-special|ExpandTemplates}}\nThe name of the [[mw:Extension:ExpandTemplates|Expand Templates extension]].",
        "expand_templates_intro": "This is the explanation given in the heading of the [[Special:ExpandTemplates]] page; it describes its functionality to the users.\nFor more information, see [[mw:Extension:ExpandTemplates]]",
        "expand_templates_title": "The label of the input box for the context title on the form displayed at [[Special:ExpandTemplates]] page.",
index 8b3db5d..8a32caf 100644 (file)
        "expansion-depth-exceeded-category": "Nisyu mast'ariy ukhu kaqniyuq p'anqakuna",
        "expansion-depth-exceeded-warning": "P'anqaqa nisyu mast'ariy ukhu kaqniyuqmi",
        "parser-unstrip-loop-warning": "Muyupayaq siqum tarisqa",
-       "parser-unstrip-recursion-limit": "Nisyu kuti muyupayay siqum ($1)",
+       "unstrip-depth-warning": "Nisyu kuti muyupayay siqum ($1)",
        "converter-manual-rule-error": "Maki rimay t'ikrana kamachinapiqa pantasqam tarisqa",
        "undo-success": "Rurasqata kutichiyta atinkim. Manaraq kutichispaykiqa, kay qatiq wakichayta qhawariy rikunaykipaq chiqapta munasqaykichu manallachu, chaymantataq waqaychay kutichinapaq.",
        "undo-failure": "Manam atinichu llamk'apusqata kutichiyta, huk ruraqtaq musuqta llamk'apurquptinñam.",
index b4a9057..e9c2512 100644 (file)
        "expansion-depth-exceeded-category": "Paginas, nua che la porfunditad d'extensiun è surpassada",
        "expansion-depth-exceeded-warning": "Questa pagina ha surpassà la profunditad d'expansiun",
        "parser-unstrip-loop-warning": "Chattà circul d'unstrip",
-       "parser-unstrip-recursion-limit": "Limita da recursiun ($1) per unstrip è surpassà",
+       "unstrip-depth-warning": "Limita da recursiun ($1) per unstrip è surpassà",
        "converter-manual-rule-error": "Ina errur è cumparida en la regla manuala da convertir la lingua",
        "undo-success": "Questa modificaziun na po betg vegnir revocada.\nControlleschan en la vista per cumparegliar sutvart sche quei è quai che ti vuls far e lura memorisescha las midadas sutvart per terminar la modificaziun.",
        "undo-failure": "La modificaziun na pudeva betg vegnir revocada causa modificaziuns pli novas che stattan en conflict cun questa acziun.",
index 97e6976..1cb75ed 100644 (file)
        "expansion-depth-exceeded-category-desc": "Pagina depășește profunzimea maximă de expansiune.",
        "expansion-depth-exceeded-warning": "Pagina depășește profunzimea de expansiune",
        "parser-unstrip-loop-warning": "Buclă nedetașabilă detectată",
-       "parser-unstrip-recursion-limit": "Limita de recursivitate nedetașabilă depășită ($1)",
+       "unstrip-depth-warning": "Limita de recursivitate nedetașabilă depășită ($1)",
        "converter-manual-rule-error": "Eroare detectată în regula manuală de conversie a limbii",
        "undo-success": "Modificarea poate fi anulată. Verificați diferența de dedesubt și apoi salvați pentru a termina anularea modificării.",
        "undo-failure": "Modificarea nu poate fi reversibilă datorită conflictului de modificări intermediare.",
        "uploadstash-refresh": "Reîmprospătează lista de fișiere",
        "uploadstash-thumbnail": "arată miniatura",
        "uploadstash-exception": "Nu pot stoca încărcare în spațiul temporar ($1): \"$2\"",
+       "uploadstash-bad-path": "Calea nu există.",
+       "uploadstash-bad-path-invalid": "Calea nu este validă.",
+       "uploadstash-bad-path-unknown-type": "Tip necunoscut „$1”",
+       "uploadstash-bad-path-bad-format": "Cheia „$1” nu este într-un format recunoscut.",
+       "uploadstash-file-not-found": "Cheia „$1” nu a fost găsită în locația temporară.",
        "invalid-chunk-offset": "Decalaj de segment nevalid",
        "img-auth-accessdenied": "Acces interzis",
        "img-auth-nopathinfo": "PATH_INFO lipsește.\nServerul dumneavoastră nu a fost setat pentru a trece aceste informații.\nS-ar putea să fie bazat pe CGI și să nu suporte img_auth.\nVedeți https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "tag-mw-replace": "Înlocuit",
        "tag-mw-replace-description": "Editări care șterg mai mult de 90% din conținutul unei pagini",
        "tag-mw-rollback": "Revenire",
+       "tag-mw-undo": "Anulare",
        "tags-title": "Etichete",
        "tags-intro": "Această pagină afișează etichetele, inclusiv semnificația lor, pe care software-ul le poate folosi la marcarea modificărilor.",
        "tags-tag": "Numele etichetei",
index 03956b5..ed9b33c 100644 (file)
        "expansion-depth-exceeded-category-desc": "'A pàgene sbonne 'a massime espanzione de profonnetà.",
        "expansion-depth-exceeded-warning": "Pàggene ca sbonnane 'a profonnetà de espanzione",
        "parser-unstrip-loop-warning": "Cicle infinite acchiate",
-       "parser-unstrip-recursion-limit": "Limite de ricorsione infinite sbunnate ($1)",
+       "unstrip-depth-warning": "Limite de ricorsione infinite sbunnate ($1)",
        "converter-manual-rule-error": "Errore assute jndr'à le regole de conversione d'a lènghe manuale",
        "undo-success": "'U cangiamende pò essere annullate.\nPe piacere verifichesce 'u combronde sotte pe condrollà ca quiste ca tu vuè ccu face e pò reggistrè le cangiaminde aqquà sotte pe spiccià l'annullamende d'u cangiamende.",
        "undo-failure": "'U cangiamende non ge pò essere annullete purcè stè 'nu conflitte de cangiaminde indermedije.",
index f7a6e44..0899f03 100644 (file)
        "expansion-depth-exceeded-category-desc": "У страницы превышена максимально допустимая глубина раскрытия.",
        "expansion-depth-exceeded-warning": "На странице превышен предел вложенности",
        "parser-unstrip-loop-warning": "Обнаружен незакрытый pre",
-       "parser-unstrip-recursion-limit": "Превышен предел рекурсии ($1)",
+       "unstrip-depth-warning": "Превышен предел рекурсии ($1)",
        "converter-manual-rule-error": "Ошибка в ручном правиле преобразования языка",
        "undo-success": "Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.",
        "undo-failure": "Правка не может быть отменена из-за несовместимости промежуточных изменений.",
index 54bf4fc..d51f9ee 100644 (file)
        "expansion-depth-exceeded-category": "Сторінкы превышують глубку експанзії",
        "expansion-depth-exceeded-warning": "Сторінка перевышыла глубку експанзії",
        "parser-unstrip-loop-warning": "Выявлене заціклїня unstrip",
-       "parser-unstrip-recursion-limit": "Перевышеный ліміт рекурзії unstrip ($1)",
+       "unstrip-depth-warning": "Перевышеный ліміт рекурзії unstrip ($1)",
        "converter-manual-rule-error": "Найджена хыба в ручнім правилї конверзії языка",
        "undo-success": "Едітованя може быти зрушене.\nПросиме Вас перевірьте порівнаня ниже, жебы сьте ся упевнили в тім, што хочете зробити а потім уложте зміны долов, жебы сьте закінчіли зрушіня едітованя.",
        "undo-failure": "Едітованя не могло быти зрушене про конфлікт міджілеглых змін.",
index c2805b2..0189324 100644 (file)
        "expansion-depth-exceeded-category-desc": "एतत् पृष्ठं विस्तारस्य सीमाम् अत्यक्रमत् ।",
        "expansion-depth-exceeded-warning": "पृष्ठेऽस्मिन् विस्तारसीमा समाप्ता",
        "parser-unstrip-loop-warning": "Unstrip परिक्रमः (loop) प्राप्तः",
-       "parser-unstrip-recursion-limit": "Unstrip इत्यस्य प्रत्यावर्तनस्य (recursion) सीमा समाप्ता ($1)",
+       "unstrip-depth-warning": "Unstrip इत्यस्य प्रत्यावर्तनस्य (recursion) सीमा समाप्ता ($1)",
        "converter-manual-rule-error": "मानवीये भाषापरिवर्तने दोषः दृष्टः ।",
        "undo-success": "एतत् सम्पादनं पूर्ववत् कर्तुं शक्यते ।\nकृपया अधः दत्तयोः तुलनां कृत्वा यत् आवश्यकं, तत् परिवर्तनं संरक्षतु च । ततः पूर्ववत्-करणप्रक्रिया समाप्यताम् ।",
        "undo-failure": "सम्पादनं पूर्ववत् कर्तुं न शक्यते । यतः मध्ये परस्परविपरितानि सम्पादनानि अभवन् ।",
index 2af5131..d94dbef 100644 (file)
        "expansion-depth-exceeded-category-desc": "Сирэй аһыллыытын дириҥэ куоһарыллыбыт.",
        "expansion-depth-exceeded-warning": "Сирэйгэ угуллубут билэлэр аһара элбээбиттэр",
        "parser-unstrip-loop-warning": "Сабыллыбатах pre көһүннэ",
-       "parser-unstrip-recursion-limit": "Рекурсия ахсаана таһынан барбыт ($1)",
+       "unstrip-depth-warning": "Рекурсия ахсаана таһынан барбыт ($1)",
        "converter-manual-rule-error": "Тылы уларытыы быраабылатын алҕаһа таҕыста",
        "undo-success": "Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.",
        "undo-failure": "Уларытыы төннөр кыаҕа суох. Ыккардынааҕы көннөрүүлэр бэйэ бэйэлэригэр сөп түбэспэттэр.",
index 02fa5be..0e60c0f 100644 (file)
        "expansion-depth-exceeded-category-desc": "La pàggina passa lu funnu d'espanzioni màssimu.",
        "expansion-depth-exceeded-warning": "Sta pàggina passau lu funnu d'espanzioni màssimu",
        "parser-unstrip-loop-warning": "Rilivatu un cìrculu di Unstrip",
-       "parser-unstrip-recursion-limit": "Passatu lu lìmiti di ricursioni di Unstrip ($1)",
+       "unstrip-depth-warning": "Passatu lu lìmiti di ricursioni di Unstrip ($1)",
        "converter-manual-rule-error": "Rilivatu n'erruri nta na règula manuali di cunvirsioni di lingua",
        "undo-success": "Lu canciamentu pò essiri annullatu.\nVirificati lu paraguni ccà sutta p'accuràrivi ca lu cuntinutu è chiddu addisiatu e doppu sarvati la pàggina pi cumplitari l'annullamentu.",
        "undo-failure": "Lu canciamentu nun pò èssiri annullatu a càusa d'un cunflittu cu li canciamenti ntirmedi.",
index cd442a3..0b5cd26 100644 (file)
        "expansion-depth-exceeded-category-desc": "The page exceeds the mucklest expansion depth.",
        "expansion-depth-exceeded-warning": "Page owershote the expansion depth",
        "parser-unstrip-loop-warning": "Unstrip luip detected",
-       "parser-unstrip-recursion-limit": "Unstrip recursion limit owershote ($1)",
+       "unstrip-depth-warning": "Unstrip recursion limit owershote ($1)",
        "converter-manual-rule-error": "mistak detected in manual leid conversion rule",
        "undo-success": "The eidit can be ondun. Please check the chynges albo tae check that this is whit ye wint tae dae, n than hain the chynges albo tae be duin ondaein the eidit.",
        "undo-failure": "The eedit coudna be ondun cause o confleectin eedits inatween.",
index 6b0dc67..a8c01a6 100644 (file)
@@ -7,7 +7,8 @@
                        "Sindhu",
                        "Mehtab ahmed",
                        "Macofe",
-                       "Indus Asia"
+                       "Indus Asia",
+                       "BukhariSaeed"
                ]
        },
        "tog-underline": "ڳنڍڻي هيٺان لڪير:",
        "table_pager_limit_submit": "ھلو",
        "table_pager_empty": "ڪو بہ نتيجو نہ مليو",
        "autoredircomment": "صفحي کي [[$1]] ڏانھن چوريو",
+       "autosumm-newblank": "خالي صفحو تخليق ڪيو",
        "watchlistedit-normal-title": "نظر ۾ فھرست کي سنواريو",
        "watchlistedit-raw-titles": "عنوانَ:",
        "watchlistedit-clear-titles": "عنوانَ:",
index de801f4..26e086b 100644 (file)
        "expansion-depth-exceeded-category-desc": "Moɲoo ga hayandiri guusuyan kul ibeeroo hoo.",
        "expansion-depth-exceeded-warning": "Moɲoo ga hayandiri guusuyanoo hoo",
        "parser-unstrip-loop-warning": "Feferiyan-naŋ zollo maatandi",
-       "parser-unstrip-recursion-limit": "Feferiyan-filla dimmaa hoo ($1)",
+       "unstrip-depth-warning": "Feferiyan-filla dimmaa hoo ($1)",
        "converter-manual-rule-error": "Firka bangay kanbe šenni bereyan ašariyaa ra",
        "undo-success": "Fasalyan ga hin ka borrandi.\nGuna ganda deedandiyanoo ka tabatandi kaŋ woo no war ga boona k'a tee, nda waati din wa ganda barmawey gaabu ka fasalyan borroyanoo benandi.",
        "undo-failure": "Barmaa ši hin ka taafeeri zama game barmay fooyaŋ ga cere hoo.",
index a9f8716..abef360 100644 (file)
        "expansion-depth-exceeded-category-desc": "Stranica je prešla najveću dubinu proširenja.",
        "expansion-depth-exceeded-warning": "Na ovoj stranici dubina proširenja je prevelika",
        "parser-unstrip-loop-warning": "Utvrđena je petlja",
-       "parser-unstrip-recursion-limit": "Dosegnuto je ograničenje rekurzije ($1)",
+       "unstrip-depth-warning": "Dosegnuto je ograničenje rekurzije ($1)",
        "converter-manual-rule-error": "Pronađena je greška u pravilu za ručno pretvaranje jezika",
        "undo-success": "Izmjena se može vratiti.\nMolimo da provjerite usporedbu ispod da budete sigurni da to želite učiniti, a zatim spremite promjene da bi ste završili vraćanje izmjene.",
        "undo-failure": "Izmjene se ne mogu vratiti zbog konflikta sa izmjenama u međuvremenu.",
index 41c87d4..6a45f15 100644 (file)
        "expansion-depth-exceeded-category-desc": "මෙම පිටුව උපරිම පුළුල් ගැඹුරු ඉක්මවා යයි.",
        "expansion-depth-exceeded-warning": "පිටුව පුළුල් ගැඹුරු ඉක්මවා",
        "parser-unstrip-loop-warning": "Unstrip ලූප අනාවරණය",
-       "parser-unstrip-recursion-limit": "Unstrip සහානුයාත සීමාව ($1) ඉක්මවා",
+       "unstrip-depth-warning": "Unstrip සහානුයාත සීමාව ($1) ඉක්මවා",
        "converter-manual-rule-error": "අත්පොත භාෂා පරිවර්තනය පාලනය අනාවරණය දෝෂ",
        "undo-success": "මෙම සංස්කරණය අහෝසි කල හැක.\nපහත දක්වා ඇති සැසැඳුම පරික්ෂා කර බලා ඔබගේ අභිලාෂය මෙයමැයි තහවුරු කොට ගෙන, සංස්කරණය අහෝසිකිරීම සඳහා පහත දැක්වෙන වෙනස්වීම් සුරකින්න.",
        "undo-failure": "පරස්පර විරෝධී අතරමැදි සංස්කරණ හේතුවෙන් මෙම සංස්කරණය අහෝසි කල නොහැක.",
index be54581..7d4b500 100644 (file)
        "expansion-depth-exceeded-category-desc": "Stránka prekročila maximálnu hĺbku expanzie.",
        "expansion-depth-exceeded-warning": "Stránka prekročila povolenú hĺbku expanzie",
        "parser-unstrip-loop-warning": "Zistené zacyklenie volania rozširovacej značky",
-       "parser-unstrip-recursion-limit": "Prektočený limit rekurzie volania rozširovacej značky ($1)",
+       "unstrip-depth-warning": "Prektočený limit rekurzie volania rozširovacej značky ($1)",
        "converter-manual-rule-error": "Bola zistená chyba v pravidle manuálnej konverzie jazyka",
        "undo-success": "Úpravu je možné vrátiť.\nProsím, skontrolujte tento rozdiel, čím overíte, že táto úprava je tá, ktorú chcete. Následne uložte zmeny, čím ukončíte vrátenie.",
        "undo-failure": "Úpravu nie je možné vrátiť kvôli konfliktným medziľahlým úpravám.",
index 5c7b60f..117ded9 100644 (file)
        "expansion-depth-exceeded-category-desc": "Stran presega največjo globino razširitve.",
        "expansion-depth-exceeded-warning": "Stran je prekoračila globino razširitve",
        "parser-unstrip-loop-warning": "Zaznal sem odvezano zanko",
-       "parser-unstrip-recursion-limit": "Presežena je omejitev odvezane rekurzije ($1)",
+       "unstrip-depth-warning": "Presežena je omejitev odvezane rekurzije ($1)",
        "converter-manual-rule-error": "Odkril sem napako v ročnem pravilu pretvorbe jezikov",
        "undo-success": "Urejanje ste razveljavili. Prosimo, preverite prikazano primerjavo redakcij in, če ustrezajo, shranite spremembe.",
        "undo-failure": "Zaradi navzkrižij urejanj, ki so se vmes pojavila, tega urejanja ni moč razveljaviti.",
index c148b64..8fdfa58 100644 (file)
        "recentchanges-legend-heading": "<strong>Legjenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (shiko gjithashtu [[Special:NewPages|listën e faqeve të reja]])",
        "recentchanges-submit": "Shfaq",
+       "rcfilters-tag-remove": "Hiq '$1'",
+       "rcfilters-legend-heading": "<strong>Lista e shkurtesave:</strong>",
+       "rcfilters-other-review-tools": "Veglat tjera të rishikimit",
+       "rcfilters-group-results-by-page": "Grupo rezultatet sipas faqës",
        "rcfilters-activefilters": "Filtrat aktiv",
        "rcfilters-advancedfilters": "Filtra të avancuar",
+       "rcfilters-limit-title": "Rezultatet për të treguar",
+       "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|ndryshimi|ndryshimet}}, $2",
+       "rcfilters-date-popup-title": "Periudha kohore për ta kërkuar",
+       "rcfilters-days-title": "Ditët e fundit",
+       "rcfilters-hours-title": "Orët e fundit",
+       "rcfilters-days-show-days": "$1 {{PLURAL:$1|dit|ditë}}",
+       "rcfilters-days-show-hours": "$1 {{PLURAL:$1|orë|orë}}",
+       "rcfilters-highlighted-filters-list": "Theksuar: $1",
        "rcfilters-quickfilters": "Filtrat e ruajtur",
-       "rcfilters-quickfilters-placeholder-title": "Asnjë lidhje e ruajtur",
+       "rcfilters-quickfilters-placeholder-title": "Asnjë filtër i ruajtur",
        "rcfilters-savedqueries-defaultlabel": "Filtrat e ruajtur",
        "rcfilters-savedqueries-rename": "Riemro",
        "rcfilters-savedqueries-setdefault": "Vendosur si parazgjedhje",
        "rcfilters-savedqueries-unsetdefault": "Hiqe si parazgjedhje",
        "rcfilters-savedqueries-remove": "Largo",
        "rcfilters-savedqueries-new-name-label": "Emri",
+       "rcfilters-savedqueries-new-name-placeholder": "Shpjego qëllimin e filtrit",
        "rcfilters-savedqueries-apply-label": "Krijo filtër",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Krijo filtrin e parazgjedhur",
        "rcfilters-savedqueries-cancel-label": "Anulo",
        "rcfilters-savedqueries-add-new-title": "Ruaj rregullimet e tanishme të filtrit",
+       "rcfilters-savedqueries-already-saved": "Këta filtër veç janë ruajtur. Ndrysho konfigurimet për të krijuar një Filtër të Ruajtur.",
        "rcfilters-restore-default-filters": "Kthej filtrat e parazgjedhur",
        "rcfilters-clear-all-filters": "Pastro të gjithë filtrat",
-       "rcfilters-search-placeholder": "Filtro ndryshimet e fundit (shfleto ose fillo të shtypësh)",
+       "rcfilters-show-new-changes": "Shih ndryshimet e fundit",
+       "rcfilters-search-placeholder": "Filtro ndryshimet (përdor menynë ose emrin e filtrit)",
        "rcfilters-invalid-filter": "Filtër jo i vlefshëm",
        "rcfilters-empty-filter": "S'ka filtra aktiv. Tregohen të gjitha kontributet.",
        "rcfilters-filterlist-title": "Filtrat",
        "rcfilters-filter-user-experience-level-newcomer-label": "Të rinjtë",
        "rcfilters-filter-user-experience-level-newcomer-description": "Më pak se 10 redaktime dhe 4 ditë aktivitet.",
        "rcfilters-filter-user-experience-level-learner-label": "Nxënës",
+       "rcfilters-filter-user-experience-level-learner-description": "Redaktorët e regjistruar përvoja e të cilëve bie në mes \"Të rinjve dhe \"Përdoruesve me përvojë.\"",
        "rcfilters-filter-user-experience-level-experienced-label": "Përdorues me përvojë",
-       "rcfilters-filter-user-experience-level-experienced-description": "Më shumë se 30 ditë aktivitete dhe 500 editime.",
+       "rcfilters-filter-user-experience-level-experienced-description": "Redaktorët e regjistruar me më shumë se 500 redaktiv dhe 30 ditë aktivitet.",
        "rcfilters-filtergroup-automated": "Kontribute automatike",
        "rcfilters-filter-bots-label": "Bot",
        "rcfilters-filter-bots-description": "Redaktime të bëra nga vegla automatike.",
        "rcfilters-filter-watchlist-watchednew-description": "Ndryshimet në faqet e Mbikëqyrura që nuk keni vizituar që nga ndodhja e ndryshimeve.",
        "rcfilters-filter-watchlist-notwatched-label": "Jo në Listën e Mbikëqyrjes",
        "rcfilters-filter-watchlist-notwatched-description": "Çdo gjë përveç ndryshimeve në faqet në Listën e Mbikëqyrjes.",
+       "rcfilters-filtergroup-watchlistactivity": "Aktiviteti i listës së mbikqyrjes",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Ndryshimet e papara",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Ndryshimet në faqet që nuk i keni vizituar që nga ndodhja e ndryshimeve.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Ndryshimet e para",
+       "rcfilters-filter-watchlistactivity-seen-description": "Ndryshimet në faqet që keni vizituar që nga ndodhja e ndryshimeve.",
        "rcfilters-filtergroup-changetype": "Lloji i ndryshimit",
        "rcfilters-filter-pageedits-label": "Redaktimet e faqes",
        "rcfilters-filter-pageedits-description": "Redaktimet e përmbajtjes wiki, diskutimeve, përshkrimit të kategorive...",
        "rcfilters-filter-lastrevision-label": "Versioni më i fundit",
        "rcfilters-filter-lastrevision-description": "Vetëm dryshimet më të fundit në një faqe.",
        "rcfilters-filter-previousrevision-label": "Jo rishimet e fundit",
-       "rcfilters-filter-previousrevision-description": "Të gjitha ndryshimet që nuk janë ndryshimet më të fundit në një faqe.",
+       "rcfilters-filter-previousrevision-description": "Të gjitha ndryshimet që nuk janë \"ndryshimet më të fundit\".",
        "rcfilters-filter-excluded": "Përjashtuar",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:jo</strong> $1",
+       "rcfilters-exclude-button-off": "Përjashto të zgjedhurat",
+       "rcfilters-exclude-button-on": "Po përjashtohen të zgjedhurat",
        "rcfilters-view-tags": "Redaktimet e etiketuara",
        "rcfilters-view-namespaces-tooltip": "Filtro rezultatet sipas hapësirës",
        "rcfilters-view-tags-tooltip": "Filtro rezultatet duke përdorur etiketat e redaktimit",
        "rcfilters-view-return-to-default-tooltip": "Kthehu te menyja kryesore e filtrave",
+       "rcfilters-view-tags-help-icon-tooltip": "Mëso më shumë për redaktimet me etiketë",
        "rcfilters-liveupdates-button": "Freskimet drejtpërdrejtë",
+       "rcfilters-liveupdates-button-title-on": "Ndal freskimet live",
+       "rcfilters-liveupdates-button-title-off": "Shfaq ndryshimet e fundit duke ndodhur",
+       "rcfilters-watchlist-markseen-button": "Shenjo të gjitha ndryshimet si të para",
+       "rcfilters-watchlist-edit-watchlist-button": "Redakto listën tuaj të faqeve të mbikëqyrura",
+       "rcfilters-preference-label": "Fshih versionin e përmirësuar të Ndryshimeve të Fundit",
+       "rcfilters-target-page-placeholder": "Shto një emër faqeje (ose kategorie)",
        "rcnotefrom": "Më poshtë {{PLURAL:$5|është shfaqur ndryshimi|janë shfaqur ndryshimet}} që nga <strong>$3, $4</strong> (deri në <strong>$1</strong>).",
        "rclistfromreset": "Anulo përzgjedhjen e datës",
        "rclistfrom": "Tregon ndryshime së fundmi duke filluar nga $3 $2",
        "uploadstash-badtoken": "Kryerja e këtij veprimi ishte e pasuksesshme, ndoshta sepse kredencialet e tua redaktuese kanë skaduar. Provoni përsëri.",
        "uploadstash-errclear": "Spastrimi i skedave ishte i pasuksesshëm.",
        "uploadstash-refresh": "Rifreskoni listën e skedave",
+       "uploadstash-bad-path": "Shtegu nuk ekziston.",
+       "uploadstash-bad-path-invalid": "Shtegu nuk është në rregull.",
+       "uploadstash-bad-path-unknown-type": "Veprim i panjohur \"$1\".",
+       "uploadstash-zero-length": "Skedari ka madhësinë zero.",
        "invalid-chunk-offset": "Kompensim cope i pavlefshëm",
        "img-auth-accessdenied": "Refuzohet hyrja",
        "img-auth-nopathinfo": "Mungon PATH_INFO.\nShërbyesi juaj nuk e kalon këtë informacion.\nMund të jetë CGI-bazuar dhe nuk mund të mbështesë img_auth.\nShiko https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "listfiles-delete": "fshije",
        "listfiles-summary": "Kjo faqe e veçantë tregon tërë skedat e ngarkuara.",
        "listfiles_search_for": "Kërko për emrin e figurës:",
+       "listfiles-userdoesnotexist": "Llogaria e përdoruesit \"$1\" nuk është e regjistruar.",
        "imgfile": "skeda",
        "listfiles": "Lista e figurave",
        "listfiles_thumb": "Parapamje",
        "listfiles_size": "Madhësia (bytes)",
        "listfiles_description": "Përshkrimi",
        "listfiles_count": "Versionet",
+       "listfiles-show-all": "Përfshijë versionet e fundit të skedarëve",
        "listfiles-latestversion": "Versioni aktual",
        "listfiles-latestversion-yes": "Po",
        "listfiles-latestversion-no": "Jo",
        "activeusers-intro": "Kjo është një listë e përdoruesve që kanë qenë aktivë për $1 {{PLURAL:$1|ditë|ditë}}.",
        "activeusers-count": "$1 {{PLURAL:$1|veprim|veprime}} në {{PLURAL:$3|ditën|$3 ditët}} e fundit",
        "activeusers-from": "Trego përdoruesit duke filluar prej te:",
+       "activeusers-groups": "Shfaq përdoruesit që u përkasin grupeve:",
+       "activeusers-excludegroups": "Përjashto përdoruesit që u përkasin grupeve:",
        "activeusers-noresult": "Asnjë përdorues nuk u gjet.",
        "activeusers-submit": "Shfaq përdoruesit aktiv",
        "listgrouprights": "Grupime përdoruesish me privilegje",
        "trackingcategories-name": "Emri i porosisë",
        "trackingcategories-desc": "Kriteret për përfshirje në kategori",
        "restricted-displaytitle-ignored": "Faqet me tituj të shfaqur të injoruar",
+       "trackingcategories-nodesc": "Nuk ka përshkrim.",
        "trackingcategories-disabled": "Kategoria është pamundësuar",
        "mailnologin": "S'ka adresë dërgimi",
        "mailnologintext": "Duhet të keni [[Special:UserLogin|hyrë brenda]] dhe të keni një adresë të saktë në [[Special:Preferences|parapëlqimet]] tuaja për tu dërguar email përdoruesve të tjerë.",
        "ipb_blocked_as_range": "Gabim: Adresa IP $1 nuk është bllokuar direkt dhe nuk mund të zhbllokohet.\nAjo është, megjithatë, e bllokuar si pjesë e rangut $2, që nuk mund të zhbllokohet.",
        "ip_range_invalid": "Shtrirje IP gabim.",
        "ip_range_toolarge": "Radhitja e bllokimeve më të mëdha se /$1 nuk lejohet.",
+       "ip_range_toolow": "Vargjet e IP efektivisht nuk lejohen.",
        "proxyblocker": "Bllokuesi i ndërmjetëseve",
        "proxyblockreason": "IP adresa juaj është bllokuar sepse është një ndërmjetëse e hapur. Ju lutem lidhuni me kompaninë e shërbimeve të Internetit që përdorni dhe i informoni për këtë problem sigurije.",
        "sorbsreason": "Adresa IP e juaj është radhitur si ndërmjetëse e hapur tek lista DNSBL.",
        "tag-filter-submit": "Filtër",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etiketa|Etiketat}}]]: $2)",
        "tag-mw-contentmodelchange": "ndryshimi i modelit të përmbajtjes",
+       "tag-mw-new-redirect": "Ridrejtim i ri",
+       "tag-mw-new-redirect-description": "Ndryshimet që krijojnë një ridrejtim të ri ose ndryshojnë faqen në ridrejtim",
+       "tag-mw-removed-redirect": "Hoqi ridrejtimin",
+       "tag-mw-changed-redirect-target": "Caku i ridrejtimit i ndryshuar",
+       "tag-mw-changed-redirect-target-description": "Redaktimet që kanë ndryshuar cakun e një ridrejtimi",
+       "tag-mw-blank": "Duke zbrazur",
+       "tag-mw-blank-description": "Redaktimet që zbrazin një faqe",
+       "tag-mw-replace": "Zëvendësuar",
        "tags-title": "Etiketat",
        "tags-intro": "Kjo faqe liston etiketat që softueri mund t'i shënojë me një redaktim, dhe kuptimin e tyre.",
        "tags-tag": "Emri i etiketës",
index 87e963b..3178f61 100644 (file)
        "toc": "Садржај",
        "showtoc": "прикажи",
        "hidetoc": "сакриј",
-       "collapsible-collapse": "СкÑ\83пи",
-       "collapsible-expand": "Ð\9fÑ\80оÑ\88иÑ\80и",
+       "collapsible-collapse": "СакÑ\80иÑ\98",
+       "collapsible-expand": "Ð\9fÑ\80икажи",
        "confirmable-confirm": "Да ли {{GENDER:$1|сте}} сигурни?",
        "confirmable-yes": "Да",
        "confirmable-no": "Не",
        "throttled-mailpassword": "Порука за промену лозинке је послата у {{PLURAL:$1|1=последњих сат времена|последња $1 сата|последњих $1 сати}}.\nДа бисмо спречили злоупотребу, подсетник шаљемо само једном у року од {{PLURAL:$1|1=сат времена|$1 сата|$1 сати}}.",
        "mailerror": "Грешка при слању поруке: $1",
        "acct_creation_throttle_hit": "Посетиоци овог викија који користе вашу IP адресу су већ отворили {{PLURAL:$1|1=један налог|$1 налога}} претходни $2, што је највећи дозвољени број у том временском периоду.\nЗбог тога посетиоци с ове IP адресе тренутно не могу отворити више налога.",
-       "emailauthenticated": "Ваша имејл адреса је потврђена $2 у $3.",
+       "emailauthenticated": "Ваша имејл адреса је потврђена на дан $2 у $3.",
        "emailnotauthenticated": "Ваша имејл адреса још увек није потврђена.\nИмејл неће бити послат ни у једном од следећих случајева.",
        "noemailprefs": "Унесите имејл адресу како би ове могућности радиле.",
        "emailconfirmlink": "Потврдите своју имејл адресу",
        "expansion-depth-exceeded-category-desc": "Страница је прекорачила највећу дубину проширења.",
        "expansion-depth-exceeded-warning": "Страница у којој је прекорачена дубина проширења",
        "parser-unstrip-loop-warning": "Утврђена је петља",
-       "parser-unstrip-recursion-limit": "Прекорачено је ограничење рекурзије ($1)",
+       "unstrip-depth-warning": "Прекорачено је ограничење рекурзије ($1)",
        "converter-manual-rule-error": "Пронађена је грешка у правилу за ручно претварање језика",
        "undo-success": "Измена се може поништити.\nПроверите разлике испод, па сачувајте измене.",
        "undo-failure": "Ова измена се не може поништити због сукоба измена.",
        "prefs-edits": "Број измена:",
        "prefsnologintext2": "Морате бити пријављени да бисте мењали своја подешавања.",
        "prefs-skin": "Тема",
-       "skin-preview": "Ð\9fрегледај",
+       "skin-preview": "прегледај",
        "datedefault": "Свеједно",
        "prefs-labs": "Пробне могућности",
        "prefs-user-pages": "Корисничке странице",
        "prefs-watchlist": "Списак надгледања",
        "prefs-editwatchlist": "Уређивање списка надгледања",
        "prefs-editwatchlist-label": "Уређивање списка:",
-       "prefs-editwatchlist-edit": "Уреди списак",
-       "prefs-editwatchlist-raw": "Уреди сиров списак",
-       "prefs-editwatchlist-clear": "Ð\98спразни списак",
+       "prefs-editwatchlist-edit": "уреди списак",
+       "prefs-editwatchlist-raw": "уреди сиров списак",
+       "prefs-editwatchlist-clear": "испразни списак",
        "prefs-watchlist-days": "Број дана у списку надгледања:",
        "prefs-watchlist-days-max": "Највише $1 {{PLURAL:$1|дан|дана|дана}}",
        "prefs-watchlist-edits": "Највећи број измена приказаних на списку надгледања:",
        "prefs-watchlist-edits-max": "Највећа вредност је хиљаду",
        "prefs-watchlist-token": "Жетон списка надгледања:",
        "prefs-misc": "Друга подешавања",
-       "prefs-resetpass": "Ð\9fромени лозинку",
-       "prefs-changeemail": "Ð\9fромени или уклони имејл адресу",
+       "prefs-resetpass": "промени лозинку",
+       "prefs-changeemail": "промени или уклони имејл адресу",
        "prefs-setemail": "Постави имејл адресу",
        "prefs-email": "Подешавања имејла",
        "prefs-rendering": "Изглед",
        "timezoneregion-pacific": "Тихи океан",
        "allowemail": "Омогући примање имејлова од других корисника",
        "email-allow-new-users-label": "Омогући примање имејлова од новајлија",
-       "email-blacklist-label": "Ð\9eнемогÑ\83Ñ\9bи следећим корисницима да ми шаљу имејлове:",
+       "email-blacklist-label": "Ð\97абÑ\80ани следећим корисницима да ми шаљу имејлове:",
        "prefs-searchoptions": "Претрага",
        "prefs-namespaces": "Именски простори",
        "default": "подразумевана",
        "prefs-files": "Датотеке",
-       "prefs-custom-css": "Ð\9fрилагођени CSS",
-       "prefs-custom-js": "Ð\9fÑ\80илагоÑ\92ени Ñ\98аваскрипт",
+       "prefs-custom-css": "прилагођени CSS",
+       "prefs-custom-js": "пÑ\80илагоÑ\92ени Ð\88аваскрипт",
        "prefs-common-config": "Дељени CSS/Јаваскрипт за све теме:",
        "prefs-reset-intro": "Можете користити ову страницу да поништите своја подешавања на подразумеване вредности.\nОва радња се не може вратити.",
        "prefs-emailconfirm-label": "Потврда имејла:",
        "yourvariant": "Варијанта језика:",
        "prefs-help-variant": "Жељена варијанта или правопис за приказ страница са садржајем овог викија.",
        "yournick": "Нови потпис:",
-       "prefs-help-signature": "Ð\9aоменÑ\82аÑ\80е Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама Ð·Ð° Ñ\80азговоÑ\80 Ð¿Ð¾Ñ\82пиÑ\81Ñ\83Ñ\98Ñ\82е Ñ\81а Ñ\87еÑ\82иÑ\80и Ñ\82илде: <nowiki>~~~~</nowiki>. Ð\9eваÑ\98 Ð²Ð¸ÐºÐ¸Ñ\82екÑ\81Ñ\82 Ñ\9bе Ð±Ð¸Ñ\82и Ð¿Ñ\80еÑ\82воÑ\80ен Ñ\83 Ð\92аÑ\88 Ð¿Ð¾Ñ\82пиÑ\81 Ð¸ Ñ\82Ñ\80енÑ\83Ñ\82но време.",
+       "prefs-help-signature": "Ð\9aоменÑ\82аÑ\80и Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ама Ð·Ð° Ñ\80азговоÑ\80 Ð±Ð¸ Ñ\82Ñ\80ебали Ð±Ð¸Ñ\82и Ð¿Ð¾Ñ\82пиÑ\81ани Ñ\81 â\80\9e<nowiki>~~~~</nowiki>â\80\9c Ñ\88Ñ\82о Ñ\9bе Ð±Ð¸Ñ\82и Ð¿Ñ\80еÑ\82воÑ\80ено Ñ\83 Ð\92аÑ\88 Ð¿Ð¾Ñ\82пиÑ\81 Ð¸ време.",
        "badsig": "Потпис је неисправан.\nПроверите ознаке HTML.",
        "badsiglength": "Ваш потпис је предугачак.\nНе сме бити дужи од $1 {{PLURAL:$1|знака|знака|знакова}}.",
        "yourgender": "Како желите да се представите?",
        "recentchanges-label-newpage": "Нова страница",
        "recentchanges-label-minor": "Мања измена",
        "recentchanges-label-bot": "Ботовска измена",
-       "recentchanges-label-unpatrolled": "Ð\9eва Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\98оÑ\88 Ð½Ð¸Ñ\98е Ð¿Ð°Ñ\82Ñ\80олиÑ\80ана",
+       "recentchanges-label-unpatrolled": "Ð\9dепаÑ\82Ñ\80олиÑ\80ана Ð¸Ð·Ð¼Ðµна",
        "recentchanges-label-plusminus": "Промена величине странице у бајтовима",
        "recentchanges-legend-heading": "<strong>Легенда:</strong>",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|списак нових страница]])",
+       "recentchanges-legend-newpage": "Овом изменом је направљена нова страница ([[Special:NewPages|списак нових страница]])",
        "recentchanges-submit": "Прикажи",
        "rcfilters-tag-remove": "Обриши $1",
        "rcfilters-legend-heading": "<strong>Списак скраћеница:</strong>",
        "rcfilters-view-tags-tooltip": "Филтрирај резултате према ознаци измене",
        "rcfilters-view-return-to-default-tooltip": "Повратак на главни мени",
        "rcfilters-view-tags-help-icon-tooltip": "Сазнајте више о означеним изменама",
-       "rcfilters-liveupdates-button": "Ð\90жÑ\83Ñ\80иÑ\80аÑ\9aа уживо",
+       "rcfilters-liveupdates-button": "Ð\90жÑ\83Ñ\80иÑ\80аÑ\98 уживо",
        "rcfilters-liveupdates-button-title-on": "Искључи ажурирања уживо",
        "rcfilters-liveupdates-button-title-off": "Прикажи нове измене уживо",
        "rcfilters-watchlist-markseen-button": "Означи све измене као виђене",
        "nopagetext": "Тражена страница не постоји.",
        "pager-newer-n": "{{PLURAL:$1|новији 1|новија $1|новијих $1}}",
        "pager-older-n": "{{PLURAL:$1|старији 1|старија $1|старијих $1}}",
-       "suppress": "Ð\98змена",
+       "suppress": "СакÑ\80иÑ\98",
        "querypage-disabled": "Ова посебна страница је онемогућена ради побољшања перформанси.",
        "apihelp": "API помоћ",
        "apihelp-no-such-module": "Модул „$1“ није пронађен.",
        "seconds-abbrev": "$1 с",
        "minutes-abbrev": "$1 м",
        "hours-abbrev": "$1 ч",
-       "days-abbrev": "$1 д",
+       "days-abbrev": "$1 д.",
        "seconds": "{{PLURAL:$1|$1 секунда|$1 секунда|$1 секунди}}",
        "minutes": "{{PLURAL:$1|$1 минут|$1 минута|$1 минута}}",
        "hours": "{{PLURAL:$1|$1 сат|$1 сата|$1 сати}}",
        "confirmrecreate": "{{GENDER:$1|Корисник|Корисница}} [[User:$1|$1]] ([[User talk:$1|разговор]]) је {{GENDER:$1|обрисао|обрисала}} ову страницу након што сте почели да је уређујете из следећег разлога:\n: <em>$2</em>\nПотврдите да стварно желите да направите страницу.",
        "confirmrecreate-noreason": "{{GENDER:$1|Корисник|Корисница}} [[User:$1|$1]] ([[User talk:$1|разговор]]) је {{GENDER:$1|обрисао|обрисала}} ову страницу након што сте почели да је уређујете. Потврдите да стварно желите да поново направите ову страницу.",
        "recreate": "Поново направи",
-       "unit-pixel": "px",
+       "unit-pixel": "п",
        "confirm-purge-title": "Освежи ову страницу",
        "confirm_purge_button": "У реду",
        "confirm-purge-top": "Очистити привремену меморију ове стране?",
index d671adc..d558670 100644 (file)
        "expansion-depth-exceeded-category": "Stranice u kojima je prekoračena dubina proširenja",
        "expansion-depth-exceeded-warning": "Stranica u kojoj je prekoračena dubina proširenja",
        "parser-unstrip-loop-warning": "Utvrđena je petlja",
-       "parser-unstrip-recursion-limit": "Prekoračeno je ograničenje rekurzije ($1)",
+       "unstrip-depth-warning": "Prekoračeno je ograničenje rekurzije ($1)",
        "converter-manual-rule-error": "Pronađena je greška u pravilu za ručno pretvaranje jezika",
        "undo-success": "Izmena se može poništiti.\nProverite razlike ispod, pa sačuvajte izmene.",
        "undo-failure": "Ova izmena se ne može poništiti zbog sukoba izmena.",
index 736a629..1c0efdd 100644 (file)
        "expansion-depth-exceeded-category-desc": "Kacana ngaleuwihan wates jero ékspansina.",
        "expansion-depth-exceeded-warning": "Kaca ngaleuwihan jero ékspansi",
        "parser-unstrip-loop-warning": "Luncatan buni kanyahoan",
-       "parser-unstrip-recursion-limit": "Wates rékursi buni kaleuwihi ($1)",
+       "unstrip-depth-warning": "Wates rékursi buni kaleuwihi ($1)",
        "converter-manual-rule-error": "Kasalahan kanyahoan dina aturan tarjamahan basa manual",
        "undo-success": "Éditan ieu bisa dibolaykeun. Mangga pariksa babandingan di handap pikeun mastikeun mémang anjeun miharep éta parobahan. Mun geus yakin, mangga simpen parobahanana pikeun ngabolaykeun éditan.",
        "undo-failure": "Éditan teu bisa dibolaykeun alatan kaselang ku éditan séjén.",
index 2729c41..bd10207 100644 (file)
        "expansion-depth-exceeded-category-desc": "Sidan har överstridit det maximala expansionsdjupet.",
        "expansion-depth-exceeded-warning": "Sidan överskrider expansionsdjupet",
        "parser-unstrip-loop-warning": "Tagavskalningsloop upptäcktes",
-       "parser-unstrip-recursion-limit": "Tagavskalningsloop överskred rekursionsgränsen ($1)",
+       "unstrip-depth-warning": "Tagavskalningsloop överskred rekursionsgränsen ($1)",
        "converter-manual-rule-error": "Fel upptäcktes i manuell språkkonverteringsregel",
        "undo-success": "Redigeringen kan göras ogjord.\nVar god och kontrollera jämförelsen nedan för att bekräfta att detta är vad du avser att göra, och spara sedan ändringarna nedan för att göra redigeringen ogjord.",
        "undo-failure": "Redigeringen kunde inte göras ogjord på grund av konflikt med mellanliggande redigeringar.",
index 655423a..2213ae6 100644 (file)
        "expansion-depth-exceeded-category-desc": "இந்த பக்கம் அதிகபட்ச விரிவு ஆழத்தைத் தாண்டியது",
        "expansion-depth-exceeded-warning": "விரிவு ஆழம் பக்க வரம்பை மீறிவிட்டது",
        "parser-unstrip-loop-warning": "Unstrip வளையம் காணப்பட்டது",
-       "parser-unstrip-recursion-limit": "Unstrip மீள்தோன்றும் எல்லை மீறப்பட்டது ($1)",
+       "unstrip-depth-warning": "Unstrip மீள்தோன்றும் எல்லை மீறப்பட்டது ($1)",
        "converter-manual-rule-error": "கைமுறை மொழி மாற்றம் விதியில் பிழை கண்டுபிடிக்கப்பட்டது",
        "undo-success": "இத்தொகுப்பை மீளமைக்க முடியும். தயவு செய்து, கீழே காட்டப்பட்டுள்ள ஒப்பீட்டைப் பார்த்து, நீங்கள் செய்ய முயற்சிப்பது இதுதானா? என்பதை உறுதிப்படுத்திக் கொண்டு '''பக்கத்தைச் சேமிக்கவும்''' என்பதன் மேல் சொடுக்கவும்.",
        "undo-failure": "முரண்பாடான இடைப்பட்டத் தொகுப்புகள் காரணமாக இத்தொகுப்பை மீளமைக்க முடியாது.",
index 08a3884..b273a2a 100644 (file)
        "expansion-depth-exceeded-category-desc": "పేజీ గరిష్ఠ విస్తరణ లోతును మించింది",
        "expansion-depth-exceeded-warning": "పేజీ విస్తరణ లోతును మించింది",
        "parser-unstrip-loop-warning": "Unstrip లూపును కనుక్కున్నాం",
-       "parser-unstrip-recursion-limit": "Unstrip రికర్షన్ పరిమితిని దాటింది ($1)",
+       "unstrip-depth-warning": "Unstrip రికర్షన్ పరిమితిని దాటింది ($1)",
        "converter-manual-rule-error": "మానవిక భాషాంతరీకరణ పరికరంలో లోపాన్ని కనుక్కున్నాం",
        "undo-success": "దిద్దుబాటును రద్దు చెయ్యవచ్చు. కింది పోలికను చూసి, మీరు చెయ్యదలచినది ఇదేనని నిర్ధారించుకోండి. ఆ తరువాత మార్పులను భద్రపరచి దిద్దుబాటు రద్దును పూర్తి చెయ్యండి.",
        "undo-failure": "మధ్యలో జరిగిన దిద్దుబాట్లతో తలెత్తిన ఘర్షణ కారణంగా ఈ దిద్దుబాటును రద్దు చెయ్యలేక పోయాం.",
index fac7ea7..cec7470 100644 (file)
        "expansion-depth-exceeded-category": "หน้าที่ความลึกการขยายเกิน",
        "expansion-depth-exceeded-warning": "หน้าเกินความลึกการขยาย",
        "parser-unstrip-loop-warning": "พบวงวน unstrip",
-       "parser-unstrip-recursion-limit": "ขีดจำกัดการเรียกซ้ำ unstrip เกิน ($1)",
+       "unstrip-depth-warning": "ขีดจำกัดการเรียกซ้ำ unstrip เกิน ($1)",
        "converter-manual-rule-error": "พบข้อผิดพลาดในกฎการแปลงผันภาษาด้วยมือ",
        "undo-success": "สามารถย้อนการแก้ไขนี้กลับได้ \nกรุณาตรวจสอบข้อแตกต่างด้านล่างเพื่อทวนสอบว่านี่เป็นสิ่งที่คุณต้องการทำ แล้วบันทึกการเปลี่ยนแปลงด้านล่างเพื่อเสร็จสิ้นการย้อนการแก้ไขกลับ",
        "undo-failure": "การแก้ไขนี้ไม่สามารถย้อนกลับได้ เนื่องจากขัดแย้งกับการแก้ไขระหว่างกลาง",
index bbaa125..f3b6a6b 100644 (file)
        "expansion-depth-exceeded-category": "Mga pahina kung saan lampas ang lalim ng paglawak",
        "expansion-depth-exceeded-warning": "Lumampas ang pahina sa lalim ng paglawak",
        "parser-unstrip-loop-warning": "Napansin ang silo ng hindi pagtalop",
-       "parser-unstrip-recursion-limit": "Nalampasan ang hangganan ng rekursiyon ng hindi pagtalop ($1)",
+       "unstrip-depth-warning": "Nalampasan ang hangganan ng rekursiyon ng hindi pagtalop ($1)",
        "converter-manual-rule-error": "Napansin ang kamalian sa alituntunin ng kinakamay na pagpapalit ng wika",
        "undo-success": "Matatanggal ang pagbabago.\nPakitingnan ang paghahambing sa ibaba para masiyasat kung ito ang ibig mong gawin, at pagkatapos sagipin ang mga pagbabago sa ibaba para matapos ang pagtatanggal ng pagbabago.",
        "undo-failure": "Hindi matanggal ang pagbabago dahil sa magkakasalungat na panggitnang mga pagbabago.",
index bb4834c..8f4008d 100644 (file)
        "expansion-depth-exceeded-category-desc": "Sayfa azami genişleme derinliğini aşıyor.",
        "expansion-depth-exceeded-warning": "Sayfa genişletme derinliği aşıldı",
        "parser-unstrip-loop-warning": "Yineleme döngüsü algılandı",
-       "parser-unstrip-recursion-limit": "($1) yineleme sınırı aşıldı",
+       "unstrip-depth-warning": "($1) yineleme sınırı aşıldı",
        "converter-manual-rule-error": "Elle yapılandırma dil dönüşüm kuralı hatası tespit edildi",
        "undo-success": "Bu değişiklik geri alınabilir. Lütfen aşağıdaki karşılaştırmayı kontrol edin, gerçekten bu değişikliği yapmak istediğinizden emin olun ve sayfayı kaydederek bir önceki değişikliği geriye alın.",
        "undo-failure": "Değişikliklerin çakışması nedeniyle geri alma işlemi başarısız oldu.",
        "rcfilters-filter-categorization-description": "Kategorilere eklenen veya kaldırılan sayfaların kayıtları.",
        "rcfilters-filter-logactions-label": "Günlüğü tutulan işlemler",
        "rcfilters-filter-logactions-description": "Hizmetli işlemleri, hesap oluşturmalar, sayfa silmeler, yüklemeler...",
+       "rcfilters-filter-lastrevision-label": "Son revizyon",
+       "rcfilters-filter-previousrevision-label": "Son revizyon değil",
        "rcfilters-liveupdates-button": "Canlı güncelleme",
        "rcfilters-liveupdates-button-title-on": "Canlı güncellemeyi kapat",
        "rcfilters-liveupdates-button-title-off": "Yeni değişiklikleri yapıldıkları anda görüntüleyin",
index 0a48ddc..2878d7e 100644 (file)
        "expansion-depth-exceeded-category": "كېڭەيتىلگەن چوڭقۇرلۇق بەت چەكلىمىسىدىن ئېشىپ كەتتى",
        "expansion-depth-exceeded-warning": "بەت كېڭەيتىلگەن چوڭقۇرلۇقتىن ئېشىپ كەتتى",
        "parser-unstrip-loop-warning": "دەۋرىيلىك بايقالدى",
-       "parser-unstrip-recursion-limit": "قايتىلانما چەكلىمە ($1) دىن ئېشىپ كەتتى",
+       "unstrip-depth-warning": "قايتىلانما چەكلىمە ($1) دىن ئېشىپ كەتتى",
        "converter-manual-rule-error": "قولدا ئالماشتۇرىدىغان قائىدىدە خاتالىق بايقالدى",
        "undo-success": "بۇ تەھرىردىن يېنىۋالغىلى بولىدۇ\nتۆۋەندىكى سېلىشتۇرۇشنى تەكشۈرۈپ بۇنىڭ ئۆزىڭىزنىڭ ئويى ئىكەنلىكىنى دەلىللەڭ، ئاندىن تۆۋەندىكى ئۆزگەرتىشنى ساقلاپ تەھرىرلەشتىن يېنىۋىلىڭ.",
        "undo-failure": "ئوتتۇرىلىقتا بىردەك بولماسلىق سەۋەبىدىن بۇ تەھرىردىن يېنىۋالغىلى بولمايدۇ.",
index 703fa0d..1f4c2f1 100644 (file)
        "expansion-depth-exceeded-category-desc": "На сторінці перевищено максимально допустима глибину розкриття.",
        "expansion-depth-exceeded-warning": "На сторінці перевищено межу глибини вкладеності",
        "parser-unstrip-loop-warning": "Виявлено незакритий тег (такий, як <pre>)",
-       "parser-unstrip-recursion-limit": "Перевищено межу вкладеної рекурсії ($1) для парсера.",
+       "unstrip-depth-warning": "Перевищено межу вкладеної рекурсії ($1) для парсера.",
        "converter-manual-rule-error": "Помилка в ручному правилі перетворення мови",
        "undo-success": "Редагування може бути скасовано.\nБудь ласка, перевірте порівняння нижче, щоб впевнитись, що це те, що ви хочете зробити, а потім збережіть зміни, щоб закінчити скасування редагування.",
        "undo-failure": "Неможливо скасувати редагування через несумісність проміжних змін.",
index d10cba2..cc9e535 100644 (file)
        "expansion-depth-exceeded-category-desc": "اس صفحہ میں توسیع کی گہرائی اپنی حد سے تجاوز کر گئی۔",
        "expansion-depth-exceeded-warning": "صفحہ میں توسیع کی گہرائی اپنی حد سے تجاوز کر گئی",
        "parser-unstrip-loop-warning": "unstrip فنکشن میں تکرار پایا گیا",
-       "parser-unstrip-recursion-limit": "unstrip فنکشن میں تکرار اپنی حد سے تجاوز کر گیا ($1)",
+       "unstrip-depth-warning": "unstrip فنکشن میں تکرار اپنی حد سے تجاوز کر گیا ($1)",
        "converter-manual-rule-error": "زبان کی دستی تبدیلی کے ضوابط میں نقص دریافت ہوا",
        "undo-success": "اس ترمیم کو واپس پھیرا جا سکتا ہے۔\nبراہ کرم ذیل میں موجود موازنہ ملاحظہ فرمائیں اور یقین کر لیں کہ اس موازنے میں موجود فرق ہی آپ کا مقصود ہے۔ اس کے بعد تبدیلیوں کو محفوظ کر دیں، ترمیم واپس پھیر دی جائے گی۔",
        "undo-failure": "درمیان میں متنازع ترامیم کی موجودگی کی بنا پر اس ترمیم کو واپس نہیں پھیرا جا سکا۔",
index f18227e..5c6403f 100644 (file)
        "expansion-depth-exceeded-category": "Pajine ndove che vien superà ła profondità de espansion",
        "expansion-depth-exceeded-warning": "Sta pajina ga superà el limite de profondità de espansion",
        "parser-unstrip-loop-warning": "Xe sta riłevà un ciclo de Unstrip",
-       "parser-unstrip-recursion-limit": "Superadi i limiti de recursion de Unstrip ($1)",
+       "unstrip-depth-warning": "Superadi i limiti de recursion de Unstrip ($1)",
        "converter-manual-rule-error": "Rilevà eror inte ła regoła manuałe de conversion de ła lèngua",
        "undo-success": "Sta modifica la pode èssar anulà. Verifica el confronto presentà de seguito par èssar sicuro che el contenuto el sia come te lo voli e quindi salva le modifiche par conpletar la procedura de anulamento.",
        "undo-failure": "No se pol mìa anular la modifica, par via de un conflito con modifiche intermedie.",
index bb064d8..04ba719 100644 (file)
        "expansion-depth-exceeded-category-desc": "Trang có độ sâu bung bản mẫu vượt quá giới hạn cho phép.",
        "expansion-depth-exceeded-warning": "Trang bung bản mẫu sâu quá",
        "parser-unstrip-loop-warning": "Vòng lặp unstrip",
-       "parser-unstrip-recursion-limit": "Đã vượt quá giới hạn về độ sâu đệ quy unstrip ($1)",
+       "unstrip-depth-warning": "Đã vượt quá giới hạn về độ sâu đệ quy unstrip ($1)",
        "converter-manual-rule-error": "Lỗi được phát hiện trong quy tắc chuyển đổi ngôn ngữ thủ công",
        "undo-success": "Các sửa đổi có thể được lùi lại. Xin hãy kiểm tra phần so sánh bên dưới để xác nhận lại những gì bạn muốn làm, sau đó lưu thay đổi ở dưới để hoàn tất việc lùi lại sửa đổi.",
        "undo-failure": "Sửa đổi không thể phục hồi vì đã có những sửa đổi mới ở sau.",
index 501d375..946da53 100644 (file)
        "viewsource-title": "Côde sourdant di «$1»",
        "viewsourcetext": "Loukîz li contnou d' l’ årtike, et s’ li rcopyî si vos vloz, por vos bouter dsu foû des fyis:",
        "protectedinterface": "Cisse pådje ci dene on tecse d' eterface pol programe, eyet elle a stî protedjeye po s' waeranti siconte des abus.",
-       "editinginterface": "<stron>Asteme:</strong> Vos estoz ki candje ene pådje eployeye po fé l' tecse po l' eterface do programe.\nLes candjmints ki vos frîz vont candjî l' rivnance di l' eterface po ls ôtes uzeus do wiki.",
+       "editinginterface": "<strong>Asteme:</strong> Vos estoz ki candje ene pådje eployeye po fé l' tecse po l' eterface do programe.\nLes candjmints ki vos frîz vont candjî l' rivnance di l' eterface po ls ôtes uzeus do wiki.",
        "cascadeprotected": "Cisse pådje ci a stî protedjeye siconte des candjmints, pask' ele est eploye ådvins {{PLURAL:$1|del pådje shuvante k' est protedjeye|des pådjes shuvantes ki sont protedjeyes}} avou l' tchuze «e cascåde» en alaedje:\n$2",
        "logouttext": "<strong>Vos vs avoz dislodjî.</strong>\n\nNotez ki des pådjes k' i gn a si pôrént continouwer a vey come si vos estîz elodjî, disk' a tant ki vos vudrîz l' muchete di vosse betchteu waibe.",
        "welcomeuser": "Bénvnowe, $1!",
index a7f8844..3e1f16e 100644 (file)
        "parser-template-recursion-depth-warning": "模板递归深度超限($1)",
        "language-converter-depth-warning": "字词转换器深度超限($1)",
        "node-count-exceeded-category": "页面个节点数超出限制",
-       "parser-unstrip-recursion-limit": "递归超过限制 ($1)",
+       "unstrip-depth-warning": "递归超过限制 ($1)",
        "converter-manual-rule-error": "来手动语言转换规则当中查着错误",
        "undo-success": "箇只编辑可以撤销。请检查下头个比较,确定侬确实想撤销,再保存下底个更改完成撤销编辑。",
        "undo-failure": "由于相互冲突个中途编辑,箇只编辑弗好撤销。",
index b296c6c..82ae04e 100644 (file)
        "expansion-depth-exceeded-category-desc": "გვერდს აქვს გადაჭარბებული გაღების სიღრმის მაქსიმალურად დასაშვები რაოდენობა",
        "expansion-depth-exceeded-warning": "გვერდზე გადამეტებულია ჩადგმების ზღვარი",
        "parser-unstrip-loop-warning": "აღმოჩენილია ციკლური ბმული",
-       "parser-unstrip-recursion-limit": "გადამეტებულია რეკურსიის ზღვარი ($1)",
+       "unstrip-depth-warning": "გადამეტებულია რეკურსიის ზღვარი ($1)",
        "converter-manual-rule-error": "შეცდომა ენის ხელით გარდაქმნის წესში",
        "undo-success": "რედაქტირების გაუქმება შესაძლებელია. გთხოვთ შეამოწმოთ განსხვავება ქვევით, რათა დარწმუნდეთ, რომ ეს ის არის რაც თქვენ გსურთ, შემდეგ კი შეინახეთ ცვლილებები რათა დაასრულოთ რედაქტირების გაუქმება.",
        "undo-failure": "რედაქტირების გაუქმება შეუძლებელია კონფლიქტური შუალედური რედაქტირებების გამო.",
index 7dc88b6..8ab39e7 100644 (file)
        "expansion-depth-exceeded-category": "Àwọn ojúewé tí ìjìn ìfẹ̀lọ wọn ju bóṣeyẹ lọ",
        "expansion-depth-exceeded-warning": "Ojúewé ní ìjìn ìfẹ̀lọ tó ju bóṣeyẹ lọ",
        "parser-unstrip-loop-warning": "Ìyípo unstrip ti jẹ́ fínfín",
-       "parser-unstrip-recursion-limit": "Ó ti kọjá àlà ìlọ́po unstrip ($1)",
+       "unstrip-depth-warning": "Ó ti kọjá àlà ìlọ́po unstrip ($1)",
        "converter-manual-rule-error": "Àṣìṣe ti jẹ́ fínfín nínú ìlànà ìyípadà èdè àfọwọ́dá",
        "undo-success": "Àtúnṣe náà ṣe é múkúrò.\nẸ jọ̀wọ́ ẹ wo ìfiwéra ìsàlẹ̀ láti rídájú pé ohun tí ẹ fẹ́ nì yẹn, nígbà náà ẹ mú àwọn àtúnṣe náà pamọ́ láti parí ìmúkúrò àtúnṣe.",
        "undo-failure": "Àtúnṣe náà kò ṣe é múkúrò nítorí títakora àwọn àtúnṣe inú àrin.",
index 0201c42..77becb9 100644 (file)
        "expansion-depth-exceeded-category-desc": "版面超出咗量大展開深度。",
        "expansion-depth-exceeded-warning": "版面超出咗展開深度",
        "parser-unstrip-loop-warning": "偵測到 Unstrip 迴圈",
-       "parser-unstrip-recursion-limit": "Unstrip 迴圈超出咗限制 ($1)",
+       "unstrip-depth-warning": "Unstrip 迴圈超出咗限制 ($1)",
        "converter-manual-rule-error": "手動語言轉換規則入面偵測到出錯",
        "undo-success": "呢個編輯可以取消。請檢查一下個差異去確認呢個係你要去做嘅,跟住儲存下面嘅更改去完成編輯。",
        "undo-failure": "呢個編輯唔能夠取消,由於同途中嘅編輯有衝突。",
index 96b9d91..4777ebe 100644 (file)
        "expansion-depth-exceeded-category-desc": "页面超出最大展开深度限制。",
        "expansion-depth-exceeded-warning": "页面超出展开深度限制",
        "parser-unstrip-loop-warning": "检测到Unstrip循环",
-       "parser-unstrip-recursion-limit": "已超出Unstrip递归限制($1)",
+       "unstrip-depth-warning": "已超出Unstrip递归限制($1)",
        "converter-manual-rule-error": "在手动语言转换规则中检测到错误",
        "undo-success": "该编辑可以被撤销。请检查下面的对比以核实您想要撤销的内容,然后保存下面的更改以完成撤销。",
        "undo-failure": "因存在冲突的中间编辑,本编辑不能撤销。",
        "sunday-at": "周日$1",
        "yesterday-at": "昨天$1",
        "bad_image_list": "格式如下:\n\n仅列表项目(以*开头的行)有效。每行的第一个链接必须是至错误文件的链接。同一行任何后续链接均被视为例外,即嵌入该文件的页面。",
-       "variantname-zh-hans": "简体",
-       "variantname-zh-hant": "繁体",
+       "variantname-zh-hans": "简体中文",
+       "variantname-zh-hant": "繁体中文",
        "variantname-zh-cn": "大陆简体",
        "variantname-zh-tw": "台湾正体",
        "variantname-zh-hk": "香港繁体",
index 340d5c2..2680fd4 100644 (file)
        "categorypage": "檢視分類頁面",
        "viewtalkpage": "檢視討論頁面",
        "otherlanguages": "其他語言",
-       "redirectedfrom": "(已重新導向自 $1)",
+       "redirectedfrom": "(重新導向自 $1)",
        "redirectpagesub": "重新導向頁面",
        "redirectto": "重新導向至:",
        "lastmodifiedat": "此頁面最後編輯於 $1 $2。",
        "pool-errorunknown": "不明錯誤",
        "pool-servererror": "無法使用程序計數服務 ($1)。",
        "poolcounter-usage-error": "用法錯誤:$1",
-       "aboutsite": "關於{{SITENAME}}",
+       "aboutsite": "關於 {{SITENAME}}",
        "aboutpage": "Project:關於",
        "copyright": "除非另有註明,否則所有內容皆以 $1 條款授權。",
        "copyrightpage": "{{ns:project}}:版權",
        "site-atom-feed": "$1 的 Atom 來源",
        "page-rss-feed": "\"$1\" 的 RSS 來源",
        "page-atom-feed": "\"$1\" 的 Atom 來源",
-       "red-link-title": "$1(頁面不存在)",
+       "red-link-title": "$1 (頁面不存在)",
        "sort-descending": "降冪排序",
        "sort-ascending": "昇冪排序",
        "nstab-main": "頁面",
        "expansion-depth-exceeded-category-desc": "超出展開深度限制的頁面。",
        "expansion-depth-exceeded-warning": "頁面超出展開深度限制",
        "parser-unstrip-loop-warning": "偵測到 Unstrip 迴圈",
-       "parser-unstrip-recursion-limit": "Unstrip 遞迴超出限制 ($1)",
+       "unstrip-depth-warning": "Unstrip 遞迴超出限制 ($1)",
        "converter-manual-rule-error": "手動語言轉換規則時偵測到錯誤",
        "undo-success": "此編輯可以被還原。\n請檢查以下比較表,確認您是否要還原,然後儲存以下變更以完成編輯還原。",
        "undo-failure": "由於編輯的修訂間有衝突,此編輯不能還原。",
        "sunday-at": "週日在 $1",
        "yesterday-at": "昨天於 $1",
        "bad_image_list": "請依照下列格式:\n\n僅清單項目有效 (以 * 開頭)。每一行的第一個連結必須是不良檔案的連結。同一行除第一個以外的連結會被視作例外清單,即檔案所在的頁面。",
-       "variantname-zh-hans": "‪简体中文",
+       "variantname-zh-hans": "簡體中文",
        "variantname-zh-hant": "‪繁體中文",
        "variantname-zh-cn": "大陸簡體",
-       "variantname-zh-tw": "灣正體",
+       "variantname-zh-tw": "灣正體",
        "variantname-zh-hk": "香港繁體",
        "variantname-zh-mo": "澳門繁體",
        "variantname-zh-sg": "新加坡簡體",
-       "variantname-zh-my": "马æ\9d¥è¥¿äº\9aç®\80ä½\93",
+       "variantname-zh-my": "馬ä¾\86西äº\9eç°¡é«\94",
        "variantname-zh": "不轉換",
        "variantname-gan-hans": "贛語 (簡體)",
        "variantname-gan-hant": "贛語 (繁體)",
index 13362e0..bcf7023 100644 (file)
@@ -132,13 +132,13 @@ EOT;
         */
        function sync( $srcTable, $dstTable ) {
                $batchSize = 1000;
-               $minTs = $this->dbw->selectField( $srcTable, 'MIN(log_timestamp)', false, __METHOD__ );
+               $minTs = $this->dbw->selectField( $srcTable, 'MIN(log_timestamp)', '', __METHOD__ );
                $minTsUnix = wfTimestamp( TS_UNIX, $minTs );
                $numRowsCopied = 0;
 
                while ( true ) {
-                       $maxTs = $this->dbw->selectField( $srcTable, 'MAX(log_timestamp)', false, __METHOD__ );
-                       $copyPos = $this->dbw->selectField( $dstTable, 'MAX(log_timestamp)', false, __METHOD__ );
+                       $maxTs = $this->dbw->selectField( $srcTable, 'MAX(log_timestamp)', '', __METHOD__ );
+                       $copyPos = $this->dbw->selectField( $dstTable, 'MAX(log_timestamp)', '', __METHOD__ );
                        $maxTsUnix = wfTimestamp( TS_UNIX, $maxTs );
                        $copyPosUnix = wfTimestamp( TS_UNIX, $copyPos );
 
index 2e1f7c9..8579f0f 100644 (file)
@@ -38,7 +38,7 @@ class ClearInterwikiCache extends Maintenance {
        public function execute() {
                global $wgLocalDatabases, $wgMemc;
                $dbr = $this->getDB( DB_REPLICA );
-               $res = $dbr->select( 'interwiki', [ 'iw_prefix' ], false );
+               $res = $dbr->select( 'interwiki', [ 'iw_prefix' ], '', __METHOD__ );
                $prefixes = [];
                foreach ( $res as $row ) {
                        $prefixes[] = $row->iw_prefix;
index 5b144fc..edd5dda 100644 (file)
@@ -55,7 +55,7 @@ class MigrateActors extends LoggedUpdateMaintenance {
                $this->output( "Creating actor entries for all registered users\n" );
                $end = 0;
                $dbw = $this->getDB( DB_MASTER );
-               $max = $dbw->selectField( 'user', 'MAX(user_id)', false, __METHOD__ );
+               $max = $dbw->selectField( 'user', 'MAX(user_id)', '', __METHOD__ );
                $count = 0;
                while ( $end < $max ) {
                        $start = $end + 1;
index 23144e9..e2fd8b5 100644 (file)
@@ -52,13 +52,13 @@ class PopulateBacklinkNamespace extends LoggedUpdateMaintenance {
 
                $start = $this->getOption( 'lastUpdatedId' );
                if ( !$start ) {
-                       $start = $db->selectField( 'page', 'MIN(page_id)', false, __METHOD__ );
+                       $start = $db->selectField( 'page', 'MIN(page_id)', '', __METHOD__ );
                }
                if ( !$start ) {
                        $this->output( "Nothing to do." );
                        return false;
                }
-               $end = $db->selectField( 'page', 'MAX(page_id)', false, __METHOD__ );
+               $end = $db->selectField( 'page', 'MAX(page_id)', '', __METHOD__ );
                $batchSize = $this->getBatchSize();
 
                # Do remaining chunk
index 7c094be..ef57640 100644 (file)
@@ -56,7 +56,7 @@ class PopulateFilearchiveSha1 extends LoggedUpdateMaintenance {
                }
 
                $this->output( "Populating fa_sha1 field from fa_storage_key\n" );
-               $endId = $dbw->selectField( $table, 'MAX(fa_id)', false, __METHOD__ );
+               $endId = $dbw->selectField( $table, 'MAX(fa_id)', '', __METHOD__ );
 
                $batchSize = $this->getBatchSize();
                $done = 0;
index 7bb1605..6e88dfa 100644 (file)
@@ -75,7 +75,7 @@ TEXT
                $start = $this->getOption( 'rev-id', 0 );
                $end = $maxRevId > 0
                        ? $maxRevId
-                       : $dbw->selectField( 'revision', 'MAX(rev_id)', false, __METHOD__ );
+                       : $dbw->selectField( 'revision', 'MAX(rev_id)', '', __METHOD__ );
 
                if ( empty( $end ) ) {
                        $this->output( "No revisions found, aborting.\n" );
index 332d7c5..589be48 100644 (file)
@@ -62,13 +62,13 @@ class PopulateLogSearch extends LoggedUpdateMaintenance {
 
                        return false;
                }
-               $start = $db->selectField( 'logging', 'MIN(log_id)', false, __FUNCTION__ );
+               $start = $db->selectField( 'logging', 'MIN(log_id)', '', __FUNCTION__ );
                if ( !$start ) {
                        $this->output( "Nothing to do.\n" );
 
                        return true;
                }
-               $end = $db->selectField( 'logging', 'MAX(log_id)', false, __FUNCTION__ );
+               $end = $db->selectField( 'logging', 'MAX(log_id)', '', __FUNCTION__ );
 
                # Do remaining chunk
                $end += $batchSize - 1;
index cacd067..3c0bba9 100644 (file)
@@ -50,13 +50,13 @@ class PopulateLogUsertext extends LoggedUpdateMaintenance {
        protected function doDBUpdates() {
                $batchSize = $this->getBatchSize();
                $db = $this->getDB( DB_MASTER );
-               $start = $db->selectField( 'logging', 'MIN(log_id)', false, __METHOD__ );
+               $start = $db->selectField( 'logging', 'MIN(log_id)', '', __METHOD__ );
                if ( !$start ) {
                        $this->output( "Nothing to do.\n" );
 
                        return true;
                }
-               $end = $db->selectField( 'logging', 'MAX(log_id)', false, __METHOD__ );
+               $end = $db->selectField( 'logging', 'MAX(log_id)', '', __METHOD__ );
 
                // If this is being run during an upgrade from 1.16 or earlier, this
                // will be run before the actor table change and should continue. But
index 39bc733..2ef58b7 100644 (file)
@@ -54,8 +54,8 @@ class PopulateParentId extends LoggedUpdateMaintenance {
                        return false;
                }
                $this->output( "Populating rev_parent_id column\n" );
-               $start = $db->selectField( 'revision', 'MIN(rev_id)', false, __FUNCTION__ );
-               $end = $db->selectField( 'revision', 'MAX(rev_id)', false, __FUNCTION__ );
+               $start = $db->selectField( 'revision', 'MIN(rev_id)', '', __FUNCTION__ );
+               $end = $db->selectField( 'revision', 'MAX(rev_id)', '', __FUNCTION__ );
                if ( is_null( $start ) || is_null( $end ) ) {
                        $this->output( "...revision table seems to be empty, nothing to do.\n" );
 
index 4ac3486..8a56d7d 100644 (file)
@@ -46,13 +46,13 @@ class PopulateRecentChangesSource extends LoggedUpdateMaintenance {
                        $this->error( 'rc_source field in recentchanges table does not exist.' );
                }
 
-               $start = $dbw->selectField( 'recentchanges', 'MIN(rc_id)', false, __METHOD__ );
+               $start = $dbw->selectField( 'recentchanges', 'MIN(rc_id)', '', __METHOD__ );
                if ( !$start ) {
                        $this->output( "Nothing to do.\n" );
 
                        return true;
                }
-               $end = $dbw->selectField( 'recentchanges', 'MAX(rc_id)', false, __METHOD__ );
+               $end = $dbw->selectField( 'recentchanges', 'MAX(rc_id)', '', __METHOD__ );
                $end += $batchSize - 1;
                $blockStart = $start;
                $blockEnd = $start + $batchSize - 1;
index bcc4999..8895c9f 100644 (file)
@@ -76,8 +76,8 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance {
                $dbr = $this->getDB( DB_REPLICA );
                $dbw = $this->getDB( DB_MASTER );
                $batchSize = $this->getBatchSize();
-               $start = $dbw->selectField( $table, "MIN($idCol)", false, __METHOD__ );
-               $end = $dbw->selectField( $table, "MAX($idCol)", false, __METHOD__ );
+               $start = $dbw->selectField( $table, "MIN($idCol)", '', __METHOD__ );
+               $end = $dbw->selectField( $table, "MAX($idCol)", '', __METHOD__ );
                if ( !$start || !$end ) {
                        $this->output( "...$table table seems to be empty.\n" );
 
index d2372a9..9662044 100644 (file)
@@ -78,8 +78,8 @@ class PopulateRevisionSha1 extends LoggedUpdateMaintenance {
        protected function doSha1Updates( $table, $idCol, $queryInfo, $prefix ) {
                $db = $this->getDB( DB_MASTER );
                $batchSize = $this->getBatchSize();
-               $start = $db->selectField( $table, "MIN($idCol)", false, __METHOD__ );
-               $end = $db->selectField( $table, "MAX($idCol)", false, __METHOD__ );
+               $start = $db->selectField( $table, "MIN($idCol)", '', __METHOD__ );
+               $end = $db->selectField( $table, "MAX($idCol)", '', __METHOD__ );
                if ( !$start || !$end ) {
                        $this->output( "...$table table seems to be empty.\n" );
 
index ae6a75e..ecdec29 100644 (file)
@@ -82,10 +82,10 @@ class RebuildFileCache extends Maintenance {
                $overwrite = $this->hasOption( 'overwrite' );
                $start = ( $start > 0 )
                        ? $start
-                       : $dbr->selectField( 'page', 'MIN(page_id)', false, __METHOD__ );
+                       : $dbr->selectField( 'page', 'MIN(page_id)', '', __METHOD__ );
                $end = ( $end > 0 )
                        ? $end
-                       : $dbr->selectField( 'page', 'MAX(page_id)', false, __METHOD__ );
+                       : $dbr->selectField( 'page', 'MAX(page_id)', '', __METHOD__ );
                if ( !$start ) {
                        $this->fatalError( "Nothing to do." );
                }
index 9d5d39f..49f1cd1 100644 (file)
@@ -170,8 +170,8 @@ class RefreshLinks extends Maintenance {
                        }
                } else {
                        if ( !$end ) {
-                               $maxPage = $dbr->selectField( 'page', 'max(page_id)', false );
-                               $maxRD = $dbr->selectField( 'redirect', 'max(rd_from)', false );
+                               $maxPage = $dbr->selectField( 'page', 'max(page_id)', '', __METHOD__ );
+                               $maxRD = $dbr->selectField( 'redirect', 'max(rd_from)', '', __METHOD__ );
                                $end = max( $maxPage, $maxRD );
                        }
                        $this->output( "Refreshing redirects table.\n" );
index 8f55b88..bd0556a 100644 (file)
@@ -65,7 +65,7 @@ class CheckStorage {
                } else {
                        print "Checking...\n";
                }
-               $maxRevId = $dbr->selectField( 'revision', 'MAX(rev_id)', false, __METHOD__ );
+               $maxRevId = $dbr->selectField( 'revision', 'MAX(rev_id)', '', __METHOD__ );
                $chunkSize = 1000;
                $flagStats = [];
                $objectStats = [];
index da3ada7..6bc2f98 100644 (file)
@@ -55,7 +55,7 @@ class FixT22757 extends Maintenance {
                $numFixed = 0;
                $numBad = 0;
 
-               $totalRevs = $dbr->selectField( 'text', 'MAX(old_id)', false, __METHOD__ );
+               $totalRevs = $dbr->selectField( 'text', 'MAX(old_id)', '', __METHOD__ );
 
                // In MySQL 4.1+, the binary field old_text has a non-working LOWER() function
                $lowerLeft = 'LOWER(CONVERT(LEFT(old_text,22) USING latin1))';
index e117992..9bb554c 100644 (file)
@@ -41,7 +41,7 @@ if ( !defined( 'MEDIAWIKI' ) ) {
        if ( isset( $options['e'] ) ) {
                $maxID = $options['e'];
        } else {
-               $maxID = $dbw->selectField( 'text', 'MAX(old_id)', false, $fname );
+               $maxID = $dbw->selectField( 'text', 'MAX(old_id)', '', $fname );
        }
        $minID = isset( $options['s'] ) ? $options['s'] : 1;
 
index 4feb95e..9c1b538 100644 (file)
@@ -47,7 +47,7 @@ class OrphanStats extends Maintenance {
                if ( !$dbr->tableExists( 'blob_orphans' ) ) {
                        $this->fatalError( "blob_orphans doesn't seem to exist, need to run trackBlobs.php first" );
                }
-               $res = $dbr->select( 'blob_orphans', '*', false, __METHOD__ );
+               $res = $dbr->select( 'blob_orphans', '*', '', __METHOD__ );
 
                $num = 0;
                $totalSize = 0;
index 8ca8bb2..f9ec398 100644 (file)
@@ -38,7 +38,7 @@ function resolveStubs() {
        $fname = 'resolveStubs';
 
        $dbr = wfGetDB( DB_REPLICA );
-       $maxID = $dbr->selectField( 'text', 'MAX(old_id)', false, $fname );
+       $maxID = $dbr->selectField( 'text', 'MAX(old_id)', '', $fname );
        $blockSize = 10000;
        $numBlocks = intval( $maxID / $blockSize ) + 1;
 
index 6dee1a5..9ba3d1b 100644 (file)
@@ -25,7 +25,7 @@ class StorageTypeStats extends Maintenance {
        function execute() {
                $dbr = $this->getDB( DB_REPLICA );
 
-               $endId = $dbr->selectField( 'text', 'MAX(old_id)', false, __METHOD__ );
+               $endId = $dbr->selectField( 'text', 'MAX(old_id)', '', __METHOD__ );
                if ( !$endId ) {
                        echo "No text rows!\n";
                        exit( 1 );
index b4514ec..ae6d2ff 100644 (file)
@@ -153,7 +153,7 @@ class TrackBlobs {
 
                $textClause = $this->getTextClause();
                $startId = 0;
-               $endId = $dbr->selectField( 'revision', 'MAX(rev_id)', false, __METHOD__ );
+               $endId = $dbr->selectField( 'revision', 'MAX(rev_id)', '', __METHOD__ );
                $batchesDone = 0;
                $rowsInserted = 0;
 
@@ -229,7 +229,7 @@ class TrackBlobs {
 
                $textClause = $this->getTextClause( $this->clusters );
                $startId = 0;
-               $endId = $dbr->selectField( 'text', 'MAX(old_id)', false, __METHOD__ );
+               $endId = $dbr->selectField( 'text', 'MAX(old_id)', '', __METHOD__ );
                $rowsInserted = 0;
                $batchesDone = 0;
 
@@ -339,7 +339,7 @@ class TrackBlobs {
                        $startId = 0;
                        $batchesDone = 0;
                        $actualBlobs = gmp_init( 0 );
-                       $endId = $extDB->selectField( $table, 'MAX(blob_id)', false, __METHOD__ );
+                       $endId = $extDB->selectField( $table, 'MAX(blob_id)', '', __METHOD__ );
 
                        // Build a bitmap of actual blob rows
                        while ( true ) {
index cb40af3..668ba79 100644 (file)
@@ -46,11 +46,11 @@ class UpdateRestrictions extends Maintenance {
                        $this->fatalError( "page_restrictions table does not exist" );
                }
 
-               $start = $db->selectField( 'page', 'MIN(page_id)', false, __METHOD__ );
+               $start = $db->selectField( 'page', 'MIN(page_id)', '', __METHOD__ );
                if ( !$start ) {
                        $this->fatalError( "Nothing to do." );
                }
-               $end = $db->selectField( 'page', 'MAX(page_id)', false, __METHOD__ );
+               $end = $db->selectField( 'page', 'MAX(page_id)', '', __METHOD__ );
 
                # Do remaining chunk
                $end += $batchSize - 1;
index 3202e59..a751cf0 100644 (file)
@@ -69,4 +69,9 @@
                display: inline-block;
                vertical-align: middle;
        }
+
+       /* T188737 */
+       .templatesUsed .mw-redirect {
+               font-style: italic;
+       }
 }
index 7260a0a..c469222 100644 (file)
        word-wrap: break-word;
 }
 
+.diff-title {
+       vertical-align: top;
+}
+
+.diff-notice,
+.diff-multi,
 .diff-otitle,
 .diff-ntitle {
        text-align: center;
index 82149b3..a777153 100644 (file)
@@ -143,6 +143,9 @@ $wgAutoloadClasses += [
        'SpecialPageTestBase' => "$testDir/phpunit/includes/specials/SpecialPageTestBase.php",
        'SpecialPageExecutor' => "$testDir/phpunit/includes/specials/SpecialPageExecutor.php",
 
+       # tests/phpunit/includes/Storage
+       'MediaWiki\Tests\Storage\RevisionSlotsTest' => "$testDir/phpunit/includes/Storage/RevisionSlotsTest.php",
+
        # tests/phpunit/languages
        'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php",
 
index 79cac5e..807099f 100644 (file)
@@ -60,6 +60,8 @@ class MutableRevisionRecordTest extends MediaWikiTestCase {
 
        public function testSimpleGetSlotWhenEmpty() {
                $record = new MutableRevisionRecord( Title::newFromText( 'Foo' ) );
+               $this->assertFalse( $record->hasSlot( 'main' ) );
+
                $this->setExpectedException( RevisionAccessException::class );
                $record->getSlot( 'main' );
        }
@@ -71,6 +73,7 @@ class MutableRevisionRecordTest extends MediaWikiTestCase {
                        new WikitextContent( 'x' )
                );
                $record->setSlot( $slot );
+               $this->assertTrue( $record->hasSlot( 'main' ) );
                $this->assertSame( $slot, $record->getSlot( 'main' ) );
        }
 
index c2a275f..0416bcf 100644 (file)
@@ -5,13 +5,12 @@ namespace MediaWiki\Tests\Storage;
 use MediaWiki\Storage\MutableRevisionSlots;
 use MediaWiki\Storage\RevisionAccessException;
 use MediaWiki\Storage\SlotRecord;
-use MediaWikiTestCase;
 use WikitextContent;
 
 /**
  * @covers \MediaWiki\Storage\MutableRevisionSlots
  */
-class MutableRevisionSlotsTest extends MediaWikiTestCase {
+class MutableRevisionSlotsTest extends RevisionSlotsTest {
 
        public function testSetMultipleSlots() {
                $slots = new MutableRevisionSlots();
@@ -20,11 +19,13 @@ class MutableRevisionSlotsTest extends MediaWikiTestCase {
 
                $slotA = SlotRecord::newUnsaved( 'some', new WikitextContent( 'A' ) );
                $slots->setSlot( $slotA );
+               $this->assertTrue( $slots->hasSlot( 'some' ) );
                $this->assertSame( $slotA, $slots->getSlot( 'some' ) );
                $this->assertSame( [ 'some' => $slotA ], $slots->getSlots() );
 
                $slotB = SlotRecord::newUnsaved( 'other', new WikitextContent( 'B' ) );
                $slots->setSlot( $slotB );
+               $this->assertTrue( $slots->hasSlot( 'other' ) );
                $this->assertSame( $slotB, $slots->getSlot( 'other' ) );
                $this->assertSame( [ 'some' => $slotA, 'other' => $slotB ], $slots->getSlots() );
        }
diff --git a/tests/phpunit/includes/Storage/NameTableStoreTest.php b/tests/phpunit/includes/Storage/NameTableStoreTest.php
new file mode 100644 (file)
index 0000000..5276a14
--- /dev/null
@@ -0,0 +1,298 @@
+<?php
+
+namespace MediaWiki\Tests\Storage;
+
+use BagOStuff;
+use EmptyBagOStuff;
+use HashBagOStuff;
+use MediaWiki\Storage\NameTableAccessException;
+use MediaWiki\Storage\NameTableStore;
+use MediaWikiTestCase;
+use Psr\Log\NullLogger;
+use WANObjectCache;
+use Wikimedia\Rdbms\Database;
+use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\TestingAccessWrapper;
+
+/**
+ * @author Addshore
+ * @group Database
+ * @covers \MediaWiki\Storage\NameTableStore
+ */
+class NameTableStoreTest extends MediaWikiTestCase {
+
+       public function setUp() {
+               $this->tablesUsed[] = 'slot_roles';
+               parent::setUp();
+       }
+
+       private function populateTable( $values ) {
+               $insertValues = [];
+               foreach ( $values as $name ) {
+                       $insertValues[] = [ 'role_name' => $name ];
+               }
+               $this->db->insert( 'slot_roles', $insertValues );
+       }
+
+       private function getHashWANObjectCache( $cacheBag ) {
+               return new WANObjectCache( [ 'cache' => $cacheBag ] );
+       }
+
+       /**
+        * @param $db
+        * @return \PHPUnit_Framework_MockObject_MockObject|LoadBalancer
+        */
+       private function getMockLoadBalancer( $db ) {
+               $mock = $this->getMockBuilder( LoadBalancer::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $mock->expects( $this->any() )
+                       ->method( 'getConnection' )
+                       ->willReturn( $db );
+               return $mock;
+       }
+
+       private function getCallCheckingDb( $insertCalls, $selectCalls ) {
+               $mock = $this->getMockBuilder( Database::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $mock->expects( $this->exactly( $insertCalls ) )
+                       ->method( 'insert' )
+                       ->willReturnCallback( function () {
+                               return call_user_func_array( [ $this->db, 'insert' ], func_get_args() );
+                       } );
+               $mock->expects( $this->exactly( $selectCalls ) )
+                       ->method( 'select' )
+                       ->willReturnCallback( function () {
+                               return call_user_func_array( [ $this->db, 'select' ], func_get_args() );
+                       } );
+               $mock->expects( $this->exactly( $insertCalls ) )
+                       ->method( 'affectedRows' )
+                       ->willReturnCallback( function () {
+                               return call_user_func_array( [ $this->db, 'affectedRows' ], func_get_args() );
+                       } );
+               $mock->expects( $this->any() )
+                       ->method( 'insertId' )
+                       ->willReturnCallback( function () {
+                               return call_user_func_array( [ $this->db, 'insertId' ], func_get_args() );
+                       } );
+               return $mock;
+       }
+
+       private function getNameTableSqlStore(
+               BagOStuff $cacheBag,
+               $insertCalls,
+               $selectCalls,
+               $normalizationCallback = null
+       ) {
+               return new NameTableStore(
+                       $this->getMockLoadBalancer( $this->getCallCheckingDb( $insertCalls, $selectCalls ) ),
+                       $this->getHashWANObjectCache( $cacheBag ),
+                       new NullLogger(),
+                       'slot_roles', 'role_id', 'role_name',
+                       $normalizationCallback
+               );
+       }
+
+       public function provideGetAndAcquireId() {
+               return [
+                       'no wancache, empty table' =>
+                               [ new EmptyBagOStuff(), true, 1, [], 'foo', 1 ],
+                       'no wancache, one matching value' =>
+                               [ new EmptyBagOStuff(), false, 1, [ 'foo' ], 'foo', 1 ],
+                       'no wancache, one not matching value' =>
+                               [ new EmptyBagOStuff(), true, 1, [ 'bar' ], 'foo', 2 ],
+                       'no wancache, multiple, one matching value' =>
+                               [ new EmptyBagOStuff(), false, 1, [ 'foo', 'bar' ], 'bar', 2 ],
+                       'no wancache, multiple, no matching value' =>
+                               [ new EmptyBagOStuff(), true, 1, [ 'foo', 'bar' ], 'baz', 3 ],
+                       'wancache, empty table' =>
+                               [ new HashBagOStuff(), true, 1, [], 'foo', 1 ],
+                       'wancache, one matching value' =>
+                               [ new HashBagOStuff(), false, 1, [ 'foo' ], 'foo', 1 ],
+                       'wancache, one not matching value' =>
+                               [ new HashBagOStuff(), true, 1, [ 'bar' ], 'foo', 2 ],
+                       'wancache, multiple, one matching value' =>
+                               [ new HashBagOStuff(), false, 1, [ 'foo', 'bar' ], 'bar', 2 ],
+                       'wancache, multiple, no matching value' =>
+                               [ new HashBagOStuff(), true, 1, [ 'foo', 'bar' ], 'baz', 3 ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetAndAcquireId
+        * @param BagOStuff $cacheBag to use in the WANObjectCache service
+        * @param bool $needsInsert Does the value we are testing need to be inserted?
+        * @param int $selectCalls Number of times the select DB method will be called
+        * @param string[] $existingValues to be added to the db table
+        * @param string $name name to acquire
+        * @param int $expectedId the id we expect the name to have
+        */
+       public function testGetAndAcquireId(
+               $cacheBag,
+               $needsInsert,
+               $selectCalls,
+               $existingValues,
+               $name,
+               $expectedId
+       ) {
+               $this->populateTable( $existingValues );
+               $store = $this->getNameTableSqlStore( $cacheBag, (int)$needsInsert, $selectCalls );
+
+               // Some names will not initially exist
+               try {
+                       $result = $store->getId( $name );
+                       $this->assertSame( $expectedId, $result );
+               } catch ( NameTableAccessException $e ) {
+                       if ( $needsInsert ) {
+                               $this->assertTrue( true ); // Expected exception
+                       } else {
+                               $this->fail( 'Did not expect an exception, but got one: ' . $e->getMessage() );
+                       }
+               }
+
+               // All names should return their id here
+               $this->assertSame( $expectedId, $store->acquireId( $name ) );
+
+               // acquireId inserted these names, so now everything should exist with getId
+               $this->assertSame( $expectedId, $store->getId( $name ) );
+
+               // calling getId again will also still work, and not result in more selects
+               $this->assertSame( $expectedId, $store->getId( $name ) );
+       }
+
+       public function provideTestGetAndAcquireIdNameNormalization() {
+               yield [ 'A', 'a', 'strtolower' ];
+               yield [ 'b', 'B', 'strtoupper' ];
+               yield [
+                       'X',
+                       'X',
+                       function ( $name ) {
+                               return $name;
+                       }
+               ];
+               yield [ 'ZZ', 'ZZ-a', __CLASS__ . '::appendDashAToString' ];
+       }
+
+       public static function appendDashAToString( $string ) {
+               return $string . '-a';
+       }
+
+       /**
+        * @dataProvider provideTestGetAndAcquireIdNameNormalization
+        */
+       public function testGetAndAcquireIdNameNormalization(
+               $nameIn,
+               $nameOut,
+               $normalizationCallback
+       ) {
+               $store = $this->getNameTableSqlStore(
+                       new EmptyBagOStuff(),
+                       1,
+                       1,
+                       $normalizationCallback
+               );
+               $acquiredId = $store->acquireId( $nameIn );
+               $this->assertSame( $nameOut, $store->getName( $acquiredId ) );
+       }
+
+       public function provideGetName() {
+               return [
+                       [ new HashBagOStuff(), 3, 3 ],
+                       [ new EmptyBagOStuff(), 3, 3 ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetName
+        */
+       public function testGetName( $cacheBag, $insertCalls, $selectCalls ) {
+               $store = $this->getNameTableSqlStore( $cacheBag, $insertCalls, $selectCalls );
+
+               // Get 1 ID and make sure getName returns correctly
+               $fooId = $store->acquireId( 'foo' );
+               $this->assertSame( 'foo', $store->getName( $fooId ) );
+
+               // Get another ID and make sure getName returns correctly
+               $barId = $store->acquireId( 'bar' );
+               $this->assertSame( 'bar', $store->getName( $barId ) );
+
+               // Blitz the cache and make sure it still returns
+               TestingAccessWrapper::newFromObject( $store )->tableCache = null;
+               $this->assertSame( 'foo', $store->getName( $fooId ) );
+               $this->assertSame( 'bar', $store->getName( $barId ) );
+
+               // Blitz the cache again and get another ID and make sure getName returns correctly
+               TestingAccessWrapper::newFromObject( $store )->tableCache = null;
+               $bazId = $store->acquireId( 'baz' );
+               $this->assertSame( 'baz', $store->getName( $bazId ) );
+               $this->assertSame( 'baz', $store->getName( $bazId ) );
+       }
+
+       public function testGetName_masterFallback() {
+               $store = $this->getNameTableSqlStore( new EmptyBagOStuff(), 1, 2 );
+
+               // Insert a new name
+               $fooId = $store->acquireId( 'foo' );
+
+               // Empty the process cache, getCachedTable() will now return this empty array
+               TestingAccessWrapper::newFromObject( $store )->tableCache = [];
+
+               // getName should fallback to master, which is why we assert 2 selectCalls above
+               $this->assertSame( 'foo', $store->getName( $fooId ) );
+       }
+
+       public function testGetMap_empty() {
+               $this->populateTable( [] );
+               $store = $this->getNameTableSqlStore( new HashBagOStuff(), 0, 1 );
+               $table = $store->getMap();
+               $this->assertSame( [], $table );
+       }
+
+       public function testGetMap_twoValues() {
+               $this->populateTable( [ 'foo', 'bar' ] );
+               $store = $this->getNameTableSqlStore( new HashBagOStuff(), 0, 1 );
+
+               // We are using a cache, so 2 calls should only result in 1 select on the db
+               $store->getMap();
+               $table = $store->getMap();
+
+               $expected = [ 2 => 'bar', 1 => 'foo' ];
+               $this->assertSame( $expected, $table );
+               // Make sure the table returned is the same as the cached table
+               $this->assertSame( $expected, TestingAccessWrapper::newFromObject( $store )->tableCache );
+       }
+
+       public function testCacheRaceCondition() {
+               $wanHashBag = new HashBagOStuff();
+               $store1 = $this->getNameTableSqlStore( $wanHashBag, 1, 1 );
+               $store2 = $this->getNameTableSqlStore( $wanHashBag, 1, 0 );
+               $store3 = $this->getNameTableSqlStore( $wanHashBag, 1, 1 );
+
+               // Cache the current table in the instances we will use
+               // This simulates multiple requests running simultaneously
+               $store1->getMap();
+               $store2->getMap();
+               $store3->getMap();
+
+               // Store 2 separate names using different instances
+               $fooId = $store1->acquireId( 'foo' );
+               $barId = $store2->acquireId( 'bar' );
+
+               // Each of these instances should be aware of what they have inserted
+               $this->assertSame( $fooId, $store1->acquireId( 'foo' ) );
+               $this->assertSame( $barId, $store2->acquireId( 'bar' ) );
+
+               // A new store should be able to get both of these new Ids
+               // Note: before there was a race condition here where acquireId( 'bar' ) would update the
+               //       cache with data missing the 'foo' key that it was not aware of
+               $store4 = $this->getNameTableSqlStore( $wanHashBag, 0, 1 );
+               $this->assertSame( $fooId, $store4->getId( 'foo' ) );
+               $this->assertSame( $barId, $store4->getId( 'bar' ) );
+
+               // If a store with old cached data tries to acquire these we will get the same ids.
+               $this->assertSame( $fooId, $store3->acquireId( 'foo' ) );
+               $this->assertSame( $barId, $store3->acquireId( 'bar' ) );
+       }
+
+}
index 4dfae4b..b9f833c 100644 (file)
@@ -10,13 +10,21 @@ use WikitextContent;
 
 class RevisionSlotsTest extends MediaWikiTestCase {
 
+       /**
+        * @param SlotRecord[] $slots
+        * @return RevisionSlots
+        */
+       protected function newRevisionSlots( $slots = [] ) {
+               return new RevisionSlots( $slots );
+       }
+
        /**
         * @covers \MediaWiki\Storage\RevisionSlots::getSlot
         */
        public function testGetSlot() {
                $mainSlot = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
                $auxSlot = SlotRecord::newUnsaved( 'aux', new WikitextContent( 'B' ) );
-               $slots = new RevisionSlots( [ $mainSlot, $auxSlot ] );
+               $slots = $this->newRevisionSlots( [ $mainSlot, $auxSlot ] );
 
                $this->assertSame( $mainSlot, $slots->getSlot( 'main' ) );
                $this->assertSame( $auxSlot, $slots->getSlot( 'aux' ) );
@@ -24,6 +32,20 @@ class RevisionSlotsTest extends MediaWikiTestCase {
                $slots->getSlot( 'nothere' );
        }
 
+       /**
+        * @covers \MediaWiki\Storage\RevisionSlots::hasSlot
+        */
+       public function testHasSlot() {
+               $mainSlot = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
+               $auxSlot = SlotRecord::newUnsaved( 'aux', new WikitextContent( 'B' ) );
+               $slots = $this->newRevisionSlots( [ $mainSlot, $auxSlot ] );
+
+               $this->assertTrue( $slots->hasSlot( 'main' ) );
+               $this->assertTrue( $slots->hasSlot( 'aux' ) );
+               $this->assertFalse( $slots->hasSlot( 'AUX' ) );
+               $this->assertFalse( $slots->hasSlot( 'xyz' ) );
+       }
+
        /**
         * @covers \MediaWiki\Storage\RevisionSlots::getContent
         */
@@ -32,7 +54,7 @@ class RevisionSlotsTest extends MediaWikiTestCase {
                $auxContent = new WikitextContent( 'B' );
                $mainSlot = SlotRecord::newUnsaved( 'main', $mainContent );
                $auxSlot = SlotRecord::newUnsaved( 'aux', $auxContent );
-               $slots = new RevisionSlots( [ $mainSlot, $auxSlot ] );
+               $slots = $this->newRevisionSlots( [ $mainSlot, $auxSlot ] );
 
                $this->assertSame( $mainContent, $slots->getContent( 'main' ) );
                $this->assertSame( $auxContent, $slots->getContent( 'aux' ) );
@@ -46,7 +68,7 @@ class RevisionSlotsTest extends MediaWikiTestCase {
        public function testGetSlotRoles_someSlots() {
                $mainSlot = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
                $auxSlot = SlotRecord::newUnsaved( 'aux', new WikitextContent( 'B' ) );
-               $slots = new RevisionSlots( [ $mainSlot, $auxSlot ] );
+               $slots = $this->newRevisionSlots( [ $mainSlot, $auxSlot ] );
 
                $this->assertSame( [ 'main', 'aux' ], $slots->getSlotRoles() );
        }
@@ -55,7 +77,7 @@ class RevisionSlotsTest extends MediaWikiTestCase {
         * @covers \MediaWiki\Storage\RevisionSlots::getSlotRoles
         */
        public function testGetSlotRoles_noSlots() {
-               $slots = new RevisionSlots( [] );
+               $slots = $this->newRevisionSlots( [] );
 
                $this->assertSame( [], $slots->getSlotRoles() );
        }
@@ -67,7 +89,7 @@ class RevisionSlotsTest extends MediaWikiTestCase {
                $mainSlot = SlotRecord::newUnsaved( 'main', new WikitextContent( 'A' ) );
                $auxSlot = SlotRecord::newUnsaved( 'aux', new WikitextContent( 'B' ) );
                $slotsArray = [ $mainSlot, $auxSlot ];
-               $slots = new RevisionSlots( $slotsArray );
+               $slots = $this->newRevisionSlots( $slotsArray );
 
                $this->assertEquals( [ 'main' => $mainSlot, 'aux' => $auxSlot ], $slots->getSlots() );
        }
@@ -87,7 +109,7 @@ class RevisionSlotsTest extends MediaWikiTestCase {
                foreach ( $contentStrings as $key => $contentString ) {
                        $slotsArray[] = SlotRecord::newUnsaved( strval( $key ), new WikitextContent( $contentString ) );
                }
-               $slots = new RevisionSlots( $slotsArray );
+               $slots = $this->newRevisionSlots( $slotsArray );
 
                $this->assertSame( $expected, $slots->computeSize() );
        }
@@ -109,7 +131,7 @@ class RevisionSlotsTest extends MediaWikiTestCase {
                foreach ( $contentStrings as $key => $contentString ) {
                        $slotsArray[] = SlotRecord::newUnsaved( strval( $key ), new WikitextContent( $contentString ) );
                }
-               $slots = new RevisionSlots( $slotsArray );
+               $slots = $this->newRevisionSlots( $slotsArray );
 
                $this->assertSame( $expected, $slots->computeSha1() );
        }
index 43784b6..3976995 100644 (file)
@@ -458,8 +458,9 @@ class RevisionStoreRecordTest extends MediaWikiTestCase {
                $rev = $this->newRevision( [ 'rev_deleted' => $visibility ] );
 
                // NOTE: slot meta-data is never suppressed, just the content is!
-               $this->assertNotNull( $rev->getSlot( 'main', RevisionRecord::RAW ), 'raw can' );
-               $this->assertNotNull( $rev->getSlot( 'main', RevisionRecord::FOR_PUBLIC ), 'public can' );
+               $this->assertTrue( $rev->hasSlot( 'main' ), 'hasSlot is never suppressed' );
+               $this->assertNotNull( $rev->getSlot( 'main', RevisionRecord::RAW ), 'raw meta' );
+               $this->assertNotNull( $rev->getSlot( 'main', RevisionRecord::FOR_PUBLIC ), 'public meta' );
 
                $this->assertNotNull(
                        $rev->getSlot( 'main', RevisionRecord::FOR_THIS_USER, $user ),
@@ -562,6 +563,13 @@ class RevisionStoreRecordTest extends MediaWikiTestCase {
                $this->assertSame( 'main', $slot->getRole(), 'getRole()' );
        }
 
+       public function testHasSlot() {
+               $rev = $this->newRevision();
+
+               $this->assertTrue( $rev->hasSlot( 'main' ) );
+               $this->assertFalse( $rev->hasSlot( 'xyz' ) );
+       }
+
        public function testGetContent() {
                $rev = $this->newRevision();
 
index c833934..07dbd00 100644 (file)
@@ -17,14 +17,23 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        ->getMock();
        }
 
-       private function createSimpleConfigMock( array $config ) {
+       private static function createEtcdResponse( array $response ) {
+               $baseResponse = [
+                       'config' => null,
+                       'error' => null,
+                       'retry' => false,
+                       'modifiedIndex' => 0,
+               ];
+               return array_merge( $baseResponse, $response );
+       }
+
+       private function createSimpleConfigMock( array $config, $index = 0 ) {
                $mock = $this->createConfigMock();
                $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' )
-                       ->willReturn( [
-                               $config,
-                               null, // error
-                               false // retry?
-                       ] );
+                       ->willReturn( self::createEtcdResponse( [
+                               'config' => $config,
+                               'modifiedIndex' => $index,
+                       ] ) );
                return $mock;
        }
 
@@ -70,6 +79,17 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                $config->get( 'unknown' );
        }
 
+       /**
+        * @covers EtcdConfig::getModifiedIndex
+        */
+       public function testGetModifiedIndex() {
+               $config = $this->createSimpleConfigMock(
+                       [ 'some' => 'value' ],
+                       123
+               );
+               $this->assertSame( 123, $config->getModifiedIndex() );
+       }
+
        /**
         * @covers EtcdConfig::__construct
         */
@@ -81,6 +101,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        ->willReturn( [
                                'config' => [ 'known' => 'from-cache' ],
                                'expires' => INF,
+                               'modifiedIndex' => 123
                        ] );
                $config = $this->createConfigMock( [ 'cache' => $cache ] );
 
@@ -95,11 +116,8 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        'class' => HashBagOStuff::class
                ] ] );
                $config->expects( $this->once() )->method( 'fetchAllFromEtcd' )
-                       ->willReturn( [
-                               [ 'known' => 'from-fetch' ],
-                               null, // error
-                               false // retry?
-                       ] );
+                       ->willReturn( self::createEtcdResponse(
+                               [ 'config' => [ 'known' => 'from-fetch' ], ] ) );
 
                $this->assertSame( 'from-fetch', $config->get( 'known' ) );
        }
@@ -166,7 +184,8 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        'cache' => $cache,
                ] );
                $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' )
-                       ->willReturn( [ [ 'known' => 'from-fetch' ], null, false ] );
+                       ->willReturn(
+                               self::createEtcdResponse( [ 'config' => [ 'known' => 'from-fetch' ] ] ) );
 
                $this->assertSame( 'from-fetch', $mock->get( 'known' ) );
        }
@@ -191,7 +210,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        'cache' => $cache,
                ] );
                $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' )
-                       ->willReturn( [ null, 'Fake error', false ] );
+                       ->willReturn( self::createEtcdResponse( [ 'error' => 'Fake error', ] ) );
 
                $this->setExpectedException( ConfigException::class );
                $mock->get( 'key' );
@@ -213,6 +232,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                [
                                        'config' => [ 'known' => 'from-cache' ],
                                        'expires' => INF,
+                                       'modifiedIndex' => 123
                                ]
                        ) );
                // .. misses lock
@@ -241,6 +261,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        ->willReturn( [
                                'config' => [ 'known' => 'from-cache' ],
                                'expires' => INF,
+                               'modifiedIndex' => 0,
                        ] );
                $cache->expects( $this->never() )->method( 'lock' );
 
@@ -266,6 +287,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        ->willReturn( [
                                'config' => [ 'known' => 'from-cache' ],
                                'expires' => INF,
+                               'modifiedIndex' => 0,
                        ] );
                $cache->expects( $this->never() )->method( 'lock' );
 
@@ -292,6 +314,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        [
                                'config' => [ 'known' => 'from-cache-expired' ],
                                'expires' => -INF,
+                               'modifiedIndex' => 0,
                        ]
                );
                // .. gets lock
@@ -303,7 +326,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        'cache' => $cache,
                ] );
                $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' )
-                       ->willReturn( [ [ 'known' => 'from-fetch' ], null, false ] );
+                       ->willReturn( self::createEtcdResponse( [ 'config' => [ 'known' => 'from-fetch' ] ] ) );
 
                $this->assertSame( 'from-fetch', $mock->get( 'known' ) );
        }
@@ -321,6 +344,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        [
                                'config' => [ 'known' => 'from-cache-expired' ],
                                'expires' => -INF,
+                               'modifiedIndex' => 0,
                        ]
                );
                // .. gets lock
@@ -332,7 +356,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        'cache' => $cache,
                ] );
                $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' )
-                       ->willReturn( [ null, 'Fake failure', true ] );
+                       ->willReturn( self::createEtcdResponse( [ 'error' => 'Fake failure', 'retry' => true ] ) );
 
                $this->assertSame( 'from-cache-expired', $mock->get( 'known' ) );
        }
@@ -350,6 +374,7 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                        ->willReturn( [
                                'config' => [ 'known' => 'from-cache-expired' ],
                                'expires' => -INF,
+                               'modifiedIndex' => 0,
                        ] );
                // .. misses lock
                $cache->expects( $this->once() )->method( 'lock' )
@@ -374,16 +399,16 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                        'body' => json_encode( [ 'node' => [ 'nodes' => [
                                                [
                                                        'key' => '/example/foo',
-                                                       'value' => json_encode( [ 'val' => true ] )
+                                                       'value' => json_encode( [ 'val' => true ] ),
+                                                       'modifiedIndex' => 123
                                                ],
                                        ] ] ] ),
                                        'error' => '',
                                ],
-                               'expect' => [
-                                       [ 'foo' => true ], // data
-                                       null,
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'config' => [ 'foo' => true ], // data
+                                       'modifiedIndex' => 123
+                               ] ),
                        ],
                        '200 OK - Empty dir' => [
                                'http' => [
@@ -393,25 +418,27 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                        'body' => json_encode( [ 'node' => [ 'nodes' => [
                                                [
                                                        'key' => '/example/foo',
-                                                       'value' => json_encode( [ 'val' => true ] )
+                                                       'value' => json_encode( [ 'val' => true ] ),
+                                                       'modifiedIndex' => 123
                                                ],
                                                [
                                                        'key' => '/example/sub',
                                                        'dir' => true,
+                                                       'modifiedIndex' => 234,
                                                        'nodes' => [],
                                                ],
                                                [
                                                        'key' => '/example/bar',
-                                                       'value' => json_encode( [ 'val' => false ] )
+                                                       'value' => json_encode( [ 'val' => false ] ),
+                                                       'modifiedIndex' => 125
                                                ],
                                        ] ] ] ),
                                        'error' => '',
                                ],
-                               'expect' => [
-                                       [ 'foo' => true, 'bar' => false ], // data
-                                       null,
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'config' => [ 'foo' => true, 'bar' => false ], // data
+                                       'modifiedIndex' => 125 // largest modified index
+                               ] ),
                        ],
                        '200 OK - Recursive' => [
                                'http' => [
@@ -422,25 +449,28 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                                [
                                                        'key' => '/example/a',
                                                        'dir' => true,
+                                                       'modifiedIndex' => 124,
                                                        'nodes' => [
                                                                [
                                                                        'key' => 'b',
                                                                        'value' => json_encode( [ 'val' => true ] ),
+                                                                       'modifiedIndex' => 123,
+
                                                                ],
                                                                [
                                                                        'key' => 'c',
                                                                        'value' => json_encode( [ 'val' => false ] ),
+                                                                       'modifiedIndex' => 123,
                                                                ],
                                                        ],
                                                ],
                                        ] ] ] ),
                                        'error' => '',
                                ],
-                               'expect' => [
-                                       [ 'a/b' => true, 'a/c' => false ], // data
-                                       null,
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'config' => [ 'a/b' => true, 'a/c' => false ], // data
+                                       'modifiedIndex' => 123 // largest modified index
+                               ] ),
                        ],
                        '200 OK - Missing nodes at second level' => [
                                'http' => [
@@ -451,15 +481,14 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                                [
                                                        'key' => '/example/a',
                                                        'dir' => true,
+                                                       'modifiedIndex' => 0,
                                                ],
                                        ] ] ] ),
                                        'error' => '',
                                ],
-                               'expect' => [
-                                       null,
-                                       "Unexpected JSON response in dir 'a'; missing 'nodes' list.",
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'error' => "Unexpected JSON response in dir 'a'; missing 'nodes' list.",
+                               ] ),
                        ],
                        '200 OK - Directory with non-array "nodes" key' => [
                                'http' => [
@@ -475,11 +504,9 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                        ] ] ] ),
                                        'error' => '',
                                ],
-                               'expect' => [
-                                       null,
-                                       "Unexpected JSON response in dir 'a'; 'nodes' is not an array.",
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'error' => "Unexpected JSON response in dir 'a'; 'nodes' is not an array.",
+                               ] ),
                        ],
                        '200 OK - Correctly encoded garbage response' => [
                                'http' => [
@@ -489,11 +516,9 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                        'body' => json_encode( [ 'foo' => 'bar' ] ),
                                        'error' => '',
                                ],
-                               'expect' => [
-                                       null,
-                                       "Unexpected JSON response: Missing or invalid node at top level.",
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'error' => "Unexpected JSON response: Missing or invalid node at top level.",
+                               ] ),
                        ],
                        '200 OK - Bad value' => [
                                'http' => [
@@ -503,30 +528,27 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                        'body' => json_encode( [ 'node' => [ 'nodes' => [
                                                [
                                                        'key' => '/example/foo',
-                                                       'value' => ';"broken{value'
+                                                       'value' => ';"broken{value',
+                                                       'modifiedIndex' => 123,
                                                ]
                                        ] ] ] ),
                                        'error' => '',
                                ],
-                               'expect' => [
-                                       null, // data
-                                       "Failed to parse value for 'foo'.",
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'error' => "Failed to parse value for 'foo'.",
+                               ] ),
                        ],
                        '200 OK - Empty node list' => [
                                'http' => [
                                        'code' => 200,
                                        'reason' => 'OK',
                                        'headers' => [],
-                                       'body' => '{"node":{"nodes":[]}}',
+                                       'body' => '{"node":{"nodes":[], "modifiedIndex": 12 }}',
                                        'error' => '',
                                ],
-                               'expect' => [
-                                       [], // data
-                                       null,
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'config' => [], // data
+                               ] ),
                        ],
                        '200 OK - Invalid JSON' => [
                                'http' => [
@@ -536,11 +558,9 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                        'body' => '',
                                        'error' => '(curl error: no status set)',
                                ],
-                               'expect' => [
-                                       null, // data
-                                       "Error unserializing JSON response.",
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'error' => "Error unserializing JSON response.",
+                               ] ),
                        ],
                        '404 Not Found' => [
                                'http' => [
@@ -550,11 +570,9 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                        'body' => '',
                                        'error' => '',
                                ],
-                               'expect' => [
-                                       null, // data
-                                       'HTTP 404 (Not Found)',
-                                       false // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'error' => 'HTTP 404 (Not Found)',
+                               ] ),
                        ],
                        '400 Bad Request - custom error' => [
                                'http' => [
@@ -564,11 +582,10 @@ class EtcdConfigTest extends PHPUnit\Framework\TestCase {
                                        'body' => '',
                                        'error' => 'No good reason',
                                ],
-                               'expect' => [
-                                       null, // data
-                                       'No good reason',
-                                       true // retry
-                               ],
+                               'expect' => self::createEtcdResponse( [
+                                       'error' => 'No good reason',
+                                       'retry' => true, // retry
+                               ] ),
                        ],
                ];
        }
index 6656fa4..823be6f 100644 (file)
@@ -153,16 +153,6 @@ class JavaScriptContentTest extends TextContentTest {
                                'any',
                                true
                        ],
-                       [ 'Foo',
-                               null,
-                               'comma',
-                               false
-                       ],
-                       [ 'Foo, bar',
-                               null,
-                               'comma',
-                               false
-                       ],
                        [ 'Foo',
                                null,
                                'link',
@@ -188,11 +178,6 @@ class JavaScriptContentTest extends TextContentTest {
                                'any',
                                true
                        ],
-                       [ '#REDIRECT [[bar]]',
-                               true,
-                               'comma',
-                               false
-                       ],
                        [ '#REDIRECT [[bar]]',
                                true,
                                'link',
index b548091..406bc96 100644 (file)
@@ -197,16 +197,6 @@ class TextContentTest extends MediaWikiLangTestCase {
                                'any',
                                true
                        ],
-                       [ 'Foo',
-                               null,
-                               'comma',
-                               false
-                       ],
-                       [ 'Foo, bar',
-                               null,
-                               'comma',
-                               false
-                       ],
                ];
        }
 
index e04f562..1db6aab 100644 (file)
@@ -266,16 +266,6 @@ just a test"
                                'any',
                                true
                        ],
-                       [ 'Foo',
-                               null,
-                               'comma',
-                               false
-                       ],
-                       [ 'Foo, bar',
-                               null,
-                               'comma',
-                               true
-                       ],
                        [ 'Foo',
                                null,
                                'link',
@@ -301,11 +291,6 @@ just a test"
                                'any',
                                false
                        ],
-                       [ '#REDIRECT [[bar]]',
-                               true,
-                               'comma',
-                               false
-                       ],
                        [ '#REDIRECT [[bar]]',
                                true,
                                'link',
index 2de35a7..729b58c 100644 (file)
@@ -508,4 +508,12 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
 
                $this->assertContains( 'SQLite ', $toString );
        }
+
+       /**
+        * @covers \Wikimedia\Rdbms\DatabaseSqlite::getAttributes()
+        */
+       public function testsAttributes() {
+               $attributes = Database::attributesFromType( 'sqlite' );
+               $this->assertTrue( $attributes[Database::ATTR_DB_LEVEL_LOCKING] );
+       }
 }
index fe7b710..6cc41d1 100644 (file)
@@ -1,10 +1,5 @@
 <?php
 
-use Wikimedia\Rdbms\DBError;
-use Wikimedia\Rdbms\LoadBalancer;
-use Wikimedia\Rdbms\DatabaseDomain;
-use Wikimedia\Rdbms\Database;
-
 /**
  * Holds tests for LoadBalancer MediaWiki class.
  *
@@ -28,6 +23,13 @@ use Wikimedia\Rdbms\Database;
  *
  * @covers \Wikimedia\Rdbms\LoadBalancer
  */
+
+use Wikimedia\Rdbms\DBError;
+use Wikimedia\Rdbms\DatabaseDomain;
+use Wikimedia\Rdbms\Database;
+use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\LoadMonitorNull;
+
 class LoadBalancerTest extends MediaWikiTestCase {
        public function testWithoutReplica() {
                global $wgDBserver, $wgDBname, $wgDBuser, $wgDBpassword, $wgDBtype, $wgSQLiteDataDir;
@@ -190,4 +192,52 @@ class LoadBalancerTest extends MediaWikiTestCase {
                }
        }
 
+       public function testServerAttributes() {
+               $servers = [
+                       [ // master
+                               'dbname'      => 'my_unittest_wiki',
+                               'tablePrefix' => 'unittest_',
+                               'type'        => 'sqlite',
+                               'dbDirectory' => "some_directory",
+                               'load'        => 0
+                       ]
+               ];
+
+               $lb = new LoadBalancer( [
+                       'servers' => $servers,
+                       'localDomain' => new DatabaseDomain( 'my_unittest_wiki', null, 'unittest_' ),
+                       'loadMonitorClass' => LoadMonitorNull::class
+               ] );
+
+               $this->assertTrue( $lb->getServerAttributes( 0 )[Database::ATTR_DB_LEVEL_LOCKING] );
+
+               $servers = [
+                       [ // master
+                               'host'        => 'db1001',
+                               'user'        => 'wikiuser',
+                               'password'    => 'none',
+                               'dbname'      => 'my_unittest_wiki',
+                               'tablePrefix' => 'unittest_',
+                               'type'        => 'mysql',
+                               'load'        => 100
+                       ],
+                       [ // emulated replica
+                               'host'        => 'db1002',
+                               'user'        => 'wikiuser',
+                               'password'    => 'none',
+                               'dbname'      => 'my_unittest_wiki',
+                               'tablePrefix' => 'unittest_',
+                               'type'        => 'mysql',
+                               'load'        => 100
+                       ]
+               ];
+
+               $lb = new LoadBalancer( [
+                       'servers' => $servers,
+                       'localDomain' => new DatabaseDomain( 'my_unittest_wiki', null, 'unittest_' ),
+                       'loadMonitorClass' => LoadMonitorNull::class
+               ] );
+
+               $this->assertFalse( $lb->getServerAttributes( 1 )[Database::ATTR_DB_LEVEL_LOCKING] );
+       }
 }
index 5fcca1a..14c7057 100644 (file)
@@ -29,6 +29,7 @@ use Wikimedia\Rdbms\MySQLMasterPos;
 use Wikimedia\Rdbms\DatabaseMysqlBase;
 use Wikimedia\Rdbms\DatabaseMysqli;
 use Wikimedia\Rdbms\Database;
+use Wikimedia\TestingAccessWrapper;
 
 /**
  * Fake class around abstract class so we can call concrete methods.
@@ -510,4 +511,97 @@ class DatabaseMysqlBaseTest extends PHPUnit\Framework\TestCase {
 
                $this->assertEquals( $pos, $roundtripPos );
        }
+
+       /**
+        * @covers Wikimedia\Rdbms\DatabaseMysqlBase::isInsertSelectSafe
+        * @dataProvider provideInsertSelectCases
+        */
+       public function testInsertSelectIsSafe( $insertOpts, $selectOpts, $row, $safe ) {
+               $db = $this->getMockBuilder( DatabaseMysqli::class )
+                       ->disableOriginalConstructor()
+                       ->setMethods( [ 'getReplicationSafetyInfo' ] )
+                       ->getMock();
+               $db->method( 'getReplicationSafetyInfo' )->willReturn( (object)$row );
+               $dbw = TestingAccessWrapper::newFromObject( $db );
+
+               $this->assertEquals( $safe, $dbw->isInsertSelectSafe( $insertOpts, $selectOpts ) );
+       }
+
+       public function provideInsertSelectCases() {
+               return [
+                       [
+                               [],
+                               [],
+                               [
+                                       'innodb_autoinc_lock_mode' => '2',
+                                       'binlog_format' => 'ROW',
+                               ],
+                               true
+                       ],
+                       [
+                               [],
+                               [ 'LIMIT' => 100 ],
+                               [
+                                       'innodb_autoinc_lock_mode' => '2',
+                                       'binlog_format' => 'ROW',
+                               ],
+                               true
+                       ],
+                       [
+                               [],
+                               [ 'LIMIT' => 100 ],
+                               [
+                                       'innodb_autoinc_lock_mode' => '0',
+                                       'binlog_format' => 'STATEMENT',
+                               ],
+                               false
+                       ],
+                       [
+                               [],
+                               [],
+                               [
+                                       'innodb_autoinc_lock_mode' => '2',
+                                       'binlog_format' => 'STATEMENT',
+                               ],
+                               false
+                       ],
+                       [
+                               [ 'NO_AUTO_COLUMNS' ],
+                               [ 'LIMIT' => 100 ],
+                               [
+                                       'innodb_autoinc_lock_mode' => '0',
+                                       'binlog_format' => 'STATEMENT',
+                               ],
+                               false
+                       ],
+                       [
+                               [],
+                               [],
+                               [
+                                       'innodb_autoinc_lock_mode' => 0,
+                                       'binlog_format' => 'STATEMENT',
+                               ],
+                               true
+                       ],
+                       [
+                               [ 'NO_AUTO_COLUMNS' ],
+                               [],
+                               [
+                                       'innodb_autoinc_lock_mode' => 2,
+                                       'binlog_format' => 'STATEMENT',
+                               ],
+                               true
+                       ],
+                       [
+                               [ 'NO_AUTO_COLUMNS' ],
+                               [],
+                               [
+                                       'innodb_autoinc_lock_mode' => 0,
+                                       'binlog_format' => 'STATEMENT',
+                               ],
+                               true
+                       ],
+
+               ];
+       }
 }
index 3d1fe1a..5c1943b 100644 (file)
@@ -64,6 +64,44 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                                        "FROM table " .
                                        "WHERE alias = 'text'"
                        ],
+                       [
+                               [
+                                       'tables' => 'table',
+                                       'fields' => [ 'field', 'alias' => 'field2' ],
+                                       'conds' => 'alias = \'text\'',
+                               ],
+                               "SELECT field,field2 AS alias " .
+                               "FROM table " .
+                               "WHERE alias = 'text'"
+                       ],
+                       [
+                               [
+                                       'tables' => 'table',
+                                       'fields' => [ 'field', 'alias' => 'field2' ],
+                                       'conds' => [],
+                               ],
+                               "SELECT field,field2 AS alias " .
+                               "FROM table"
+                       ],
+                       [
+                               [
+                                       'tables' => 'table',
+                                       'fields' => [ 'field', 'alias' => 'field2' ],
+                                       'conds' => '',
+                               ],
+                               "SELECT field,field2 AS alias " .
+                               "FROM table"
+                       ],
+                       [
+                               [
+                                       'tables' => 'table',
+                                       'fields' => [ 'field', 'alias' => 'field2' ],
+                                       'conds' => '0', // T188314
+                               ],
+                               "SELECT field,field2 AS alias " .
+                               "FROM table " .
+                               "WHERE 0"
+                       ],
                        [
                                [
                                        // 'tables' with space prepended indicates pre-escaped table name
index 7adc43b..6367a0f 100644 (file)
@@ -374,20 +374,6 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                                true
                        ],
 
-                       // comma
-                       [ 'WikiPageTest_testIsCountable',
-                               CONTENT_MODEL_WIKITEXT,
-                               'Foo',
-                               'comma',
-                               false
-                       ],
-                       [ 'WikiPageTest_testIsCountable',
-                               CONTENT_MODEL_WIKITEXT,
-                               'Foo, bar',
-                               'comma',
-                               true
-                       ],
-
                        // link
                        [ 'WikiPageTest_testIsCountable',
                                CONTENT_MODEL_WIKITEXT,
@@ -409,12 +395,6 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                                'any',
                                false
                        ],
-                       [ 'WikiPageTest_testIsCountable',
-                               CONTENT_MODEL_WIKITEXT,
-                               '#REDIRECT [[bar]]',
-                               'comma',
-                               false
-                       ],
                        [ 'WikiPageTest_testIsCountable',
                                CONTENT_MODEL_WIKITEXT,
                                '#REDIRECT [[bar]]',
@@ -429,12 +409,6 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                                'any',
                                false
                        ],
-                       [ 'Talk:WikiPageTest_testIsCountable',
-                               CONTENT_MODEL_WIKITEXT,
-                               'Foo, bar',
-                               'comma',
-                               false
-                       ],
                        [ 'Talk:WikiPageTest_testIsCountable',
                                CONTENT_MODEL_WIKITEXT,
                                'Foo [[bar]]',
@@ -449,12 +423,6 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                                'any',
                                false
                        ],
-                       [ 'MediaWiki:WikiPageTest_testIsCountable.js',
-                               null,
-                               'Foo, bar',
-                               'comma',
-                               false
-                       ],
                        [ 'MediaWiki:WikiPageTest_testIsCountable.js',
                                null,
                                'Foo [[bar]]',
diff --git a/tests/phpunit/includes/parser/StripStateTest.php b/tests/phpunit/includes/parser/StripStateTest.php
new file mode 100644 (file)
index 0000000..0f4f6e0
--- /dev/null
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * @covers StripState
+ */
+class StripStateTest extends MediaWikiTestCase {
+       public function setUp() {
+               parent::setUp();
+               $this->setContentLang( 'qqx' );
+       }
+
+       private function getMarker() {
+               static $i;
+               return Parser::MARKER_PREFIX . '-blah-' . sprintf( '%08X', $i++ ) . Parser::MARKER_SUFFIX;
+       }
+
+       private static function getWarning( $message, $max = '' ) {
+               return "<span class=\"error\">($message: $max)</span>";
+       }
+
+       public function testAddNoWiki() {
+               $ss = new StripState;
+               $marker = $this->getMarker();
+               $ss->addNoWiki( $marker, '<>' );
+               $text = "x{$marker}y";
+               $text = $ss->unstripGeneral( $text );
+               $text = str_replace( '<', '', $text );
+               $text = $ss->unstripNoWiki( $text );
+               $this->assertSame( 'x<>y', $text );
+       }
+
+       public function testAddGeneral() {
+               $ss = new StripState;
+               $marker = $this->getMarker();
+               $ss->addGeneral( $marker, '<>' );
+               $text = "x{$marker}y";
+               $text = $ss->unstripNoWiki( $text );
+               $text = str_replace( '<', '', $text );
+               $text = $ss->unstripGeneral( $text );
+               $this->assertSame( 'x<>y', $text );
+       }
+
+       public function testUnstripBoth() {
+               $ss = new StripState;
+               $mk1 = $this->getMarker();
+               $mk2 = $this->getMarker();
+               $ss->addNoWiki( $mk1, '<1>' );
+               $ss->addGeneral( $mk2, '<2>' );
+               $text = "x{$mk1}{$mk2}y";
+               $text = str_replace( '<', '', $text );
+               $text = $ss->unstripBoth( $text );
+               $this->assertSame( 'x<1><2>y', $text );
+       }
+
+       public static function provideUnstripRecursive() {
+               return [
+                       [ 0, 'text' ],
+                       [ 1, '=text=' ],
+                       [ 2, '==text==' ],
+                       [ 3, '==' . self::getWarning( 'unstrip-depth-warning', 2 ) . '==' ],
+               ];
+       }
+
+       /** @dataProvider provideUnstripRecursive */
+       public function testUnstripRecursive( $depth, $expected ) {
+               $ss = new StripState( null, [ 'depthLimit' => 2 ] );
+               $text = 'text';
+               for ( $i = 0; $i < $depth; $i++ ) {
+                       $mk = $this->getMarker();
+                       $ss->addNoWiki( $mk, "={$text}=" );
+                       $text = $mk;
+               }
+               $text = $ss->unstripNoWiki( $text );
+               $this->assertSame( $expected, $text );
+       }
+
+       public function testUnstripLoop() {
+               $ss = new StripState( null, [ 'depthLimit' => 2 ] );
+               $mk = $this->getMarker();
+               $ss->addNoWiki( $mk, $mk );
+               $text = $ss->unstripNoWiki( $mk );
+               $this->assertSame( self::getWarning( 'parser-unstrip-loop-warning' ), $text );
+       }
+
+       public static function provideUnstripSize() {
+               return [
+                       [ 0, 'x' ],
+                       [ 1, 'xx' ],
+                       [ 2, str_repeat( self::getWarning( 'unstrip-size-warning', 5 ), 2 ) ]
+               ];
+       }
+
+       /** @dataProvider provideUnstripSize */
+       public function testUnstripSize( $depth, $expected ) {
+               $ss = new StripState( null, [ 'sizeLimit' => 5 ] );
+               $text = 'x';
+               for ( $i = 0; $i < $depth; $i++ ) {
+                       $mk = $this->getMarker();
+                       $ss->addNoWiki( $mk, $text );
+                       $text = "$mk$mk";
+               }
+               $text = $ss->unstripNoWiki( $text );
+               $this->assertSame( $expected, $text );
+       }
+
+       public function provideGetLimitReport() {
+               for ( $i = 1; $i < 4; $i++ ) {
+                       yield [ $i ];
+               }
+       }
+
+       /** @dataProvider provideGetLimitReport */
+       public function testGetLimitReport( $depth ) {
+               $sizeLimit = 100000;
+               $ss = new StripState( null, [ 'depthLimit' => 5, 'sizeLimit' => $sizeLimit ] );
+               $text = 'x';
+               for ( $i = 0; $i < $depth; $i++ ) {
+                       $mk = $this->getMarker();
+                       $ss->addNoWiki( $mk, $text );
+                       $text = "$mk$mk";
+               }
+               $text = $ss->unstripNoWiki( $text );
+               $report = $ss->getLimitReport();
+               $messages = [];
+               foreach ( $report as list( $msg, $params ) ) {
+                       $messages[$msg] = $params;
+               }
+               $this->assertSame( [ $depth - 1, 5 ], $messages['limitreport-unstrip-depth'] );
+               $this->assertSame(
+                       [
+                               strlen( $this->getMarker() ) * 2 * ( pow( 2, $depth ) - 2 ) + pow( 2, $depth ),
+                               $sizeLimit
+                       ],
+                       $messages['limitreport-unstrip-size' ] );
+       }
+}
index 7bfd769..a75ea56 100644 (file)
@@ -127,6 +127,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                ] );
                $client->setModuleScripts( [
                        'test.scripts',
+                       'test.scripts.user',
                        'test.scripts.user.empty',
                        'test.scripts.shouldembed',
                        'test.unregistered.scripts',
@@ -142,6 +143,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                                'test.styles.private' => 'ready',
                                'test.styles.shouldembed' => 'ready',
                                'test.scripts' => 'loading',
+                               'test.scripts.user' => 'loading',
                                'test.scripts.user.empty' => 'ready',
                                'test.scripts.shouldembed' => 'loading',
                        ],
@@ -153,6 +155,7 @@ class ResourceLoaderClientHtmlTest extends PHPUnit\Framework\TestCase {
                        ],
                        'scripts' => [
                                'test.scripts',
+                               'test.scripts.user',
                                'test.scripts.shouldembed',
                        ],
                        'embed' => [
index 1db8c61..23ef26f 100644 (file)
                        [ '$ 1.50' ],
                        [ '$ 3.00' ],
                        [ '$3.50' ],
-                       // Comma's sort after dots
+                       // Commas sort after dots
                        // Not intentional but test to detect changes
                        [ '€ 2,99' ]
                ],