Merge "Add special pages aliases for Western Balochi (bgn) from translatewiki"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 7 Apr 2015 16:12:54 +0000 (16:12 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 7 Apr 2015 16:12:54 +0000 (16:12 +0000)
62 files changed:
CREDITS
RELEASE-NOTES-1.25
autoload.php
includes/Block.php
includes/DefaultSettings.php
includes/MediaWiki.php
includes/User.php
includes/api/ApiEditPage.php
includes/api/ApiMain.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQuerySiteinfo.php
includes/api/i18n/es.json
includes/api/i18n/ja.json
includes/api/i18n/pl.json
includes/debug/logger/Shims.php
includes/debug/logger/monolog/Shims.php [new file with mode: 0644]
includes/deferred/SqlDataUpdate.php
includes/exception/MWExceptionHandler.php
includes/installer/i18n/ne.json
includes/page/WikiPage.php
includes/parser/Parser.php
includes/parser/ParserOptions.php
includes/profiler/TransactionProfiler.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderImage.php
includes/skins/Skin.php
includes/skins/SkinTemplate.php
includes/specials/SpecialBlockList.php
includes/specials/SpecialEditWatchlist.php
jsduck.json
languages/i18n/be-tarask.json
languages/i18n/bgn.json
languages/i18n/bho.json
languages/i18n/cu.json
languages/i18n/cv.json
languages/i18n/en.json
languages/i18n/hi.json
languages/i18n/ja.json
languages/i18n/lrc.json
languages/i18n/ne.json
languages/i18n/pl.json
languages/i18n/ps.json
languages/i18n/qqq.json
languages/i18n/sah.json
languages/i18n/uk.json
languages/i18n/yue.json
languages/messages/MessagesBgn.php
languages/messages/MessagesFa.php
languages/messages/MessagesLrc.php
maintenance/jsduck/categories.json
resources/Resources.php
resources/src/mediawiki.messagePoster/mediawiki.messagePoster.MessagePoster.js [new file with mode: 0644]
resources/src/mediawiki.messagePoster/mediawiki.messagePoster.WikitextMessagePoster.js [new file with mode: 0644]
resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js [new file with mode: 0644]
resources/src/mediawiki/mediawiki.feedback.js
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/objectcache/BagOStuffTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderImageTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/qunit/QUnitTestResources.php
tests/qunit/suites/resources/mediawiki/mediawiki.messagePoster.factory.test.js [new file with mode: 0644]

diff --git a/CREDITS b/CREDITS
index f58fabb..54890fe 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -56,6 +56,7 @@ following names for their contribution to the product.
 * Marius Hoch
 * Matěj Grabovský
 * Matt Johnston
+* Matthew Flaschen
 * Max Semenik
 * Meno25
 * MinuteElectron
index 1ec8b93..4612c45 100644 (file)
@@ -119,6 +119,9 @@ production.
   proper, published library, which is now tagged as v1.0.0.
 * A new message (defaulting to blank), 'editnotice-notext', can be shown to users
   when they are editing if no edit notices apply to the page being edited.
+* (T94536) You can now make the sitenotice appear to logged-in users only by
+  editing MediaWiki:Anonnotice and replacing its content with "". Setting it to
+  "-" (default) will continue disable it and fallback to MediaWiki:Sitenotice.
 
 ==== External libraries ====
 * MediaWiki now requires certain external libraries to be installed. In the past
@@ -424,6 +427,8 @@ changes to languages because of Bugzilla reports.
   retrievedfrom, thisisdeleted, viewsourcelink, lastmodifiedat, laggedslavemode,
   protect-summary-cascade
 * All BloomCache related code has been removed. This was largely experimental.
+* $wgResourceModuleSkinStyles no longer supports per-module local or remote paths. They
+  can only be set for the entire skin.
 
 == Compatibility ==
 
index d646a0e..1e62ccc 100644 (file)
@@ -698,11 +698,11 @@ $wgAutoloadLocalClasses = array(
        'MWLoggerFactory' => __DIR__ . '/includes/debug/logger/Shims.php',
        'MWLoggerLegacyLogger' => __DIR__ . '/includes/debug/logger/Shims.php',
        'MWLoggerLegacySpi' => __DIR__ . '/includes/debug/logger/Shims.php',
-       'MWLoggerMonologHandler' => __DIR__ . '/includes/debug/logger/Shims.php',
-       'MWLoggerMonologLegacyFormatter' => __DIR__ . '/includes/debug/logger/Shims.php',
-       'MWLoggerMonologProcessor' => __DIR__ . '/includes/debug/logger/Shims.php',
-       'MWLoggerMonologSpi' => __DIR__ . '/includes/debug/logger/Shims.php',
-       'MWLoggerMonologSyslogHandler' => __DIR__ . '/includes/debug/logger/Shims.php',
+       'MWLoggerMonologHandler' => __DIR__ . '/includes/debug/logger/monolog/Shims.php',
+       'MWLoggerMonologLegacyFormatter' => __DIR__ . '/includes/debug/logger/monolog/Shims.php',
+       'MWLoggerMonologProcessor' => __DIR__ . '/includes/debug/logger/monolog/Shims.php',
+       'MWLoggerMonologSpi' => __DIR__ . '/includes/debug/logger/monolog/Shims.php',
+       'MWLoggerMonologSyslogHandler' => __DIR__ . '/includes/debug/logger/monolog/Shims.php',
        'MWLoggerNullSpi' => __DIR__ . '/includes/debug/logger/Shims.php',
        'MWLoggerSpi' => __DIR__ . '/includes/debug/logger/Shims.php',
        'MWMemcached' => __DIR__ . '/includes/objectcache/MemcachedClient.php',
index 4698f45..873a26d 100644 (file)
@@ -442,19 +442,33 @@ class Block {
                        $dbw = wfGetDB( DB_MASTER );
                }
 
-               # Don't collide with expired blocks
-               Block::purgeExpired();
+               # Periodic purge via commit hooks
+               if ( mt_rand( 0, 9 ) == 0 ) {
+                       Block::purgeExpired();
+               }
 
                $row = $this->getDatabaseArray();
                $row['ipb_id'] = $dbw->nextSequenceValue( "ipblocks_ipb_id_seq" );
 
-               $dbw->insert(
-                       'ipblocks',
-                       $row,
-                       __METHOD__,
-                       array( 'IGNORE' )
-               );
+               $dbw->insert( 'ipblocks', $row, __METHOD__, array( 'IGNORE' ) );
                $affected = $dbw->affectedRows();
+
+               # Don't collide with expired blocks.
+               # Do this after trying to insert to avoid pointless gap locks.
+               if ( !$affected ) {
+                       $dbw->delete( 'ipblocks',
+                               array(
+                                       'ipb_address' => $row['ipb_address'],
+                                       'ipb_user' => $row['ipb_user'],
+                                       'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() )
+                               ),
+                               __METHOD__
+                       );
+
+                       $dbw->insert( 'ipblocks', $row, __METHOD__, array( 'IGNORE' ) );
+                       $affected = $dbw->affectedRows();
+               }
+
                $this->mId = $dbw->insertId();
 
                if ( $affected ) {
index fe67adf..c8197f2 100644 (file)
@@ -3338,8 +3338,6 @@ $wgResourceModules = array();
  *
  * As with $wgResourceModules, paths default to being relative to the MediaWiki root.
  * You should always provide a localBasePath and remoteBasePath (or remoteExtPath/remoteSkinPath).
- * Either for all skin styles at once (first example below) or for each module separately (second
- * example).
  *
  * @par Example:
  * @code
@@ -3349,19 +3347,6 @@ $wgResourceModules = array();
  *     'remoteSkinPath' => 'Foo',
  *     'localBasePath' => __DIR__,
  *   );
- *
- *   $wgResourceModuleSkinStyles['foo'] = array(
- *     'bar' => array(
- *       'bar.css',
- *       'remoteSkinPath' => 'Foo',
- *       'localBasePath' => __DIR__,
- *     ),
- *     'quux' => array(
- *       'quux.css',
- *       'remoteSkinPath' => 'Foo',
- *       'localBasePath' => __DIR__,
- *     ),
- *   );
  * @endcode
  */
 $wgResourceModuleSkinStyles = array();
index 68d03c8..86531bb 100644 (file)
@@ -529,7 +529,7 @@ class MediaWiki {
                                        wfDebugLog( 'RedirectedPosts', "Redirected from HTTP to HTTPS: $oldUrl" );
                                }
                                // Setup dummy Title, otherwise OutputPage::redirect will fail
-                               $title = Title::newFromText( NS_MAIN, 'REDIR' );
+                               $title = Title::newFromText( 'REDIR', NS_MAIN );
                                $this->context->setTitle( $title );
                                $output = $this->context->getOutput();
                                // Since we only do this redir to change proto, always send a vary header
index 322f8af..4ada6b1 100644 (file)
@@ -452,7 +452,7 @@ class User implements IDBAccessObject {
                // The cache needs good consistency due to its high TTL, so the user
                // should have been loaded from the master to avoid lag amplification.
                if ( !( $this->queryFlagsUsed & self::READ_LATEST ) ) {
-                       wfWarn( "Cannot save slave-loaded User object data to cache." );
+                       wfWarn( "Cannot cache slave-loaded User object with ID '{$this->mId}'." );
                        return;
                }
 
@@ -2233,9 +2233,15 @@ class User implements IDBAccessObject {
         * user_touched field when we update things.
         * @return string Timestamp in TS_MW format
         */
-       private static function newTouchedTimestamp() {
+       private function newTouchedTimestamp() {
                global $wgClockSkewFudge;
-               return wfTimestamp( TS_MW, time() + $wgClockSkewFudge );
+
+               $time = wfTimestamp( TS_MW, time() + $wgClockSkewFudge );
+               if ( $this->mTouched && $time <= $this->mTouched ) {
+                       $time = wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $this->mTouched ) + 1 );
+               }
+
+               return $time;
        }
 
        /**
@@ -2265,7 +2271,7 @@ class User implements IDBAccessObject {
                }
                $this->load();
                if ( $this->mId ) {
-                       $this->mTouched = self::newTouchedTimestamp();
+                       $this->mTouched = $this->newTouchedTimestamp();
 
                        $dbw = wfGetDB( DB_MASTER );
                        $userid = $this->mId;
@@ -2307,7 +2313,7 @@ class User implements IDBAccessObject {
 
                if ( $this->mId ) {
                        $key = wfMemcKey( 'user-quicktouched', 'id', $this->mId );
-                       $timestamp = self::newTouchedTimestamp();
+                       $timestamp = $this->newTouchedTimestamp();
                        $wgMemc->set( $key, $timestamp );
                        $this->mQuickTouched = $timestamp;
                }
@@ -3586,22 +3592,33 @@ class User implements IDBAccessObject {
                global $wgAuth;
 
                if ( wfReadOnly() ) {
-                       return; // @TODO: caller should deal with this instead!
+                       // @TODO: caller should deal with this instead!
+                       // This should really just be an exception.
+                       MWExceptionHandler::logException( new DBExpectedError(
+                               null,
+                               "Could not update user with ID '{$this->mId}'; DB is read-only."
+                       ) );
+                       return;
                }
 
                $this->load();
                $this->loadPasswords();
                if ( 0 == $this->mId ) {
-                       return;
+                       return; // anon
                }
 
                // This method is for updating existing users, so the user should
                // have been loaded from the master to begin with to avoid problems.
                if ( !( $this->queryFlagsUsed & self::READ_LATEST ) ) {
-                       wfWarn( "Attempting to save slave-loaded User object data." );
+                       wfWarn( "Attempting to save slave-loaded User object with ID '{$this->mId}'." );
                }
 
-               $this->mTouched = self::newTouchedTimestamp();
+               // Get a new user_touched that is higher than the old one.
+               // This will be used for a CAS check as a last-resort safety
+               // check against race conditions and slave lag.
+               $oldTouched = $this->mTouched;
+               $this->mTouched = $this->newTouchedTimestamp();
+
                if ( !$wgAuth->allowSetLocalPassword() ) {
                        $this->mPassword = self::getPasswordFactory()->newFromCiphertext( null );
                }
@@ -3622,10 +3639,22 @@ class User implements IDBAccessObject {
                                'user_email_token_expires' => $dbw->timestampOrNull( $this->mEmailTokenExpires ),
                                'user_password_expires' => $dbw->timestampOrNull( $this->mPasswordExpires ),
                        ), array( /* WHERE */
-                               'user_id' => $this->mId
+                               'user_id' => $this->mId,
+                               'user_touched' => $dbw->timestamp( $oldTouched ) // CAS check
                        ), __METHOD__
                );
 
+               if ( !$dbw->affectedRows() ) {
+                       // User was changed in the meantime or loaded with stale data
+                       MWExceptionHandler::logException( new MWException(
+                               "CAS update failed on user_touched for user ID '{$this->mId}'."
+                       ) );
+                       // Maybe the problem was a missed cache update; clear it to be safe
+                       $this->clearSharedCache();
+
+                       return;
+               }
+
                $this->saveOptions();
 
                Hooks::run( 'UserSaveSettings', array( $this ) );
@@ -3694,7 +3723,7 @@ class User implements IDBAccessObject {
                        'user_token' => strval( $user->mToken ),
                        'user_registration' => $dbw->timestamp( $user->mRegistration ),
                        'user_editcount' => 0,
-                       'user_touched' => $dbw->timestamp( self::newTouchedTimestamp() ),
+                       'user_touched' => $dbw->timestamp( $user->newTouchedTimestamp() ),
                );
                foreach ( $params as $name => $value ) {
                        $fields["user_$name"] = $value;
@@ -3741,7 +3770,7 @@ class User implements IDBAccessObject {
                        $this->setToken(); // init token
                }
 
-               $this->mTouched = self::newTouchedTimestamp();
+               $this->mTouched = $this->newTouchedTimestamp();
 
                $dbw = wfGetDB( DB_MASTER );
                $inWrite = $dbw->writesOrCallbacksPending();
index f697b6f..ef8957e 100644 (file)
@@ -28,7 +28,9 @@
  * A module that allows for editing and creating pages.
  *
  * Currently, this wraps around the EditPage class in an ugly way,
- * EditPage.php should be rewritten to provide a cleaner interface
+ * EditPage.php should be rewritten to provide a cleaner interface,
+ * see T20654 if you're inspired to fix this.
+ *
  * @ingroup API
  */
 class ApiEditPage extends ApiBase {
index 1feb485..2978453 100644 (file)
@@ -416,7 +416,13 @@ class ApiMain extends ApiBase {
                // Bug 63145: Rollback any open database transactions
                if ( !( $e instanceof UsageException ) ) {
                        // UsageExceptions are intentional, so don't rollback if that's the case
-                       MWExceptionHandler::rollbackMasterChangesAndLog( $e );
+                       try {
+                               MWExceptionHandler::rollbackMasterChangesAndLog( $e );
+                       } catch ( DBError $e2 ) {
+                               // Rollback threw an exception too. Log it, but don't interrupt
+                               // our regularly scheduled exception handling.
+                               MWExceptionHandler::logException( $e2 );
+                       }
                }
 
                // Allow extra cleanup and logging
index adf96fd..a9349b1 100644 (file)
@@ -366,11 +366,11 @@ class ApiQueryLogEvents extends ApiQueryBase {
                                                unset( $params[$idsKey] );
                                        }
                                        if ( isset( $params[$ofieldKey] ) ) {
-                                               $params[] = $params[$ofieldKey];
+                                               $params[] = 'ofield=' . $params[$ofieldKey];
                                                unset( $params[$ofieldKey] );
                                        }
                                        if ( isset( $params[$nfieldKey] ) ) {
-                                               $params[] = $params[$nfieldKey];
+                                               $params[] = 'nfield=' . $params[$nfieldKey];
                                                unset( $params[$nfieldKey] );
                                        }
                                }
index 5ac1036..d4f7e6a 100644 (file)
@@ -674,8 +674,14 @@ class ApiQuerySiteinfo extends ApiQueryBase {
 
        protected function appendRightsInfo( $property ) {
                $config = $this->getConfig();
-               $title = Title::newFromText( $config->get( 'RightsPage' ) );
-               $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $config->get( 'RightsUrl' );
+               $rightsPage = $config->get( 'RightsPage' );
+               if ( is_string( $rightsPage ) ) {
+                       $title = Title::newFromText( $rightsPage );
+                       $url = wfExpandUrl( $title, PROTO_CURRENT );
+               } else {
+                       $title = false;
+                       $url = $config->get( 'RightsUrl' );
+               }
                $text = $config->get( 'RightsText' );
                if ( !$text && $title ) {
                        $text = $title->getPrefixedText();
index 318cd96..d097477 100644 (file)
        "api-help-param-list": "{{PLURAL:$1|1=Un valor|2=Valores (separados por <kbd>{{!}}</kbd>)}}: $2",
        "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Debe estar vacío|Puede estar vacío, o $2}}",
        "api-help-param-multi-separate": "Separar los valores con <kbd>|</kbd>.",
-       "api-help-examples": "{{PLURAL:$1|Ejemplo|Ejemplos}}:"
+       "api-help-param-default": "Predeterminado: $1",
+       "api-help-param-default-empty": "Predeterminado: <span class=\"apihelp-empty\">(vacío)</span>",
+       "api-help-param-no-description": "<span class=\"apihelp-empty\">(sin descripción)</span>",
+       "api-help-examples": "{{PLURAL:$1|Ejemplo|Ejemplos}}:",
+       "api-help-permissions": "{{PLURAL:$1|Permiso|Permisos}}:",
+       "api-help-permissions-granted-to": "{{PLURAL:$1|Concedido a|Concedidos a}}: $2",
+       "api-credits-header": "Créditos",
+       "api-credits": "Desarrolladores de la API:\n* Roan Kattouw (desarrollador principal sep 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (creador, desarrollador principal sep 2006–sep 2007)\n* Brad Jorsch (desarrollador principal 2013–actualidad)\n\nEnvía comentarios, sugerencias y preguntas a mediawiki-api@lists.wikimedia.org\no reporta un error en https://phabricator.wikimedia.org/."
 }
index e0e32f5..3940469 100644 (file)
@@ -4,7 +4,8 @@
                        "Shirayuki",
                        "2nd-player",
                        "Los688",
-                       "Whym"
+                       "Whym",
+                       "Mfuji"
                ]
        },
        "apihelp-main-param-action": "実行する操作です。",
        "apihelp-move-param-from": "移動するページのページ名です。<var>$1fromid</var> とは同時に使用できません。",
        "apihelp-move-param-fromid": "移動するページのページIDです。<var>$1from</var> とは同時に使用できません。",
        "apihelp-move-param-to": "移動後のページ名。",
-       "apihelp-move-param-reason": "移動の理由。",
+       "apihelp-move-param-reason": "名称変更の理由。",
        "apihelp-move-param-movetalk": "存在する場合、トークページも名前を変更します。",
        "apihelp-move-param-movesubpages": "可能であれば、下位ページも名前を変更します。",
        "apihelp-move-param-noredirect": "転送ページを作成しません。",
index fc92c43..1a5c897 100644 (file)
@@ -8,7 +8,8 @@
                        "Devwebtel",
                        "Macofe",
                        "Pio387",
-                       "Peter Bowman"
+                       "Peter Bowman",
+                       "Darellur"
                ]
        },
        "apihelp-main-param-action": "Wybierz akcję do wykonania.",
@@ -32,6 +33,8 @@
        "apihelp-edit-param-minor": "Drobna zmiana.",
        "apihelp-edit-param-notminor": "Nie drobna zmiana.",
        "apihelp-edit-param-bot": "Oznacz tę edycję jako edycję bota.",
+       "apihelp-edit-param-watch": "Dodaj stronę do aktualnej listy obserwacji użytkownika.",
+       "apihelp-edit-param-unwatch": "Usuń stronę z aktualnej listy obserwacji użytkownika.",
        "apihelp-edit-example-edit": "Edytuj stronę",
        "apihelp-emailuser-description": "Wyślij e‐mail do użytkownika.",
        "apihelp-feedrecentchanges-example-simple": "Pokaż ostatnie zmiany.",
index c78b0dc..0476d0f 100644 (file)
@@ -100,56 +100,6 @@ class MWLoggerLegacyLogger extends \MediaWiki\Logger\LegacyLogger {
 class MWLoggerLegacySpi extends \MediaWiki\Logger\LegacySpi {
 }
 
-/**
- * Backwards compatibility stub for usage from before the introduction of
- * the MediaWiki\Logger namespace.
- *
- * @deprecated since 1.25 Use \MediaWiki\Logger\Monolog\LegacyHandler
- * @todo This class should be removed before the 1.25 final release.
- */
-class MWLoggerMonologHandler extends \MediaWiki\Logger\Monolog\LegacyHandler {
-}
-
-/**
- * Backwards compatibility stub for usage from before the introduction of
- * the MediaWiki\Logger namespace.
- *
- * @deprecated since 1.25 Use \MediaWiki\Logger\Monolog\LegacyFormatter
- * @todo This class should be removed before the 1.25 final release.
- */
-class MWLoggerMonologLegacyFormatter extends \MediaWiki\Logger\Monolog\LegacyFormatter {
-}
-
-/**
- * Backwards compatibility stub for usage from before the introduction of
- * the MediaWiki\Logger namespace.
- *
- * @deprecated since 1.25 Use \MediaWiki\Logger\Monolog\WikiProcessor
- * @todo This class should be removed before the 1.25 final release.
- */
-class MWLoggerMonologProcessor extends \MediaWiki\Logger\Monolog\WikiProcessor {
-}
-
-/**
- * Backwards compatibility stub for usage from before the introduction of
- * the MediaWiki\Logger namespace.
- *
- * @deprecated since 1.25 Use \MediaWiki\Logger\MonologSpi
- * @todo This class should be removed before the 1.25 final release.
- */
-class MWLoggerMonologSpi extends \MediaWiki\Logger\MonologSpi {
-}
-
-/**
- * Backwards compatibility stub for usage from before the introduction of
- * the MediaWiki\Logger namespace.
- *
- * @deprecated since 1.25 Use \MediaWiki\Logger\Monolog\SyslogHandler
- * @todo This class should be removed before the 1.25 final release.
- */
-class MWLoggerMonologSyslogHandler extends \MediaWiki\Logger\Monolog\SyslogHandler {
-}
-
 /**
  * Backwards compatibility stub for usage from before the introduction of
  * the MediaWiki\Logger namespace.
diff --git a/includes/debug/logger/monolog/Shims.php b/includes/debug/logger/monolog/Shims.php
new file mode 100644 (file)
index 0000000..f250713
--- /dev/null
@@ -0,0 +1,69 @@
+<?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
+ */
+
+/**
+ * Backwards compatibility stub for usage from before the introduction of
+ * the MediaWiki\Logger namespace.
+ *
+ * @deprecated since 1.25 Use \MediaWiki\Logger\Monolog\LegacyHandler
+ * @todo This class should be removed before the 1.25 final release.
+ */
+class MWLoggerMonologHandler extends \MediaWiki\Logger\Monolog\LegacyHandler {
+}
+
+/**
+ * Backwards compatibility stub for usage from before the introduction of
+ * the MediaWiki\Logger namespace.
+ *
+ * @deprecated since 1.25 Use \MediaWiki\Logger\Monolog\LegacyFormatter
+ * @todo This class should be removed before the 1.25 final release.
+ */
+class MWLoggerMonologLegacyFormatter extends \MediaWiki\Logger\Monolog\LegacyFormatter {
+}
+
+/**
+ * Backwards compatibility stub for usage from before the introduction of
+ * the MediaWiki\Logger namespace.
+ *
+ * @deprecated since 1.25 Use \MediaWiki\Logger\Monolog\WikiProcessor
+ * @todo This class should be removed before the 1.25 final release.
+ */
+class MWLoggerMonologProcessor extends \MediaWiki\Logger\Monolog\WikiProcessor {
+}
+
+/**
+ * Backwards compatibility stub for usage from before the introduction of
+ * the MediaWiki\Logger namespace.
+ *
+ * @deprecated since 1.25 Use \MediaWiki\Logger\MonologSpi
+ * @todo This class should be removed before the 1.25 final release.
+ */
+class MWLoggerMonologSpi extends \MediaWiki\Logger\MonologSpi {
+}
+
+/**
+ * Backwards compatibility stub for usage from before the introduction of
+ * the MediaWiki\Logger namespace.
+ *
+ * @deprecated since 1.25 Use \MediaWiki\Logger\Monolog\SyslogHandler
+ * @todo This class should be removed before the 1.25 final release.
+ */
+class MWLoggerMonologSyslogHandler extends \MediaWiki\Logger\Monolog\SyslogHandler {
+}
index 5823b2e..49164e3 100644 (file)
@@ -111,39 +111,40 @@ abstract class SqlDataUpdate extends DataUpdate {
                        return;
                }
 
-               /**
-                * Determine which pages need to be updated
-                * This is necessary to prevent the job queue from smashing the DB with
-                * large numbers of concurrent invalidations of the same page
-                */
-               $now = $this->mDb->timestamp();
-               $ids = array();
-               $res = $this->mDb->select( 'page', array( 'page_id' ),
-                       array(
-                               'page_namespace' => $namespace,
-                               'page_title' => $dbkeys,
-                               'page_touched < ' . $this->mDb->addQuotes( $now )
-                       ), __METHOD__
-               );
-
-               foreach ( $res as $row ) {
-                       $ids[] = $row->page_id;
-               }
-
-               if ( $ids === array() ) {
-                       return;
-               }
-
-               /**
-                * Do the update
-                * We still need the page_touched condition, in case the row has changed since
-                * the non-locking select above.
-                */
-               $this->mDb->update( 'page', array( 'page_touched' => $now ),
-                       array(
-                               'page_id' => $ids,
-                               'page_touched < ' . $this->mDb->addQuotes( $now )
-                       ), __METHOD__
-               );
+               $dbw = $this->mDb;
+               $dbw->onTransactionPreCommitOrIdle( function() use ( $dbw, $namespace, $dbkeys ) {
+                       /**
+                        * Determine which pages need to be updated
+                        * This is necessary to prevent the job queue from smashing the DB with
+                        * large numbers of concurrent invalidations of the same page
+                        */
+                       $now = $dbw->timestamp();
+                       $ids = $dbw->selectFieldValues( 'page',
+                               'page_id',
+                               array(
+                                       'page_namespace' => $namespace,
+                                       'page_title' => $dbkeys,
+                                       'page_touched < ' . $dbw->addQuotes( $now )
+                               ),
+                               __METHOD__
+                       );
+
+                       if ( $ids === array() ) {
+                               return;
+                       }
+
+                       /**
+                        * Do the update
+                        * We still need the page_touched condition, in case the row has changed since
+                        * the non-locking select above.
+                        */
+                       $dbw->update( 'page',
+                               array( 'page_touched' => $now ),
+                               array(
+                                       'page_id' => $ids,
+                                       'page_touched < ' . $dbw->addQuotes( $now )
+                               ), __METHOD__
+                       );
+               } );
        }
 }
index ed0f3c2..c50b6c8 100644 (file)
@@ -150,22 +150,24 @@ class MWExceptionHandler {
         * @since 1.25
         * @param Exception $e
         */
-       public static function handleException( $e ) {
-               global $wgFullyInitialised;
+       public static function handleException( Exception $e ) {
+               try {
+                       // Rollback DBs to avoid transaction notices. This may fail
+                       // to rollback some DB due to connection issues or exceptions.
+                       // However, any sane DB driver will rollback implicitly anyway.
+                       self::rollbackMasterChangesAndLog( $e );
+               } catch ( DBError $e2 ) {
+                       // If the DB is unreacheable, rollback() will throw an error
+                       // and the error report() method might need messages from the DB,
+                       // which would result in an exception loop. PHP may escalate such
+                       // errors to "Exception thrown without a stack frame" fatals, but
+                       // it's better to be explicit here.
+                       self::logException( $e2 );
+               }
 
-               self::rollbackMasterChangesAndLog( $e );
                self::logException( $e );
                self::report( $e );
 
-               // Final cleanup
-               if ( $wgFullyInitialised ) {
-                       try {
-                               // uses $wgRequest, hence the $wgFullyInitialised condition
-                               wfLogProfilingData();
-                       } catch ( Exception $e ) {
-                       }
-               }
-
                // Exit value should be nonzero for the benefit of shell jobs
                exit( 1 );
        }
index 836e0fc..b3d40d2 100644 (file)
        "config-your-language": "तपाईंको भाषा:",
        "config-your-language-help": "इन्स्टल गर्दा उपयोग गर्ने भाषा छान्नुहोस् ।",
        "config-wiki-language": "विकि भाषाहरू",
+       "config-back": "← पछाडी",
+       "config-continue": "जारी राख्ने →",
+       "config-page-language": "भाषा",
+       "config-page-welcome": "मिडीयाविकिमा तपाईंलाई स्वागत छ!",
+       "config-page-dbconnect": "डेटाबेससँग सम्बन्ध बनाउने",
        "config-page-name": "नाम",
        "config-page-options": "विकल्पहरु",
        "config-page-install": "स्थापना गर्ने",
@@ -20,6 +25,7 @@
        "config-page-restart": "स्थापना फेरि सुरु गर्ने",
        "config-page-readme": "पढ्नुहोस्",
        "config-page-releasenotes": "प्रकाशन टिप्पणी",
+       "config-help": "सहायता",
        "config-help-tooltip": "विस्तार गर्न क्लीक गर्नुहोस्",
        "mainpagetext": "'''मीडिया सफलतापूर्वक कम्प्यूटरमा स्थापित भयो ।'''",
        "mainpagedocfooter": " विकी अनुप्रयोग कसरी प्रयोग गर्ने भन्ने जानकारीको लागि  [//meta.wikimedia.org/wiki/Help:Contents प्रयोगकर्ता सहायता] हेर्नुहोस्\n\n== सुरू गर्नको लागि  ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings विन्यास सेटिङ्ग सूची]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ मेडियाविकि सामान्य प्रश्नका उत्तरहरु]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce मेडियाविकि सुचना मेलिङ्ग सूची]"
index b435c5c..5caffab 100644 (file)
@@ -367,14 +367,12 @@ class WikiPage implements Page, IDBAccessObject {
                        $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
                } elseif ( $from === self::READ_NORMAL ) {
                        $data = $this->pageDataFromTitle( wfGetDB( DB_SLAVE ), $this->mTitle );
-                       // Use a "last rev inserted" timestamp key to diminish the issue of slave lag.
-                       // Note that DB also stores the master position in the session and checks it.
-                       $touched = $this->getCachedLastEditTime();
-                       if ( $touched ) { // key set
-                               if ( !$data || $touched > wfTimestamp( TS_MW, $data->page_touched ) ) {
-                                       $from = self::READ_LATEST;
-                                       $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
-                               }
+                       if ( !$data
+                               && wfGetLB()->getServerCount() > 1
+                               && wfGetLB()->hasOrMadeRecentMasterChanges()
+                       ) {
+                               $from = self::READ_LATEST;
+                               $data = $this->pageDataFromTitle( wfGetDB( DB_MASTER ), $this->mTitle );
                        }
                } else {
                        // No idea from where the caller got this data, assume slave database.
@@ -810,29 +808,6 @@ class WikiPage implements Page, IDBAccessObject {
                }
        }
 
-       /**
-        * Get the cached timestamp for the last time the page changed.
-        * This is only used to help handle slave lag by comparing to page_touched.
-        * @return string MW timestamp
-        */
-       protected function getCachedLastEditTime() {
-               global $wgMemc;
-               $key = wfMemcKey( 'page-lastedit', md5( $this->mTitle->getPrefixedDBkey() ) );
-               return $wgMemc->get( $key );
-       }
-
-       /**
-        * Set the cached timestamp for the last time the page changed.
-        * This is only used to help handle slave lag by comparing to page_touched.
-        * @param string $timestamp
-        * @return void
-        */
-       public function setCachedLastEditTime( $timestamp ) {
-               global $wgMemc;
-               $key = wfMemcKey( 'page-lastedit', md5( $this->mTitle->getPrefixedDBkey() ) );
-               $wgMemc->set( $key, wfTimestamp( TS_MW, $timestamp ), 60 * 15 );
-       }
-
        /**
         * Determine whether a page would be suitable for being counted as an
         * article in the site_stats table based on the title & its content
@@ -1311,7 +1286,6 @@ class WikiPage implements Page, IDBAccessObject {
                if ( $result ) {
                        $this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect );
                        $this->setLastEdit( $revision );
-                       $this->setCachedLastEditTime( $now );
                        $this->mLatest = $revision->getId();
                        $this->mIsRedirect = (bool)$rt;
                        // Update the LinkCache.
@@ -1513,8 +1487,18 @@ class WikiPage implements Page, IDBAccessObject {
 
                $baseRevId = null;
                if ( $edittime && $sectionId !== 'new' ) {
-                       $dbw = wfGetDB( DB_MASTER );
-                       $rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime );
+                       $dbr = wfGetDB( DB_SLAVE );
+                       $rev = Revision::loadFromTimestamp( $dbr, $this->mTitle, $edittime );
+                       // Try the master if this thread may have just added it.
+                       // This could be abstracted into a Revision method, but we don't want
+                       // to encourage loading of revisions by timestamp.
+                       if ( !$rev
+                               && wfGetLB()->getServerCount() > 1
+                               && wfGetLB()->hasOrMadeRecentMasterChanges()
+                       ) {
+                               $dbw = wfGetDB( DB_MASTER );
+                               $rev = Revision::loadFromTimestamp( $dbw, $this->mTitle, $edittime );
+                       }
                        if ( $rev ) {
                                $baseRevId = $rev->getId();
                        }
@@ -1553,10 +1537,7 @@ class WikiPage implements Page, IDBAccessObject {
                        if ( is_null( $baseRevId ) || $sectionId === 'new' ) {
                                $oldContent = $this->getContent();
                        } else {
-                               // TODO: try DB_SLAVE first
-                               $dbw = wfGetDB( DB_MASTER );
-                               $rev = Revision::loadFromId( $dbw, $baseRevId );
-
+                               $rev = Revision::newFromId( $baseRevId );
                                if ( !$rev ) {
                                        wfDebug( __METHOD__ . " asked for bogus section (page: " .
                                                $this->getId() . "; section: $sectionId)\n" );
index 7c221d8..ace63a0 100644 (file)
@@ -4945,7 +4945,7 @@ class Parser {
        /**
         * Clean up signature text
         *
-        * 1) Strip ~~~, ~~~~ and ~~~~~ out of signatures @see cleanSigInSig
+        * 1) Strip 3, 4 or 5 tildes out of signatures @see cleanSigInSig
         * 2) Substitute all transclusions
         *
         * @param string $text
@@ -4984,7 +4984,7 @@ class Parser {
        }
 
        /**
-        * Strip ~~~, ~~~~ and ~~~~~ out of signatures
+        * Strip 3, 4 or 5 tildes out of signatures.
         *
         * @param string $text
         * @return string Signature text with /~{3,5}/ removed
index 5fa52ff..100656d 100644 (file)
@@ -145,9 +145,7 @@ class ParserOptions {
 
        /**
         * Clean up signature texts?
-        *
-        * 1) Strip ~~~, ~~~~ and ~~~~~ out of signatures
-        * 2) Substitute all transclusions
+        * @see Parser::cleanSig
         */
        public $mCleanSignatures;
 
index baec181..f02d66f 100644 (file)
@@ -263,10 +263,12 @@ class TransactionProfiler implements LoggerAwareInterface {
         * @param string $query
         */
        protected function reportExpectationViolated( $expect, $query ) {
+               global $wgRequest;
+
                $n = $this->expect[$expect];
                $by = $this->expectBy[$expect];
                $this->logger->info(
-                       "Expectation ($expect <= $n) by $by not met:\n$query\n" . wfBacktrace( true )
+                       "[{$wgRequest->getMethod()}] Expectation ($expect <= $n) by $by not met:\n$query\n" . wfBacktrace( true )
                );
        }
 }
index b9d1b2b..3d5cc51 100644 (file)
@@ -346,12 +346,9 @@ class ResourceLoader {
                                        }
 
                                        // Add new file paths, remapping them to refer to our directories and not use settings
-                                       // from the module we're modifying. These can come from the base definition or be defined
-                                       // for each module.
+                                       // from the module we're modifying, which come from the base definition.
                                        list( $localBasePath, $remoteBasePath ) =
                                                ResourceLoaderFileModule::extractBasePaths( $skinStyles );
-                                       list( $localBasePath, $remoteBasePath ) =
-                                               ResourceLoaderFileModule::extractBasePaths( $paths, $localBasePath, $remoteBasePath );
 
                                        foreach ( $paths as $path ) {
                                                $styleFiles[] = new ResourceLoaderFilePath( $path, $localBasePath, $remoteBasePath );
@@ -1095,23 +1092,19 @@ MESSAGE;
                } elseif ( !is_array( $scripts ) ) {
                        throw new MWException( 'Invalid scripts error. Array of URLs or string of code expected.' );
                }
-
-               return Xml::encodeJsCall(
-                       'mw.loader.implement',
-                       array(
-                               $name,
-                               $scripts,
-                               // Force objects. mw.loader.implement requires them to be javascript objects.
-                               // Although these variables are associative arrays, which become javascript
-                               // objects through json_encode. In many cases they will be empty arrays, and
-                               // PHP/json_encode() consider empty arrays to be numerical arrays and
-                               // output javascript "[]" instead of "{}". This fixes that.
-                               (object)$styles,
-                               (object)$messages,
-                               (object)$templates,
-                       ),
-                       ResourceLoader::inDebugMode()
+               // mw.loader.implement requires 'styles', 'messages' and 'templates' to be objects (not
+               // arrays). json_encode considers empty arrays to be numerical and outputs "[]" instead
+               // of "{}". Force them to objects.
+               $module = array(
+                       $name,
+                       $scripts,
+                       (object) $styles,
+                       (object) $messages,
+                       (object) $templates,
                );
+               self::trimArray( $module );
+
+               return Xml::encodeJsCall( 'mw.loader.implement', $module, ResourceLoader::inDebugMode() );
        }
 
        /**
@@ -1218,20 +1211,33 @@ MESSAGE;
                );
        }
 
+       private static function isEmptyObject( stdClass $obj ) {
+               foreach ( $obj as $key => &$value ) {
+                       return false;
+               }
+               return true;
+       }
+
        /**
         * Remove empty values from the end of an array.
         *
         * Values considered empty:
         *
         * - null
-        * - empty array
+        * - array()
+        * - new XmlJsCode( '{}' )
+        * - new stdClass() // (object) array()
         *
         * @param Array $array
         */
        private static function trimArray( Array &$array ) {
                $i = count( $array );
                while ( $i-- ) {
-                       if ( $array[$i] === null || $array[$i] === array() ) {
+                       if ( $array[$i] === null
+                               || $array[$i] === array()
+                               || ( $array[$i] instanceof XmlJsCode && $array[$i]->value === '{}' )
+                               || ( $array[$i] instanceof stdClass && self::isEmptyObject( $array[$i] ) )
+                       ) {
                                unset( $array[$i] );
                        } else {
                                break;
index d14b7a8..12d1e82 100644 (file)
@@ -53,6 +53,20 @@ class ResourceLoaderImage {
                $this->basePath = $basePath;
                $this->variants = $variants;
 
+               // Expand shorthands:
+               // array( "en,de,fr" => "foo.svg" ) → array( "en" => "foo.svg", "de" => "foo.svg", "fr" => "foo.svg" )
+               if ( is_array( $this->descriptor ) && isset( $this->descriptor['lang'] ) ) {
+                       foreach ( array_keys( $this->descriptor['lang'] ) as $langList ) {
+                               if ( strpos( $langList, ',' ) !== false ) {
+                                       $this->descriptor['lang'] += array_fill_keys(
+                                               explode( ',', $langList ),
+                                               $this->descriptor['lang'][ $langList ]
+                                       );
+                                       unset( $this->descriptor['lang'][ $langList ] );
+                               }
+                       }
+               }
+
                // Ensure that all files have common extension.
                $extensions = array();
                $descriptor = (array)$descriptor;
index dc25c6c..ac7a85b 100644 (file)
@@ -1477,7 +1477,8 @@ abstract class Skin extends ContextSource {
         * Get a cached notice
         *
         * @param string $name Message name, or 'default' for $wgSiteNotice
-        * @return string HTML fragment
+        * @return string|bool HTML fragment, or false to indicate that the caller
+        *   should fall back to the next notice in its sequence
         */
        private function getCachedNotice( $name ) {
                global $wgRenderHashAppend, $parserMemc, $wgContLang;
@@ -1493,7 +1494,9 @@ abstract class Skin extends ContextSource {
                        }
                } else {
                        $msg = $this->msg( $name )->inContentLanguage();
-                       if ( $msg->isDisabled() ) {
+                       if ( $msg->isBlank() ) {
+                               return '';
+                       } elseif ( $msg->isDisabled() ) {
                                return false;
                        }
                        $notice = $msg->plain();
@@ -1554,13 +1557,13 @@ abstract class Skin extends ContextSource {
                                $siteNotice = $this->getCachedNotice( 'sitenotice' );
                        } else {
                                $anonNotice = $this->getCachedNotice( 'anonnotice' );
-                               if ( !$anonNotice ) {
+                               if ( $anonNotice === false ) {
                                        $siteNotice = $this->getCachedNotice( 'sitenotice' );
                                } else {
                                        $siteNotice = $anonNotice;
                                }
                        }
-                       if ( !$siteNotice ) {
+                       if ( $siteNotice === false ) {
                                $siteNotice = $this->getCachedNotice( 'default' );
                        }
                }
index b0390e9..61aad92 100644 (file)
@@ -717,7 +717,7 @@ class SkinTemplate extends Skin {
                        $text = $msg->text();
                } else {
                        global $wgContLang;
-                       $text = $wgContLang->getFormattedNsText(
+                       $text = $wgContLang->getConverter()->convertNamespace(
                                MWNamespace::getSubject( $title->getNamespace() ) );
                }
 
index 4583430..0ec144a 100644 (file)
@@ -113,11 +113,6 @@ class SpecialBlockList extends SpecialPage {
        }
 
        function showList() {
-               # Purge expired entries on one in every 10 queries
-               if ( !mt_rand( 0, 10 ) ) {
-                       Block::purgeExpired();
-               }
-
                $conds = array();
                # Is the user allowed to see hidden blocks?
                if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
@@ -398,6 +393,10 @@ class BlockListPager extends TablePager {
                        'join_conds' => array( 'user' => array( 'LEFT JOIN', 'user_id = ipb_by' ) )
                );
 
+               # Filter out any expired blocks
+               $db = $this->getDatabase();
+               $info['conds'][] = 'ipb_expiry > ' . $db->addQuotes( $db->timestamp() );
+
                # Is the user allowed to see hidden blocks?
                if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
                        $info['conds']['ipb_deleted'] = 0;
index ffe7892..910fe25 100644 (file)
@@ -344,7 +344,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
         */
        protected function getWatchlistInfo() {
                $titles = array();
-               $dbr = wfGetDB( DB_MASTER );
+               $dbr = wfGetDB( DB_SLAVE );
 
                $res = $dbr->select(
                        array( 'watchlist' ),
index 24ca33f..ae723e9 100644 (file)
@@ -15,6 +15,7 @@
                "resources/src/mediawiki.action",
                "resources/src/mediawiki.api",
                "resources/src/mediawiki.language",
+               "resources/src/mediawiki.messagePoster",
                "resources/src/mediawiki.page",
                "resources/src/mediawiki.special",
                "resources/src/mediawiki.toolbar",
index c1b6145..d9f2ae7 100644 (file)
        "prevn": "{{PLURAL:$1|папярэдняя|папярэднія|папярэднія}} $1",
        "nextn": "{{PLURAL:$1|наступная|наступныя|наступныя}} $1",
        "prev-page": "папярэдняя старонка",
+       "next-page": "наступная старонка",
        "prevn-title": "{{PLURAL:$1|Папярэдні $1 вынік|Папярэднія $1 вынікі|Папярэднія $1 вынікаў}}",
        "nextn-title": "{{PLURAL:$1|Наступны $1 вынік|Наступныя $1 вынікі|Наступныя $1 вынікаў}}",
        "shown-title": "Паказваць $1 {{PLURAL:$1|вынік|вынікі|вынікаў}} на старонцы",
index f86214f..e473177 100644 (file)
        "wrongpassword": "ای پاسورد یا چیهر گالا که داخل کورته ایت صحیح نه اینت.\nمهربانی بکنیت، پدا امتحان بکینت.",
        "wrongpasswordempty": "ای پاسورد یا چیهر گالا که داخل کورته ایت ، خالی اینت.\nمهربانی پدا کوشش بکنیت.",
        "passwordtooshort": "پاسورد باید کم شه کم {{PLURAL:$1|۱ حرف|$1 حرف}} داشته بیئت.",
+       "passwordtoolong": "پاسورد نه باید گیشتیر شه {{PLURAL:$1|۱ حرف|$1 حرفا}}  داشته بیئت.",
        "password-name-match": "شمی چیهرگال یا پاسورد باید شه شمی کار زورکی ئین ناما فرق داشته بیئت.",
        "password-login-forbidden": "استفاده شه ای کار زوروکی ناما و شه ای چیهرگالا اجازه نه اینت.",
        "mailmypassword": "پاک کورتین پاسوردئ",
index 3e003ed..c79c723 100644 (file)
        "template-protected": "(संरक्षित)",
        "template-semiprotected": "(अर्ध-सुरक्षित)",
        "nocreate-loggedin": "नया पन्ना बनावे रउआ अधिकार नइखे।",
+       "sectioneditnotsupported-title": "अनुभाग सम्पादन समर्थित नइखे",
+       "sectioneditnotsupported-text": "इ पन्ना पर अनुभाग सम्पादन समर्थित नइखे",
        "permissionserrors": "अनुमति त्रुटी",
+       "permissionserrorstext": "निम्नलिखित {{PLURAL:$1|कारण|कारणन}} के चलते आपके अइसन करे के अनुमति नइखे:",
        "log-fulllog": "पूरा लॉग देखीं",
        "edit-conflict": "संपादन अंतर्विरोध",
        "postedit-confirmation-created": "पन्ना बना दिहल गईल।",
        "postedit-confirmation-saved": "राउर सम्पादन सुरक्षित कर दिहल गईल।",
+       "defaultmessagetext": "संदेश के डिफ़ॉल्ट पाठ्य",
        "invalid-content-data": "अवैध डाटा सामग्री",
        "content-model-wikitext": "विकीपाठ्य",
        "content-model-text": "सामान्य पाठ",
index f59c963..144fcbe 100644 (file)
@@ -98,6 +98,7 @@
        "faqpage": "Project:Чѧстꙑ въпроси",
        "actions": "дѣиства",
        "namespaces": "имєнъ просторꙑ",
+       "navigation-heading": "плаваниѥ",
        "errorpagetitle": "блаꙁна",
        "tagline": "{{grammar:genitive|{{SITENAME}}}} страница",
        "help": "помощь",
        "userloginnocreate": "въниди",
        "logout": "ис̾ходъ",
        "userlogout": "ис̾ходъ",
+       "userlogin-noaccount": "мѣсто ти нѣстъ ли ?",
        "nologin": "мѣсто ти нѣстъ ли ? $1",
        "nologinlink": "съꙁижди си мѣсто",
        "createaccount": "съꙁижди си мѣсто",
        "accountcreated": "мѣсто сътворєно ѥстъ",
        "accountcreatedtext": "польꙃєватєльско мѣсто [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|бєсѣда]]) сътворєно бѣ",
        "loginlanguagelabel": "ѩꙁꙑкъ : $1",
+       "pt-login": "въниди",
+       "pt-login-button": "въниди",
+       "pt-createaccount": "съꙁижди си мѣсто",
        "pt-userlogout": "ис̾ходъ",
        "changepassword": "таина словєсє иꙁмѣнѥниѥ",
        "resetpass_header": "таина слова иꙁмѣнѥниѥ",
        "template-protected": "(ꙁабранєно ѥстъ)",
        "template-semiprotected": "(чѧстьно ꙁабранѥно)",
        "hiddencategories": "сꙗ страница въ {{PLURAL:$1|1 съкрꙑтѣи катигорїи|$1 съкрꙑтѣхъ катигорїѩ}} сѧ авлꙗѥтъ :",
+       "moveddeleted-notice": "сꙗ страница поничьжєна ѥстъ ⁙\nпоничьжєниꙗ и прѣимєнованиꙗ їстории си страницѧ нижѣ видѣти можєши",
        "postedit-confirmation-saved": "твоꙗ мѣна съхранѥна ѥстъ",
        "viewpagelogs": "си страницѧ їсторїѩ",
        "cur": "нꙑ҃н",
        "rightslog": "чинодатєльства їсторїꙗ",
        "action-edit": "си страницѧ исправлєниѥ",
        "nchanges": "$1 {{PLURAL:$1|мѣна|мѣнꙑ|мѣнъ}}",
+       "enhancedrc-history": "їсторїꙗ",
        "recentchanges": "послѣдьнѩ мѣнꙑ",
        "recentchanges-legend": "послѣдьн҄ь мѣнъ строи",
        "recentchanges-summary": "с҄ьдє послѣдьнѩ мѣнꙑ сѥѩ викиопꙑтьствованиꙗ видѣти можєши",
        "recentchanges-label-minor": "малаꙗ мѣна",
        "recentchanges-label-bot": "сѭ мѣноу аѵтоматъ сътворилъ",
        "rcshowhideminor": "$1 малꙑ мѣнꙑ",
+       "rcshowhideminor-show": "каꙁаниѥ",
+       "rcshowhideminor-hide": "съкрꙑтиѥ",
        "rcshowhidebots": "$1 аѵтоматъ",
+       "rcshowhidebots-show": "каꙁаниѥ",
+       "rcshowhidebots-hide": "съкрꙑтиѥ",
        "rcshowhideliu": "$1 польꙃєватєлъ · ѩжє съꙁижьдє сѥ мѣсто · мѣнꙑ",
+       "rcshowhideliu-hide": "съкрꙑтиѥ",
        "rcshowhideanons": "$1 анѡнѷмьнъ польꙃєватєлъ мѣнꙑ",
+       "rcshowhideanons-show": "каꙁаниѥ",
+       "rcshowhideanons-hide": "съкрꙑтиѥ",
        "rcshowhidemine": "$1 моꙗ мѣнꙑ",
+       "rcshowhidemine-show": "каꙁаниѥ",
+       "rcshowhidemine-hide": "съкрꙑтиѥ",
        "rclinks": "$1 послѣдьн҄ь  мѣнъ · ѩжє $2 послѣдьни дьни створѥнꙑ сѫтъ · каꙁаниѥ<br />$3",
        "diff": "ра҃ꙁн",
        "hist": "їс҃т",
        "minoreditletter": "м҃л",
        "newpageletter": "н҃в",
        "boteditletter": "а҃ѵ",
+       "rc-change-size-new": "$1 {{PLURAL:$1|баитъ|баита|баитъ}} послѣди мѣнꙑ",
        "rc-old-title": "напрьва страница створѥна ꙗко ⁖ $1 ⁖",
        "recentchangeslinked": "съвѧꙁанꙑ страницѧ",
        "recentchangeslinked-feed": "съвѧꙁанꙑ страницѧ",
        "movethispage": "си страницѧ прѣимєнованиѥ",
        "pager-newer-n": "{{PLURAL:$1|нова 1|новꙑ $1|новъ $1}}",
        "pager-older-n": "{{PLURAL:$1|давьнꙗ 1|давьни $1|давьн҄ь $1}}",
+       "booksources-search": "исканиѥ",
        "specialloguserlabel": "испльнитєл҄ь :",
        "speciallogtitlelabel": "страницѧ или польꙃєватєлꙗ имѧ :",
        "log": "їсторїѩ",
        "whatlinkshere-hidelinks": "$1 съвѧꙁи",
        "whatlinkshere-filters": "ситꙑ",
        "block": "ꙁагради польꙃєватєл҄ь",
-       "blockip": "ꙁагради польꙃєватєл҄ь",
+       "blockip": "ꙁагради {{GENDER:$1|польꙃєватєл҄ь}}",
        "blockip-legend": "ꙁагради польꙃєватєл҄ь",
        "ipaddressorusername": "IP число или польꙃєватєлꙗ имѧ :",
        "ipbreason": "какъ съмꙑслъ :",
        "logentry-move-move": "$1 {{GENDER:$2|нарєчє}} страницѫ ⁖ $3 ⁖ имєньмь ⁖ $4 ⁖",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|нарєчє}} страницѫ ⁖ $3 ⁖ имєньмь ⁖ $4 ⁖ бєꙁ прѣнаправлєниꙗ сътворѥниꙗ",
        "logentry-newusers-create": "польꙃєватєльско мѣсто ⁖ $1 ⁖ {{GENDER:$2|сътворѥно}} ѥстъ",
+       "logentry-upload-upload": "$1 {{GENDER:$2|положишє}} $3",
        "revdelete-summary": "мѣнꙑ опьсаниѥ",
        "searchsuggest-search": "исканиѥ",
        "searchsuggest-containing": "сѥ дрьжащи···",
-       "api-error-unknownerror": "нєвѣдома блаꙁна : ⁖ $1 ⁖"
+       "api-error-unknownerror": "нєвѣдома блаꙁна : ⁖ $1 ⁖",
+       "special-characters-group-latin": "латиньска аꙁъбоукꙑ",
+       "special-characters-group-latinextended": "латиньскꙑ аꙁъбоукьвє доложєниѥ",
+       "special-characters-group-ipa": "М҃ФА",
+       "special-characters-group-symbols": "сѷмволи",
+       "special-characters-group-greek": "грьчьска аꙁъбоукꙑ",
+       "special-characters-group-cyrillic": "климєнтовица / гражданьска аꙁъбоукꙑ",
+       "special-characters-group-arabic": "аравьска аꙁъбоукꙑ",
+       "special-characters-group-hebrew": "єврєиска аꙁъбоукꙑ",
+       "special-characters-group-bangla": "бангальска аꙁъбоукꙑ",
+       "special-characters-group-telugu": "тєлоужьска аꙁъбоукꙑ",
+       "special-characters-group-sinhala": "синхальска аꙁъбоукꙑ"
 }
index 94aa115..2402316 100644 (file)
        "namespaceprotected": "Сирĕн «$1» ят уçлăхĕнчи статьясене тӳрлетмелли май çук..",
        "ns-specialprotected": "«{{ns:special}}» ят уçлăхĕнчи страницăсене эсир тӳрлетейместĕр.",
        "titleprotected": "Ку ятлă страницăна хатĕрлессине [[Хутшăнакан:$1|$1]] хутшăнакан чарса хунă.\nÇак сăлтава кăтартнă: ''$2''.",
+       "exception-nologin": "Кĕмен",
        "virus-badscanner": "Ĕнерлев йăнăшĕ. Вирус сканерĕ паллă мар: ''$1''",
        "virus-scanfailed": "скенерланă чухнехи йăнăш (код $1)",
        "virus-unknownscanner": "паллă мар антивирус:",
        "logouttext": "Эсир палласа илмен хутшăнакан евĕр ĕçлетĕр.\nСайт сире ятпа мар, IP-адрес урлă пĕлет.\nЭсир анонимла, е малтанхи евĕрлĕ çĕнĕ сеанс уçса, е  урăх ятпа ĕçлеме пултаратăр.\nХăш-пĕр страницăсем эсир сайта кĕнĕ пек курăнма пултараççĕ, ăна тӳрлетмешкĕн браузер кэшне çĕнетĕр.",
-       "yourname": "Усăкуракан ят:",
+       "yourname": "Усă куракан ят:",
        "userlogin-yourname": "Усă куракан ят",
        "yourpassword": "Вăрттăн сăмах:",
        "yourpasswordagain": "Вăрттăн сăмах тепре çырăр:",
        "logout": "Сеансне пĕтерни",
        "userlogout": "Тухрăр",
        "notloggedin": "Эсир сайта кĕмен",
-       "nologin": "ЭÑ\81иÑ\80 Ñ\85алÄ\95 Ñ\82е Ñ\80егиÑ\81Ñ\82Ñ\80аÑ\86иленмен-и? '''$1'''.",
+       "nologin": "Ð\90ккаÑ\83нÑ\82 Ã§Ñ\83к-и? $1.",
        "nologinlink": "Çĕнĕ хутшăнакана регистрацилесси",
-       "createaccount": "Çĕнĕ хутшăнакана регистрацилесси",
-       "gotaccount": "ЭÑ\81иÑ\80 Ñ\80егиÑ\81Ñ\82Ñ\80аÑ\86иленÑ\81е-и? '''$1'''.",
+       "createaccount": "Аккаунт ту",
+       "gotaccount": "Ð\90ккаÑ\83нÑ\82 Ð¿Ñ\83Ñ\80-и? $1.",
        "gotaccountlink": "Кĕрĕр",
        "createaccountmail": "эл. почта тăрăх",
+       "createacct-realname": "Чăн-чăн ят (пулсан)",
        "createacct-submit": "Аккаунт ту",
+       "createacct-benefit-body1": "{{PLURAL:$1|тӳрлетни|тӳрлетнисем}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|страница|страницасем}}",
        "badretype": "Эсир кăтартнă парольсем пĕр пек мар.",
        "userexists": "Эсир усă курас теекен ята йышăннă. Тархасшăн, урăх ят суйласа илĕр.",
        "loginerror": "Хутшăнакана палласа илеймерĕмĕр",
        "prefs-searchoptions": "Шырамалли",
        "prefs-files": "Файлсем",
        "youremail": "Электронлă почта:",
-       "username": "{{GENDER:$1|Ð¥Ñ\83Ñ\82Ñ\88Ä\83наканÄ\83н Ñ\8fÑ\87Ä\95}}:",
+       "username": "{{GENDER:$1|УÑ\81Ä\83 ÐºÑ\83Ñ\80акан Ñ\8fÑ\82}}:",
        "prefs-registration": "Регистрацин вăхăтчĕ:",
        "yourrealname": "Чăн-чăн ят:",
        "yourlanguage": "Интерфейс чĕлхи:",
        "recentchanges-legend": "Çĕнĕ улшăнусен ĕнерлевĕ",
        "recentchanges-label-bot": "Ку улшăнăва бот тунă",
        "recentchanges-legend-newpage": "$1 — çĕнĕ страница",
+       "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "rclistfrom": "Юлашки улшăнусене $3 $2 вăхăтран пуçласа кăтартнă",
        "rcshowhideminor": "пĕчĕк тӳрлетнисене $1",
        "rcshowhidebots": "ботсене $1",
        "brokenredirects-edit": "тӳрлет",
        "brokenredirects-delete": "кăларса пăрах",
        "fewestrevisions": "Сахал тӳрлетнĕ статьясем",
-       "nbytes": "$1 {{PLURAL:$1|1=байт|байт}}",
+       "nbytes": "$1 {{PLURAL:$1|байт|байтсем}}",
        "ncategories": "$1 {{PLURAL:$1|категори|категорисем}}",
        "nlinks": "$1 {{PLURAL:$1|1=каçă|каçă}}",
        "nviews": "$1 {{PLURAL:$1|пăхни|пăхнисем}}",
        "confirm_purge_button": "OK",
        "confirm-watch-button": "OK",
        "confirm-unwatch-button": "OK",
+       "pipe-separator": "&#32;|&#32;",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← малтанхи страница",
        "imgmultipagenext": "тепĕр страница →",
index 16a1e6a..1190c40 100644 (file)
        "emailccsubject": "Copy of your message to $1: $2",
        "emailsent": "Email sent",
        "emailsenttext": "Your email message has been sent.",
-       "emailuserfooter": "This email was sent by $1 to $2 by the \"Email user\" function at {{SITENAME}}.",
+       "emailuserfooter": "This email was sent by $1 to $2 by the \"{{int:emailpage}}\" function at {{SITENAME}}.",
        "usermessage-summary": "Leaving system message.",
        "usermessage-editor": "System messenger",
        "usermessage-template": "MediaWiki:UserMessage",
        "feedback-error1": "Error: Unrecognized result from API",
        "feedback-error2": "Error: Edit failed",
        "feedback-error3": "Error: No response from API",
+       "feedback-error4": "Error: Unable to post to given feedback title",
        "feedback-message": "Message:",
        "feedback-subject": "Subject:",
        "feedback-submit": "Submit",
index a5f5815..b0ed3d2 100644 (file)
        "notextmatches": "किसी भी पृष्ठ में यह सामग्री नहीं मिली",
        "prevn": "पिछले {{PLURAL:$1|$1}}",
        "nextn": "अगले {{PLURAL:$1|$1}}",
+       "prev-page": "पिछला पृष्ठ",
+       "next-page": "अगला पृष्ठ",
        "prevn-title": "{{PLURAL:$1|पिछला|पिछले}} $1 परिणाम",
        "nextn-title": "{{PLURAL:$1|अगला|अगले}} $1 परिणाम",
        "shown-title": "हर पृष्ठ पर $1 {{PLURAL:$1|परिणाम}} दिखाएँ",
index 68e621e..5c25332 100644 (file)
        "category-empty": "<em>このカテゴリには現在、ページやメディアが何もありません。</em>",
        "hidden-categories": "{{PLURAL:$1|隠しカテゴリ}}",
        "hidden-category-category": "隠しカテゴリ",
-       "category-subcat-count": "{{PLURAL:$2|このカテゴリには以下の下位カテゴリのみが含まれています。|このカテゴリには$2件の下位カテゴリが含まれており、そのうち以下の{{PLURAL:$1|下位カテゴリ$1件}}を表示しています。}}",
+       "category-subcat-count": "{{PLURAL:$2|このカテゴリには以下の下位カテゴリのみが含まれています。|このカテゴリには下位カテゴリ $2 件が含まれており、そのうち以下の{{PLURAL:$1| $1 件}}を表示しています。}}",
        "category-subcat-count-limited": "このカテゴリには以下の{{PLURAL:$1|下位カテゴリ|​&#32;$1件の下位カテゴリ}}が含まれています。",
        "category-article-count": "{{PLURAL:$2|このカテゴリには以下のページのみが含まれています。|このカテゴリには $2 ページが含まれており、そのうち以下の $1 ページを表示しています。}}",
        "category-article-count-limited": "現在のカテゴリには以下の{{PLURAL:$1|ページ|​&#32;$1 ページ}}が含まれています。",
        "wrongpassword": "パスワードが間違っています。 \nもう一度やり直してください。",
        "wrongpasswordempty": "パスワードを空欄にはできません。\nもう一度やり直してください。",
        "passwordtooshort": "パスワードは {{PLURAL:$1|$1 文字}}以上にしてください。",
+       "passwordtoolong": "パスワードは {{PLURAL:$1|$1 文字}}以下にしてください。",
        "password-name-match": "パスワードは利用者名とは異なる必要があります。",
        "password-login-forbidden": "この利用者名とパスワードの使用は禁止されています。",
        "mailmypassword": "パスワードを再設定",
        "missingcommentheader": "<strong>注意:</strong> このコメントに対する題名/見出しが空欄です。\n「{{int:savearticle}}」ボタンをもう一度押すと、空のまま編集が保存されます。",
        "summary-preview": "要約のプレビュー:",
        "subject-preview": "題名/見出しのプレビュー:",
+       "previewerrortext": "変更のプレビューを処理中にエラーが発生しました。",
        "blockedtitle": "利用者はブロックされています",
        "blockedtext": "<strong>この利用者名またはIPアドレスはブロックされています。</strong>\n\nブロックは$1によって実施されました。\nブロックの理由は <em>$2</em> です。\n\n* ブロック開始日時: $8\n* ブロック解除予定: $6\n* ブロック対象: $7\n\nこのブロックについて、$1もしくは他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]に問い合わせることができます。\nただし、[[Special:Preferences|個人設定]]で有効なメールアドレスが登録されていない場合、またはメール送信機能の使用がブロックされている場合、「この利用者にメールを送信」の機能は使えません。\n現在ご使用中のIPアドレスは$3、このブロックIDは#$5です。\nお問い合わせの際には、上記の情報を必ず書いてください。",
        "autoblockedtext": "このIPアドレスは、$1によりブロックされた利用者によって使用されたため、自動的にブロックされています。\n理由は次の通りです。\n\n:<em>$2</em>\n\n* ブロック開始日時: $8\n* ブロック解除予定: $6\n* ブロック対象: $7\n\n$1または他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]にこのブロックについて問い合わせることができます。\n\nただし、[[Special:Preferences|個人設定]]に正しいメールアドレスが登録されていない場合、またはメール送信がブロックされている場合、「この利用者にメールを送信」機能を使用できないことに注意してください。\n\n現在ご使用中のIPアドレスは$3 、このブロックIDは#$5です。\nお問い合わせの際は、上記の情報を必ず書いてください。",
        "difference-title": "「$1」の版間の差分",
        "difference-title-multipage": "ページ「$1」と「$2」の間の差分",
        "difference-multipage": "(ページ間の差分)",
-       "lineno": "行$1:",
+       "lineno": "$1行目:",
        "compareselectedversions": "選択した版同士を比較",
        "showhideselectedversions": "選択した版を表示/非表示",
        "editundo": "取り消し",
        "searchprofile-everything-tooltip": "全本文ページ (トークページを含む) 内を検索",
        "searchprofile-advanced-tooltip": "特定の名前空間内を検索",
        "search-result-size": "$1 ({{PLURAL:$2|$2 語}})",
-       "search-result-category-size": "{{PLURAL:$1|$1件}} ({{PLURAL:$2|下位カテゴリ$2件}}、{{PLURAL:$3|ファイル$3件}})",
+       "search-result-category-size": "{{PLURAL:$1|$1 件}} ({{PLURAL:$2|下位カテゴリ $2 件}}、{{PLURAL:$3|ファイル $3 件}})",
        "search-redirect": "($1からのリダイレクト)",
        "search-section": "($1の節)",
        "search-category": "(カテゴリ $1)",
        "tags-create-warnings-below": "このタグの作成を続けますか?",
        "tags-delete-title": "タグを削除",
        "tags-delete-explanation-initial": "あなたはタグ「$1」をデータベースから削除しようとしています。",
+       "tags-delete-explanation-in-use": "現在適用されている{{PLURAL:$2|リビジョンやログ項目 $2 件}}を削除します。",
        "tags-delete-explanation-warning": "この操作は<strong>元に戻せず</strong>、データベース管理者をもってしても<strong>取り消しは不可能</strong>です。削除するタグとして間違いがないことをもう一度しっかり確認してください。",
        "tags-delete-explanation-active": "<strong>タグ「$1」はまだ有効であり、今後も付与され続けます。</strong>これを止めるには、タグが付与されるよう設定されているところに行き、そこで無効化してください。",
        "tags-delete-reason": "理由:",
        "revdelete-uname-unhid": "利用者名の可視化",
        "revdelete-restricted": "管理者に対する制限の適用",
        "revdelete-unrestricted": "管理者に対する制限の除去",
-       "logentry-block-block": "$1 が $3 を$5ブロックしました $6",
-       "logentry-block-reblock": "$1 が $3 のブロック設定を $5 に変更しました $6",
+       "logentry-block-block": "$1 が {{GENDER:$4|$3}} を$5までの期限付きで{{GENDER:$2|ブロックしました}} $6",
+       "logentry-block-unblock": "$1 が {{GENDER:$4|$3}} の{{GENDER:$2|ブロックを解除しました}}",
+       "logentry-block-reblock": "$1 が {{GENDER:$4|$3}} のブロック設定を$5までの期限に{{GENDER:$2|変更しました}} $6",
+       "logentry-suppress-block": "$1 が {{GENDER:$4|$3}} を$5までの期限付きで{{GENDER:$2|ブロックしました}} $6",
+       "logentry-suppress-reblock": "$1 が {{GENDER:$4|$3}} のブロック設定を$5までの期限に{{GENDER:$2|変更しました}} $6",
+       "logentry-import-upload": "$1 がファイルをアップロードして $3 を{{GENDER:$2|インポートしました}}",
+       "logentry-import-interwiki": "$1 が他のウィキから $3 を{{GENDER:$2|インポートしました}}",
        "logentry-merge-merge": "$1{{GENDER:$2|統合元}} と$3を$4に統合(改訂版を$5に掲載)",
        "logentry-move-move": "$1 がページ「$3」を「$4」に{{GENDER:$2|移動しました}}",
        "logentry-move-move-noredirect": "$1 がページ「$3」を「$4」に、リダイレクトを残さずに{{GENDER:$2|移動しました}}",
        "logentry-upload-revert": "$1 が $3 を {{GENDER:$2|アップロードしました}}",
        "log-name-managetags": "タグ管理記録",
        "log-description-managetags": "このページは[[Special:Tags|タグ]]に関係する管理タスクをリストアップしています。ログには管理者によって手動で実行された操作の記録しか記載されていません。ウィキ・ソフトウェアによって、ログを残さずにタグが作成・削除されている場合があります。",
+       "logentry-managetags-create": "$1 がタグ「$4」を{{GENDER:$2|作成しました}}",
        "rightsnone": "(なし)",
        "revdelete-summary": "編集内容の要約",
        "feedback-adding": "ページへのフィードバックの追加...",
index e961455..d480ccf 100644 (file)
        "protect-unchain-permissions": "وا کردن گزینه یا هنی پر و پیم کردن",
        "protect-text": "شما می تونیت ریتراز پر و پیم کاری بلگه '''$1''' نه سیل بکیت و از ایچه ونه آلشت بکیت.",
        "protect-locked-blocked": "شما د گاتی که د دسرسیتو نهاگری بیه نمی تونیت ریتراز پر و پیم کاری بلگه یا نه آلشت بئیت.\nمیزونکاری ایسنی بلگه '''$1''' د ای قراره:",
+       "protect-locked-dblock": "سی یه که رسینه جا قلف بیه، امکان آلشت دئن ریتراز پر و پیم کاری بلگه یا د ایسه نئ.\nمیزونکاری ایسنی بلگه '''$1''' ها دی ای قرار:",
+       "protect-locked-access": "حساو کاریاری شما سی آلشتکاری ریتراز پر و پیم کاری صلاداری ناره.\nمیزونکاریا ایسنی بلگه '''$1''' ها دی ای قرار:",
+       "protect-cascadeon": "ای بلگه ایسنی پر و پیم کاری بیه، سی یه که د {{PLURAL:$1|بلگه|بلگه یا}} هاری که گزینه پر و پیم کاری تاف نمایی {{PLURAL:$1|وه|ونو}} کنشتکاره، اومائه.\nآلشتیایی که مال ریتراز ای بلگه ن ری پر و پیم کاری تاف نمایی کارگرایی نارن.",
        "protect-default": "همه کاروریا اجازه دارن",
        "protect-fallback": "فقط کاریاریایی که وه «$1» دسرسی دارن، صلادار ای کارن",
        "protect-level-autoconfirmed": "فقط کاریاریا که خودپشت راس بینه صلادارن",
        "protect-expiring-local": "گات تموم بیین $1",
        "protect-expiry-indefinite": "بی زمون",
        "protect-cascade": "پر و پیم بیین تافنمایی- همه بلگه یایی که هان د ای بلگه پر و پیم بوئن.",
+       "protect-cantedit": "شما نمی تونیت حال و بار پر و پیم کاری ای بلگه نه آلشت بئیت، سی یه که صلا ویرایشت دئن ونه ناریت.",
        "protect-othertime": "وخت هنی:",
        "protect-othertime-op": "گات هنی",
        "protect-existing-expiry": "گات تموم بیین ایسنی: $2، $3",
        "protect-existing-expiry-infinity": "گات تموم بیین: بی گاته",
        "protect-otherreason": "دلیل اضافی/هنی:",
        "protect-otherreason-op": "دلیل هنی",
+       "protect-dropdown": "*دلیلیا جاافتائه سی پر و پیم کاری\n** خراوکاری گپ کلون\n** هرزه نیسی گپ کلون\n** جئن ویرایشتی وه درد نحور\n** بلگه فره تماشاکار دار",
        "protect-edit-reasonlist": "دلیلا پر و پیم بیین ویرایشت",
        "protect-expiry-options": "1 ساعت:1 ساعت,1 روز:1 روز,1 هفته:1 هفته,2 هفته:2 هفته,1 ما:1 ما,3 ما:3 ما,6 ما:6 ما,1 سال:1 سال,بی حساو:بی حساو",
        "restriction-type": "دسرسی:",
        "undelete": "دیئن بلگه یا پاکسا بیه",
        "undeletepage": "دیئن و  ؤرگشتن بلگه یا پاکسا بیه",
        "viewdeletedpage": "دیئن بلگه یا پاکسا بیه",
+       "undeletepagetext": "{{PLURAL:$1|بلگه های پاکسا بیه|بلگه یا هاری پاکسا بینه}} ولی ایسه د اماییه جا {{PLURAL:$1|هئ|هان}} و {{PLURAL:$1|می تونه د نو زنه با|می‌ تونن د نو زنه بان}}.\nای اماییه جا ممکنه هر چن گری تمیس بوئه.",
        "undelete-fieldset-title": "د نو زنه کردن وانئریا",
        "undeleterevisions": "$1 نسقه مال دیاری{{PLURAL:$1|بیه|بینه}}",
        "undelete-revision": "نسقه پاکسا بیه $1 (د ویرگار$4 ساعت $5) وه دس $3:",
        "limitreport-ppvisitednodes-value": "$1/$2",
        "limitreport-ppgeneratednodes-value": "$1/$2",
        "limitreport-expansiondepth-value": "$1/$2",
+       "limitreport-expensivefunctioncount": "انازه انجومگریا وااشکافتکار پر مصرف",
        "limitreport-expensivefunctioncount-value": "$1/$2",
        "expandtemplates": "گپ کلون کردن چوئه یا",
+       "expand_templates_title": "داسون، سی {{FULLPAGENAME}} و چیا هنی:",
        "expand_templates_input": "نیسسه درینده:",
        "expand_templates_output": "نتیجه",
        "expand_templates_xml_output": "درده ایکس ام ال",
+       "expand_templates_html_output": "وه در ده اچ تی ام ال خام",
        "expand_templates_ok": "خوئه",
        "expand_templates_remove_comments": "جا وه جا بیئن ویر و باوریا",
+       "expand_templates_remove_nowiki": "خومثی کردن سردیسیا <nowiki> د کارگرایی",
+       "expand_templates_generate_xml": "نشو دئن دار وااشکافتکاری XML",
+       "expand_templates_generate_rawhtml": "نشو دئن اچ‌ تی‌ ام‌ ال خام",
        "expand_templates_preview": "پيش سيل",
        "pagelanguage": "بلگه انتخاو زون",
        "pagelang-name": "بلگه",
        "mediastatistics-header-text": "نیسسه دار",
        "mediastatistics-header-executable": "اجرا کردنیا",
        "mediastatistics-header-archive": "قالویا جم بیه",
+       "json-error-state-mismatch": "جی‌ سن نادرست یا ناقص",
        "json-error-syntax": "خطا دستوری",
        "json-error-inf-or-nan": "ارزایشتیا INF یا NAN یه گل یا بیشتر د وه د انازه یی که رازینه کاری بیه",
        "json-error-unsupported-type": "یه گل ارزایشت د جوری که نبوئه رازینه کاری با وتو دئه بیه",
index 1ef0cc5..6e78ef2 100644 (file)
@@ -44,7 +44,7 @@
        "tog-shownumberswatching": "निगरानी गरिरहेका प्रयोगकर्ताहरुको संख्या देखाउने",
        "tog-oldsig": "वर्तमान हस्ताक्षर:",
        "tog-fancysig": "मेरो दस्तखतलाई विकि पाठको रुपमा लिने(स्वत सम्वन्ध बिना)",
-       "tog-uselivepreview": "प्रत्यक्ष पूर्वरुप प्रयोग गर्नुहोस् (प्रयोगात्मक)",
+       "tog-uselivepreview": "प्रत्यक्ष पूर्वरुप प्रयोग गर्नुहोस",
        "tog-forceeditsummary": "खाली सम्पादन सार प्रविष्टि गरेमा मलाई सोध्ने",
        "tog-watchlisthideown": "मेरा सम्पादनहरू निगनारी सूचीबाट लुकाउने",
        "tog-watchlisthidebots": "बोट सम्पादनहरू निगरानी सूचीबाट लुकाउने",
        "changeemail-oldemail": "हालको इमेल-ठेगाना:",
        "changeemail-newemail": "नयाँ इमेल-ठेगाना:",
        "changeemail-none": "(कुनै पनि हैन)",
+       "changeemail-password": "तपाईंको {{SITENAME}} पासवर्ड:",
        "changeemail-submit": "इमेल परिवर्तन गर्ने",
+       "changeemail-throttled": "तपाईंले भर्खरै धेरै पल्ट प्रवेशको निम्ति प्रयास गर्नुभएको छ।\nकृपया $1 पर्खेर मात्र प्रयास गर्नुहोस्।",
        "resettokens": "टोकन पूर्वरुपमा फर्काउने",
        "resettokens-no-tokens": "पूर्वरुपमा फर्काउन कुनै पनि टोकन छैन ।",
        "resettokens-legend": "टोकनहरू पूर्वरुपमा फर्काउने",
        "updated": "नवीन",
        "note": "'''सूचना:'''",
        "previewnote": "'''याद राख्नुहोस् यो केवल पूर्वावलोकन मात्र हो; तपाईंका परिवर्तनहरू संग्रहित भएका छैनन्!'''",
+       "continue-editing": "सम्पादन क्षेत्रमा जानुहोस",
        "previewconflict": "यस पूर्वावलोकनले संपादन क्षेत्र को माथिल्लो भागको पाठ परिवर्तन गर्ने ठाउँको पाठलाइ देखाउँछ अनि तपाइले यसलाइ सेभ गरेपछि देखापर्छ।",
        "session_fail_preview": "'''माफ गर्नुहोस्! सत्र-आँकड़ा (session data) हराउनाले हामीले तपाईंको सम्पादन प्रक्रिया अघि बढाउन सकेनौं।.'''\nकृपया पुनः प्रयास गर्नुहोस्।\nयदि फेरि पनि काम भएन भनें, [[Special:UserLogout|बाहिर गई(लग आउट गरी)]]  फेरि प्रवेश गर्नुहोस्।",
        "session_fail_preview_html": "'''माफ गर्नुहोला! सत्र को डेटा को नोकसान को कारण ले गर्दा तपाइको सम्पादन लाइ जारी राख्न सकिएन।'''\n\n''जावास्क्रिप्ट हमलाहरु रोक्नको लागि यो पूर्वावलोकन लाइ देखाइएको छैन किन कि {{SITENAME}} मा काँचो HTML को प्रयोग गर्न मिल्ने बनाइएको छ।''\n\n'''यदि यो एक वैध प्रयास हो भने, कृपया पुन: प्रयास गर्नुहोला.'''\nयदि अझै पनि काम गरेन भने [[Special:UserLogout|निर्गमन(logging out)]] र पुन:आगमन(login) गर्ने प्रयास गर्नुहोला।",
        "revertmerge": "नमिलाउने",
        "mergelogpagetext": "एउटा पृष्ठको इतिहास अर्कोमा भर्खरै मिलाइएको सूची तल दिइन्छ।",
        "history-title": "\"$1\" को पुनरावृत्ति इतिहास",
+       "difference-title": "\"$1\" को बिचमा भिन्नता",
+       "difference-title-multipage": "\"$1\" तथा \"$2\" को बिचमा भिन्नता",
        "difference-multipage": "(पृष्ठहरूमा भिन्नता)",
        "lineno": "पंक्ति $1:",
        "compareselectedversions": "छानिएका संस्करणहरू दाँज्नुहोस्",
        "notextmatches": "अक्षरस् पेज भेटिएन",
        "prevn": "पहिलेको {{PLURAL:$1|$1}}",
        "nextn": "अर्को {{PLURAL:$1|$1}}",
+       "prev-page": "अघिल्लो पृष्ठ",
+       "next-page": "अर्को पृष्ठ",
        "prevn-title": "पहिलेको  $1 {{PLURAL:$1|नतिजा|नतिजाहरु}}",
        "nextn-title": "यस पछिको $1 {{PLURAL:$1|नतिजा |नतिजाहरु}}",
        "shown-title": "देखाउने $1 {{PLURAL:$1|नतिजा|नतिजाहरु}} प्रति पृष्ठ",
        "viewprevnext": "हेर्नुहोस् ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "''' \"[[:$1]]\" नाम गरेको पृष्ठ  यो विकीमा रहेको छ'''",
-       "searchmenu-new": "'''यस विकिमा  \"[[:$1]]\" शीर्षक भएको पृष्ठ बनाउनुहोस् !'''",
+       "searchmenu-new": "<strong>\"[[:$1]]\" पृष्ठ यस विकिमा बनाउनुहोस्!</strong> {{PLURAL:$2|0=|तपाईंले खोज गरी भटिएको पृष्ठ पनि मिलान गर्नुहोस्।|तपाईंको खोज परिणाम पनि हेर्नुहोस।}}",
        "searchprofile-articles": "सामग्री पृष्ठहरू",
        "searchprofile-images": "मल्टिमिडिया(श्रव्य दृश्य)",
        "searchprofile-everything": "सब थोक",
        "right-move": "पृष्ठहरू सार्ने",
        "right-move-subpages": "तिनीहरुको सह-पृष्ठसहित पृष्ठहरु सार्ने",
        "right-move-rootuserpages": "मूल(root) प्रयोगकर्ताको पृष्ठहरु सार्ने",
+       "right-move-categorypages": "श्रेणी पृष्ठ सार्नुहोस",
        "right-movefile": "फाइलहरु सार्ने",
        "right-suppressredirect": "पृष्ठ सार्दा स्रोत पृष्ठबाट पठाउने लिंक नबनाउने",
        "right-upload": "फाइलहरु उर्ध्वभरण गर्ने",
        "right-reupload-shared": "साझा मिडिया भण्डारमा स्थानियरुपमा फाइलहरु अधिक्रमण गर्ने",
        "right-upload_by_url": "URL बाट फाइल उर्ध्वभरण गर्ने",
        "right-purge": "साइटको क्याश( cache) निश्चित नगरिकनै पर्ज(Purge) गर्ने",
-       "right-autoconfirmed": "à¤\85रà¥\8dध-सà¥\81रà¤\95à¥\8dषित à¤ªà¥\83षà¥\8dठहरà¥\81 à¤¸à¤®à¥\8dपादन à¤\97र्ने",
+       "right-autoconfirmed": "à¤\86à¤\87पà¥\80 à¤¦à¤° à¤¸à¥\80मालà¥\87 à¤\85सर à¤¨à¤ªà¤¾र्ने",
        "right-bot": "स्वाचालित कार्यको रुपमा व्यवहार गर्ने",
        "right-apihighlimits": "API खोजको लागि उच्च सीमा प्रयोग गर्नुहोस्",
        "right-writeapi": "लेखन API प्रयोग गर्ने",
        "license-header": "अनुज्ञा प्राप्त गर्दै",
        "nolicense": "केहिपनि छानिएन",
        "license-nopreview": "(पूर्वरुप उपलब्ध छैन)",
-       "upload_source_file": " (तपाईँको कम्प्युटरमा रहेको एक फाइल)",
+       "upload_source_file": "(तपाईँले आफ्नो कम्प्युटरबाट छानेको फाइल)",
+       "listfiles-delete": "मेट्ने",
+       "listfiles-summary": "यस विशेष पृष्ठले उर्ध्वभरण गरिका सबै फाइलहरु देखाउँछ।",
        "listfiles_search_for": "मिडिया नामको लागि खोज्नुहोस:",
        "imgfile": "फाइल",
        "listfiles": "फाइल सूची",
        "unusedtemplateswlh": "अन्य कड़ीहरु",
        "randompage": "कुनै एक लेख",
        "randompage-nopages": "{{PLURAL:$2| $1 नाम भएको कुनै पृष्ट छैन|$1 नाम भएका कुनै पृष्टहरु छैनन्}}",
+       "randomincategory-category": "श्रेणी:",
        "randomredirect": "कुनै एउटा अनुप्रेषितमा जाने",
        "randomredirect-nopages": "\"$1\" नामस्थानमा अनुप्रेषित छैन।",
        "statistics": "तथ्यांक",
        "dberr-problems": "क्षमा पाउँ! यो साइटमा तकनीकी गड़बड़ी आइपरेकोछ।",
        "dberr-again": "केही समय पर्खिएर पुन: लोड हुन दिनुहोस् ।",
        "dberr-info": "(डेटाबेस सर्वर $1सित सम्पर्क साध्न सकिंदैन)",
-       "dberr-info-hidden": "(डà¥\87à¤\9fावà¥\87स à¤¸à¤°à¥\8dभरमा सम्पर्क स्थापना गर्न सकिएन)",
+       "dberr-info-hidden": "(डà¥\87à¤\9fाबà¥\87समा सम्पर्क स्थापना गर्न सकिएन)",
        "dberr-usegoogle": "तपाईले अहिले गुगलबाट खोज गर्न प्रयास गर्न सक्नुहुन्छ।",
        "dberr-outofdate": "कृपया स्मरणमा राख्नुहोस् हाम्रा लेखहरूको सूची जुन उनीहरूले राखेका छन् त्यो अद्यावधिक नहुन सक्छ ।",
        "dberr-cachederror": "यो अनुरोध गरिएको पृष्ठको क्याशमा रहेका प्रतिलिपी हो , र अद्यावधिक नहुन सक्छ ।",
        "htmlform-chosen-placeholder": "एक विकल्प छान्नुहोस्",
        "sqlite-has-fts": "$1 पूरा पाठ खोज समर्थन सहित",
        "sqlite-no-fts": "$1 पूरा पाठ खोज समर्थन बिना",
-       "logentry-delete-restore": "$3 पृष्ठ $1ले पुनर्स्थापित गरेको हो",
+       "logentry-delete-restore": "$3 पृष्ठ $1ले {{GENDER:$2|पुनर्स्थापित}} गरेको हो",
        "revdelete-content-hid": "सामग्री लुकाइएको",
        "revdelete-summary-hid": "सम्पादन सारांस लुकाइएको",
        "revdelete-uname-hid": "प्रयोगकर्ताको नाम लुकाइयो",
        "revdelete-summary": "सम्पादन सारांश",
        "feedback-cancel": "रद्द गर्ने",
        "feedback-close": "गरियो",
+       "feedback-error-title": "त्रुटि",
        "feedback-error2": "त्रुटि: सम्पादन असफल",
        "feedback-message": "सन्देश:",
        "feedback-subject": "विषय:",
        "feedback-submit": "बुझाउने",
+       "feedback-thanks-title": "धन्यवाद!",
+       "feedback-useragent": "प्रयोगकर्ता एजेन्ट:",
        "searchsuggest-search": "खोज",
        "api-error-badaccess-groups": "यस विकिमा तपाईंलाई फाइल अपलोड गर्ने अनुमति छैन।",
        "api-error-copyuploaddisabled": "यस सर्वरमा URL द्वारा अपलोड गर्ने व्यवस्था निस्क्रिय गरिएकोछ।",
index 6da17fe..64a84f4 100644 (file)
        "expand_templates_generate_xml": "Pokaż drzewo analizatora składni w formacie XML",
        "expand_templates_generate_rawhtml": "Pokaż surowy HTML",
        "expand_templates_preview": "Podgląd",
+       "expand_templates_preview_fail_html": "<em>Ponieważ {{SITENAME}} ma włączony surowy kod HTML i zaistniała strata danych z sesji, podgląd jest ukryty jako zabezpieczenie przed atakiem JavaScript.</em>\n\n<strong>Jeśli to jest próba słusznego podglądu, proszę spróbować ponownie.</strong>\nJeśli to nadal nie działa, spróbuj [[Special:UserLogout|wylogować się]] i zalogować się z powrotem.",
        "pagelanguage": "Wybór języka strony",
        "pagelang-name": "Strona",
        "pagelang-language": "Język",
index 967fbd0..cade0ad 100644 (file)
        "recentchanges-legend-heading": "'''لنډونونه:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|د نويو مخونو لړليک]] هم وگورئ)",
        "rcnotefrom": "دلته لاندې د <strong>$2</strong> څخه راپدېخوا پېښ شوي بدلونونه راغلي (تر <strong>$1</strong> پورې ښکاري).",
-       "rclistfrom": "Ù\87غÙ\87 Ù\86Ù\88Ù\8a Ø¨Ø¯Ù\84Ù\88Ù\86Ù\88Ù\86Ù\87 Ú\9aکارÙ\87 Ú©Ù\88Ù\84 Ú\86Û\90 Ù\84Ù\87 $3 $2 Ù\86Ù\87 Ù¾Ù\8aÙ\84Û\90Ú\96Ù\8a",
+       "rclistfrom": "Ù\86Ù\88Ù\8a Ø¨Ø¯Ù\84Ù\88Ù\86Ù\88Ù\86Ù\87 Ú\86Û\90 Ù\84Ù\87 $3Ø\8c $2 Ú\85Ø®Ù\87 Ù¾Ù\8aÙ\84Û\90Ú\96Ù\8a Ú\9aکارÙ\87 Ú©Ù\88Ù\84",
        "rcshowhideminor": "وړې سمونې $1",
        "rcshowhideminor-show": "ښکاره کول",
        "rcshowhideminor-hide": "پټول",
        "pageinfo-header-restrictions": "مخ ژغورنه",
        "pageinfo-header-properties": "د مخ ځانتياوې",
        "pageinfo-display-title": "ښکارېدونکی سرليک",
+       "pageinfo-default-sort": "تلواليزه اوډن کونجۍ",
        "pageinfo-length": "مخ اوږدوالی (په بايټونو)",
        "pageinfo-article-id": "د مخ پېژند",
        "pageinfo-language": "د مخ د مېنځپانگې ژبه",
+       "pageinfo-content-model": "د مخ مېنځپانگې جوړښت",
        "pageinfo-robot-policy": "ليکلړ اوډنه د روباټونو لخوا",
        "pageinfo-robot-index": "پرېښل",
        "pageinfo-robot-noindex": "ناپرېښل",
        "pageinfo-watchers": "د مخ د کتونکو شمېر",
+       "pageinfo-few-watchers": "له $1 څخه لږ {{PLURAL:$1|کتونکی|کتونکي}}",
        "pageinfo-redirects-name": "دې مخ ته د ورگرځونو شمېر",
        "pageinfo-subpages-name": "دې مخ ته څېرمه مخونه",
        "pageinfo-firstuser": "مخ جوړونکی",
        "pageinfo-edits": "د ټولو سمونونو شمېر",
        "pageinfo-authors": "د بېلابېلو ليکوالو ټولټال شمېر",
        "pageinfo-recent-edits": "د وروستني سمونونو شمېر (په تېرو $1 کې)",
+       "pageinfo-recent-authors": "د بېلابېلو ليکوالو وروستنی شمېر",
        "pageinfo-toolboxlink": "د مخ مالومات",
        "pageinfo-redirectsto-info": "مالومات",
        "pageinfo-contentpage": "مېنځپانگيز مخ کې شمېرل شوی",
index 0992b49..f0ba941 100644 (file)
        "feedback-error1": "Error message, appears when an unknown error occurs submitting feedback",
        "feedback-error2": "Error message, appears when we could not add feedback",
        "feedback-error3": "Error message, appears when we lose our connection to the wiki",
+       "feedback-error4": "Error message, appears when mediawiki.feedback or one of its dependencies is misconfigured or there is a problem fetching one of the modules",
        "feedback-message": "Label for a textarea; signature refers to a Wikitext signature.\n{{Identical|Message}}",
        "feedback-subject": "Label for a text input\n{{Identical|Subject}}",
        "feedback-submit": "Button label\n{{Identical|Submit}}",
index 4d3bbf3..ca59d02 100644 (file)
        "tags-active-no": "Суох",
        "tags-edit": "уларытыы",
        "tags-hitcount": "$1 {{PLURAL:$1|уларытыы|уларытыылар}}",
+       "tags-create-tag-name": "Бэлиэ аата:",
+       "tags-create-reason": "Төрүөтэ:",
+       "tags-create-submit": "Оҥоруу",
+       "tags-create-no-name": "Бэлиэ аатын суруйуохтааххын.",
+       "tags-create-invalid-chars": "Бэлиэ аатыгар сопутуой (<code>,</code>) эбэтэр слэш  (<code>/</code>) буолуохтаах.",
+       "tags-create-invalid-title-chars": "Тиэк аатыгар сирэй баһыгар туттуллуо суохтаах бэлиэ киириэ суохтаах",
+       "tags-create-already-exists": "«$1» тиэк хайыы-үйэ баар эбит.",
        "comparepages": "Сирэйдэри тэҥнииргэ",
        "compare-page1": "Бастакы сирэй",
        "compare-page2": "Иккис сирэй",
index 636129c..3e3df26 100644 (file)
        "searchrelated": "пов'язаний",
        "searchall": "усі",
        "showingresults": "Нижче {{PLURAL:$1|показане|показані|показані}} '''$1''' {{PLURAL:$1|результат|результати|результатів}}, починаючи з №&nbsp;'''$2'''",
-       "showingresultsinrange": "Нижче показано до {{PLURAL:$1|<strong>1</strong> результата|<strong>$1</strong> результатів|<strong>$1</strong> результати}} у діапазоні від #<strong>$2</strong> до #<strong>$3</strong>.",
+       "showingresultsinrange": "Нижче показано до {{PLURAL:$1|<strong>1</strong> результату|<strong>$1</strong> результатів}} у діапазоні від #<strong>$2</strong> до #<strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Результат <strong>$1</strong> із <strong>$3</strong>|Результати <strong>$1 — $2</strong> із <strong>$3</strong>}}",
        "search-nonefound": "Не знайдено результатів, що відповідають запиту.",
        "powersearch-legend": "Розширений пошук",
        "grouppage-sysop": "{{ns:project}}:Адміністратори",
        "grouppage-bureaucrat": "{{ns:project}}:Бюрократи",
        "grouppage-suppress": "{{ns:project}}:Ревізори",
-       "right-read": "Ð\9fерегляд сторінок",
+       "right-read": "перегляд сторінок",
        "right-edit": "Редагування сторінок",
        "right-createpage": "Створення сторінок (але не обговорень)",
        "right-createtalk": "Створення обговорень сторінок",
        "right-createaccount": "Створення нових облікових записів",
-       "right-minoredit": "Ð\9fозначення редагувань як незначні",
-       "right-move": "Ð\9fерейменування сторінок",
-       "right-move-subpages": "Ð\9fерейменування сторінок і їх підсторінок",
+       "right-minoredit": "позначення редагувань як незначні",
+       "right-move": "перейменування сторінок",
+       "right-move-subpages": "перейменування сторінок і їх підсторінок",
        "right-move-rootuserpages": "перейменування кореневих сторінок користувачів",
        "right-move-categorypages": "перейменування сторінок категорій",
        "right-movefile": "перейменування файлів",
-       "right-suppressredirect": "Ð\9dестворення перенаправлення зі старої назви на нову при перейменуванні сторінки",
+       "right-suppressredirect": "нестворення перенаправлення зі старої назви на нову при перейменуванні сторінки",
        "right-upload": "Завантаження файлів",
        "right-reupload": "Перезаписування існуючих файлів",
        "right-reupload-own": "Перезаписування існуючих файлів, завантажених тим самим користувачем",
        "right-reupload-shared": "Підміна файлів зі спільного сховища локальними",
        "right-upload_by_url": "Завантаження файлів за URL-адресами",
        "right-purge": "Очищення кешу для сторінки без сторінки підтвердження",
-       "right-autoconfirmed": "Ð\91ез обмежень швидкості за IP",
-       "right-bot": "Ð\90втоматична обробка",
-       "right-nominornewtalk": "Ð\9dезначні редагування на сторінках обговорень користувачів не викликають попередження про нові повідомлення",
-       "right-apihighlimits": "Розширення обмежень на виконання API-запитів",
-       "right-writeapi": "Ð\92икористання API для запису",
+       "right-autoconfirmed": "без обмежень швидкості за IP",
+       "right-bot": "автоматична обробка",
+       "right-nominornewtalk": "незначні редагування на сторінках обговорень користувачів не викликають попередження про нові повідомлення",
+       "right-apihighlimits": "розширення обмежень на виконання API-запитів",
+       "right-writeapi": "використання API для запису",
        "right-delete": "Вилучення сторінок",
        "right-bigdelete": "Вилучення сторінок з великою історією",
        "right-deletelogentry": "Вилучення та відновлення окремих записів журналу",
        "right-editusercssjs": "Редагування CSS- і JS-файлів інших користувачів",
        "right-editusercss": "Редагування CSS-файлів інших користувачів",
        "right-edituserjs": "Редагування JS-файлів інших користувачів",
-       "right-editmyusercss": "Редагування власних CSS-файлів користувача",
-       "right-editmyuserjs": "Редагування власних JavaScript-файлів користувача",
-       "right-viewmywatchlist": "Ð\9fеÑ\80еглÑ\8fдаÑ\82и Ð²Ð»Ð°Ñ\81ний Ñ\81пиÑ\81ок спостереження",
-       "right-editmywatchlist": "Редагувати власний список спостереження. Зверніть увагу, що деякі дії будуть додавати сторінки навіть без такого права.",
-       "right-viewmyprivateinfo": "Ð\9fерегляд власних приватних даних (напр., адреса електронної пошти, справжнє ім'я)",
-       "right-editmyprivateinfo": "Редагування власних приватних даних (напр., адреса електронної пошти, справжнє ім'я)",
-       "right-editmyoptions": "Редагування власних налаштувань",
+       "right-editmyusercss": "редагування власних CSS-файлів користувача",
+       "right-editmyuserjs": "редагування власних JavaScript-файлів користувача",
+       "right-viewmywatchlist": "пеÑ\80еглÑ\8fд Ð²Ð»Ð°Ñ\81ного Ñ\81пиÑ\81кÑ\83 спостереження",
+       "right-editmywatchlist": "редагування власного списку спостереження; зверніть увагу, що деякі дії будуть додавати сторінки навіть без такого права.",
+       "right-viewmyprivateinfo": "перегляд власних приватних даних (напр., адреса електронної пошти, справжнє ім'я)",
+       "right-editmyprivateinfo": "редагування власних приватних даних (напр., адреса електронної пошти, справжнє ім'я)",
+       "right-editmyoptions": "редагування власних налаштувань",
        "right-rollback": "Швидкий відкіт редагувань останнього користувача, який редагував сторінку",
        "right-markbotedits": "Позначення відкинутих редагувань як редагування бота",
        "right-noratelimit": "Нема обмежень за швидкістю",
        "right-import": "Імпорт сторінок з інших вікі",
        "right-importupload": "Імпорт сторінок через завантаження файлів",
        "right-patrol": "Позначення редагувань патрульованими",
-       "right-autopatrol": "Ð\90втоматичне позначення редагувань патрульованими",
+       "right-autopatrol": "автоматичне позначення редагувань патрульованими",
        "right-patrolmarks": "Перегляд патрульованих сторінок у нових редагуваннях",
        "right-unwatchedpages": "Перегляд списку сторінок, за якими ніхто не спостерігає",
        "right-mergehistory": "Об'єднання історій редагувань сторінок",
        "listgrouprights-members": "(список членів)",
        "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code>($2)</code></span>",
        "listgrouprights-right-revoked": "<span class=\"listgrouprights-revoked\">$1 <code>($2)</code></span>",
-       "listgrouprights-addgroup": "Ð\9cожливість додавати в {{PLURAL:$2|1=групу|групи}}: $1",
-       "listgrouprights-removegroup": "Ð\9cожливість виключати з {{PLURAL:$2|1=групи|груп}}: $1",
-       "listgrouprights-addgroup-all": "Ð\9cожливість додавати до всіх груп",
-       "listgrouprights-removegroup-all": "Ð\9cожливÑ\96Ñ\81Ñ\82Ñ\8c Ð²Ð¸ÐºÐ»Ñ\8eÑ\87аÑ\82и Ð·Ñ\96 Ð²сіх груп",
+       "listgrouprights-addgroup": "можливість додавати в {{PLURAL:$2|1=групу|групи}}: $1",
+       "listgrouprights-removegroup": "можливість виключати з {{PLURAL:$2|1=групи|груп}}: $1",
+       "listgrouprights-addgroup-all": "можливість додавати до всіх груп",
+       "listgrouprights-removegroup-all": "можливÑ\96Ñ\81Ñ\82Ñ\8c Ð²Ð¸ÐºÐ»Ñ\8eÑ\87аÑ\82и Ð· Ñ\83сіх груп",
        "listgrouprights-addgroup-self": "може додавати {{PLURAL:$2|1=групу|групи}} до свого облікового запису: $1",
        "listgrouprights-removegroup-self": "Можливість вилучити зі свого облікового запису {{PLURAL:$2|1=групу|групи}}: $1",
        "listgrouprights-addgroup-self-all": "Може додавати всі групи до свого облікового запису",
index 7c6e698..d1a9784 100644 (file)
@@ -40,6 +40,7 @@
        "tog-watchdefault": "將我修改嘅頁同檔案加入監視清單",
        "tog-watchmoves": "將我移動嘅頁同檔案加入監視清單",
        "tog-watchdeletion": "將我刪除嘅頁同檔案加入監視清單",
+       "tog-watchrollback": "將我反轉過嘅頁加落監視清單",
        "tog-minordefault": "預設全部編輯做小修改",
        "tog-previewontop": "喺修改欄上方顯示預覽",
        "tog-previewonfirst": "第一次修改時顯示預覽",
        "pool-queuefull": "隊池已滿",
        "pool-errorunknown": "未知嘅錯誤",
        "pool-servererror": "用唔到程序計數服務 ($1)。",
+       "poolcounter-usage-error": "用法出錯:$1",
        "aboutsite": "關於{{SITENAME}}",
        "aboutpage": "Project:關於",
        "copyright": "除非另外講明,響呢版度嘅內容係根據$1嘅條款發佈。",
        "disclaimers": "免責聲明",
        "disclaimerpage": "Project:一般免責聲明",
        "edithelp": "編輯協助",
+       "helppage-top-gethelp": "幫手",
        "mainpage": "頭版",
        "mainpage-description": "頭版",
        "policy-url": "Project:政策",
        "readonly_lag": "當從伺服器追緊主伺服器時,資料庫會自動被鎖",
        "internalerror": "內部錯誤",
        "internalerror_info": "內部錯誤: $1",
+       "internalerror-fatal-exception": "嚴重例外類型「$1」",
        "filecopyerror": "檔案 \"$1\" 抄唔到去 \"$2\"。",
        "filerenameerror": "檔案 \"$1\" 唔改得做 \"$2\"。",
        "filedeleteerror": "檔案 \"$1\" 唔刪得。",
        "wrongpassword": "密碼唔啱,麻煩你再試多次。",
        "wrongpasswordempty": "你都未入密碼,唔該再試多次啦。",
        "passwordtooshort": "你嘅密碼最少要有$1個半形字元。",
+       "passwordtoolong": "密碼唔可以長過{{PLURAL:$1|1個字元|$1個字元}}。",
        "password-name-match": "你嘅密碼一定要同你嘅用戶名唔一樣。",
        "password-login-forbidden": "呢個用戶名同密碼嘅利用係被禁止嘅。",
        "mailmypassword": "重設密碼",
        "anoneditwarning": "'''警告:'''閣下重未登入。閣下嘅 IP 地址會喺爾一版嘅修訂歷史裡邊記錄落嚟。",
        "anonpreviewwarning": "''你重未登入,你嘅 IP 位址會喺呢個頁面嘅修訂歷史中記錄落嚟。''",
        "missingsummary": "'''提醒:''' 你未提供編輯摘要。如果你再撳多一下「{{int:savearticle}}」嘅話,咁你儲存嘅編輯就會無摘要。",
+       "selfredirect": "<strong>警告:</strong> 你個跳轉彈返去自己度。\n你可能設錯咗跳轉目標,或者改錯咗版。\n如果你再撳多「{{int:savearticle}}」一下,就會照幫你開呢個跳轉。",
        "missingcommenttext": "請輸入一個註解。",
        "missingcommentheader": "'''提醒:'''你響呢個註解度並無提供一個主題/標題。如果你再撳一次「{{int:savearticle}}」,你嘅編輯就會無題。",
        "summary-preview": "摘要預覽:",
        "subject-preview": "標題/頭條預覽:",
+       "previewerrortext": "預覽你嘅修改嗰陣出錯。",
        "blockedtitle": "用戶已經封鎖",
        "blockedtext": "你嘅用戶名或者 IP 位址已經被 $1 封咗。\n\n呢次封鎖係由$1所封嘅。當中嘅原因係''$2''。\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 對於被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]],討論呢次封鎖。\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「電郵呢個用戶」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會封鎖嘅。\n\n你現時嘅 IP 位址係 $3 ,而個封鎖 ID 係 #$5。 請你喺你嘅查詢都註明以上封鎖嘅資料。",
        "autoblockedtext": "你嘅IP地址已經被自動封鎖,由於之前嘅另一位用戶係畀$1封咗。\n而封鎖嘅原因係:\n\n:''$2''\n\n* 呢次封鎖嘅開始時間係:$8\n* 呢次封鎖嘅到期時間係:$6\n* 對於被封鎖者:$7\n\n你可以聯絡 $1 或者其他嘅[[{{MediaWiki:Grouppage-sysop}}|管理員]],討論呢次封鎖。\n\n除非你已經響你嘅[[Special:Preferences|戶口喜好設定]]入面設定咗有效嘅電郵地址,否則你係唔可以用「電郵呢個用戶」嘅功能。當設定咗一個有效嘅電郵地址之後,呢個功能係唔會封鎖嘅。\n\n你現時用緊嘅 IP 地址係 $3,個封鎖 ID 係 #$5。 請喺你嘅查詢都註明呢個封鎖上面嘅資料。",
        "postedit-confirmation-saved": "呢版經已儲存咗。",
        "edit-already-exists": "唔可以開一新版。\n佢已經存在。",
        "defaultmessagetext": "預設訊息文字",
+       "invalid-content-data": "無效嘅內容資料",
        "content-not-allowed-here": "「$1」唔可以輸入[[$2]]。",
        "editwarning-warning": "離開爾一版會令到閣下嘅修改唔見咗。\n閣下可以喺喜好設定嘅\"{{int:prefs-editing}}\"小節度停用爾個警告。",
        "editpage-notsupportedcontentformat-title": "唔支持爾種內容格式。",
        "content-model-text": "純文字",
        "content-model-javascript": "JavaScript程式語言",
        "content-model-css": "層疊樣式表",
+       "content-json-empty-object": "吉嘅嘢",
+       "content-json-empty-array": "吉嘅陣列",
        "duplicate-args-category": "模用重複參數嘅嘅版面",
        "expensive-parserfunction-warning": "警告: 呢一版有太多耗費嘅語法功能呼叫。\n\n佢應該少過$2次呼叫,佢而家係$1次呼叫。",
        "expensive-parserfunction-category": "響版度有太多嘅耗費嘅語法功能呼叫",
        "undo-success": "呢個編輯可以取消。請檢查一下個差異去確認呢個係你要去做嘅,跟住儲存下面嘅更改去完成編輯。",
        "undo-failure": "呢個編輯唔能夠取消,由於同途中嘅編輯有衝突。",
        "undo-norev": "呢個編輯唔能夠取消,由於佢唔存在或者刪除咗。",
+       "undo-nochange": "呢個編輯睇嚟經已一早取消咗。",
        "undo-summary": "取消由[[Special:Contributions/$2|$2]] ([[User talk:$2|對話]])所做嘅修訂 $1",
+       "undo-summary-username-hidden": "取消匿埋咗嘅用戶嘅修改版本 $1",
        "cantcreateaccounttitle": "唔可以開新戶口",
        "cantcreateaccount-text": "由呢個IP地址 ('''$1''') 開嘅新戶口已經被[[User:$3|$3]]封鎖。\n\n當中俾$3封鎖嘅原因係''$2''",
+       "cantcreateaccount-range-text": "由呢個IP地址範圍'''$1'''(包括你個IP '''$4''')開嘅新戶口已經畀[[User:$3|$3]]封鎖咗。\n\n$3畀嘅理由係''$2''",
        "viewpagelogs": "睇呢頁嘅日誌",
        "nohistory": "呢版冇歷史。",
        "currentrev": "最新嘅修訂",
        "revdelete-no-file": "指定嘅檔案未存在。",
        "revdelete-show-file-confirm": "你係咪真係想去睇響$2 $3刪咗 \"$1\" 嘅檔案修訂?",
        "revdelete-show-file-submit": "係",
+       "revdelete-selected-text": "揀咗[[:$2]]嘅$1個版本:",
+       "revdelete-selected-file": "揀咗[[:$2]]嘅$1個檔案版本:",
        "logdelete-selected": "揀咗嘅日誌事件:",
+       "revdelete-text-text": "刪咗嘅版本重喺修改紀錄度,但入面嘅內容唔畀公眾睇。",
+       "revdelete-text-file": "刪咗嘅檔案版本重喺檔案修改紀錄度,但入面嘅內容唔畀公眾睇。",
+       "logdelete-text": "刪咗嘅日誌項目重喺日誌度,但入面嘅內容唔畀公眾睇。",
+       "revdelete-text-others": "其他管理員可以睇收埋咗嘅內容同埋恢復返佢,除非設咗額外條件。",
        "revdelete-confirm": "請確認你肯定去做嘅話,你就要明白到後果,同埋呢個程序符合[[{{MediaWiki:Policy-url}}|政策]]。",
        "revdelete-suppress-text": "壓制'''只'''應該響下面嘅情況之下進行:\n* 可能係誹謗嘅資料\n* 唔合適嘅個人資料\n*: ''屋企地址、電話號碼、身份證號碼等。''",
        "revdelete-legend": "設定可見性嘅限制",
        "mergehistory-empty": "無修訂可以合併",
        "mergehistory-success": "[[:$1]]嘅$3次修訂已經成功噉合併到[[:$2]]。",
        "mergehistory-fail": "歷史合併唔到,請重新檢查嗰一版同埋時間參數。",
+       "mergehistory-fail-toobig": "唔能夠合併編輯紀錄,因為入面超過咗$1個版本嘅上限。",
        "mergehistory-no-source": "來源頁$1唔存在。",
        "mergehistory-no-destination": "目的頁$1唔存在。",
        "mergehistory-invalid-source": "來源頁一定要係一個有效嘅標題。",
        "mergelogpagetext": "下面係一個最近由一版嘅修訂記錄合併到另一個嘅一覽。",
        "history-title": "「$1」嘅修訂歷史",
        "difference-title": "\"$1\" 版本嘅差別",
+       "difference-title-multipage": "「$1」同「$2」嘅差別",
        "difference-multipage": "(版之間嘅差異)",
        "lineno": "第$1行:",
        "compareselectedversions": "比較被選嘅修訂",
        "showhideselectedversions": "顯示/隱藏揀咗嘅修訂",
        "editundo": "復原",
+       "diff-empty": "(無差別)",
        "diff-multi-sameuser": "(無顯示同一用戶中途改嘅 $1 個版本)",
+       "diff-multi-otherusers": "(無顯示{{PLURAL:$2|另一個用戶|另外$2個用戶}}中途改嘅 $1 個版本)",
        "diff-multi-manyusers": "(由$2位更多用戶所做嘅$1個中途修訂冇顯示到)",
        "searchresults": "搵嘢結果",
        "searchresults-title": "對\"$1\"嘅搵嘢結果",
        "notextmatches": "冇頁面文字符合",
        "prevn": "前$1",
        "nextn": "後{{PLURAL:$1|$1}}",
+       "prev-page": "上一版",
+       "next-page": "下一版",
        "prevn-title": "前$1項結果",
        "nextn-title": "後$1項結果",
        "shown-title": "每版顯示$1項結果",
        "search-result-category-size": "$1位成員 ($2個細類,$3個檔案)",
        "search-redirect": "(跳轉 $1)",
        "search-section": "(小節 $1)",
+       "search-category": "(類 $1)",
+       "search-file-match": "(夾啱樓案内容)",
        "search-suggest": "你係唔係搵: $1",
        "search-interwiki-caption": "姊妹計劃",
-       "search-interwiki-default": "$1項結果:",
+       "search-interwiki-default": "嚟自$1嘅結果:",
        "search-interwiki-more": "(更多)",
        "search-relatedarticle": "有關",
        "searchrelated": "有關",
        "searchall": "全部",
        "showingresults": "'自#'''$2'''起顯示最多'''$1'''個結果。",
+       "showingresultsinrange": "下面顯示由第 <strong>$2</strong> 個到第 <strong>$3</strong> 個入面嘅第 {{PLURAL:$1|<strong>$1</strong> 個結果}}:",
        "search-showingresults": "{{PLURAL:$4|第 <strong>$1</strong>個結果,一共有 <strong>$3</strong> 個|第 <strong>$1 - $2</strong> 個結果,一共有 <strong>$3</strong> 個}}",
        "search-nonefound": "響個查詢度無結果配合。",
        "powersearch-legend": "進階搵嘢",
        "powersearch-togglelabel": "检查:",
        "powersearch-toggleall": "全部",
        "powersearch-togglenone": "無",
+       "powersearch-remember": "記住今次選擇方便第時搵嘢用返",
        "search-external": "出面搵嘢",
        "searchdisabled": "{{SITENAME}}嘅搜尋功能已經關閉。你可以利用Google嚟搵。不過佢哋對{{SITENAME}}嘅索引可能唔係最新嘅。",
+       "search-error": "搵嘢嗰陣出錯:$1",
        "preferences": "喜好設定",
        "mypreferences": "自訂喜好",
        "prefs-edits": "編輯數:",
+       "prefsnologintext2": "請簽到去改你嘅自訂喜好。",
        "prefs-skin": "畫面",
        "skin-preview": "預覽",
        "datedefault": "冇喜好",
        "prefs-labs": "實驗性嘅特色",
+       "prefs-user-pages": "用戶頁",
        "prefs-personal": "用戶簡介",
        "prefs-rc": "最近更改",
        "prefs-watchlist": "監視清單",
+       "prefs-editwatchlist": "編輯監視清單",
+       "prefs-editwatchlist-label": "編輯監視清單入面嘅項目:",
+       "prefs-editwatchlist-edit": "睇下同刪走你個編輯監視清單入面嘅標題",
+       "prefs-editwatchlist-raw": "編輯原始監視清單",
+       "prefs-editwatchlist-clear": "清理你嘅監視清單",
        "prefs-watchlist-days": "監視清單嘅顯示日數:",
-       "prefs-watchlist-days-max": "Maximum $1 {{PLURAL:$1|day|days}}",
+       "prefs-watchlist-days-max": "最多 $1 日",
        "prefs-watchlist-edits": "喺加強版監視清單度嘅最多顯示更改數:",
        "prefs-watchlist-edits-max": "最大數量:1000",
        "prefs-watchlist-token": "監視清單幣:",
        "prefs-misc": "雜項",
        "prefs-resetpass": "改密碼",
+       "prefs-changeemail": "改電郵地址",
+       "prefs-setemail": "入電郵地址",
        "prefs-email": "電郵選項",
        "prefs-rendering": "外觀",
        "saveprefs": "儲存",
-       "restoreprefs": "恢復全部預設設定",
+       "restoreprefs": "恢復全部預設設定(喺所有項目)",
        "prefs-editing": "編輯中",
        "rows": "行數:",
        "columns": "列數:",
        "recentchangesdays-max": "最多 $1 日",
        "recentchangescount": "預設顯示嘅編輯數:",
        "prefs-help-recentchangescount": "呢個包埋最近修改、頁歷史同埋日誌紀錄。",
+       "prefs-help-watchlist-token2": "呢個係網上訂閱你個監視清單嘅密匙。\n任何人只要知道個密匙,就會睇到你個監視清單,所以唔好畀人知。\n如果有需要嘅話,[[Special:ResetTokens|你可以重設佢]]。",
        "savedprefs": "你嘅喜好設定已經儲存。",
        "timezonelegend": "時區:",
        "localtime": "本地時間:",
-       "timezoneuseserverdefault": "用伺服器預設值",
+       "timezoneuseserverdefault": "用維基預設值($1)",
        "timezoneuseoffset": "其他 (指定偏移)",
        "servertime": "伺機器時間:",
        "guesstimezone": "由瀏覽器填上",
        "timezoneregion-indian": "印度洋",
        "timezoneregion-pacific": "太平洋",
        "allowemail": "由其它用戶啟用電子郵件",
-       "prefs-searchoptions": "搵嘢選項",
+       "prefs-searchoptions": "搵嘢",
        "prefs-namespaces": "空間名",
        "default": "預設",
        "prefs-files": "檔案",
        "prefs-reset-intro": "你可以用呢版去重設你嘅喜好設定到網站預設值。呢個動作無得番轉頭。",
        "prefs-emailconfirm-label": "電郵確認:",
        "youremail": "電郵:",
-       "username": "用戶名:",
-       "prefs-memberingroups": "{{PLURAL:$1|一|多}}組嘅成員:",
+       "username": "{{GENDER:$1|用戶名}}:",
+       "prefs-memberingroups": "{{PLURAL:$1|組}}嘅{{GENDER:$2|成員}}:",
        "prefs-registration": "註冊時間:",
        "yourrealname": "真名:",
        "yourlanguage": "話:",
-       "yourvariant": "變換:",
+       "yourvariant": "內容語言變換:",
+       "prefs-help-variant": "你想喺呢度嘅內容顯示嘅語言變換。",
        "yournick": "新花名:",
        "prefs-help-signature": "響討論版嘅評論應該要用 \"<nowiki>~~~~</nowiki>\" 簽名,噉就會轉做你嘅簽名同埋一個時間截記。",
        "badsig": "無效嘅程式碼簽名。檢查吓 HTML 有無錯。",
        "badsiglength": "你嘅花名太長喇。\n唔長得過$1個字元。",
-       "yourgender": "性別:",
-       "gender-unknown": "æ\9cªæ\8c\87å®\9a",
-       "gender-male": "",
-       "gender-female": "女",
-       "prefs-help-gender": "å\8f¯é\81¸: ç\94¨å\9a\9fæ\95´è»\9f件æ\80§å\88¥æ\8c\87å®\9aã\80\82呢項資料將會被公開。",
+       "yourgender": "你想點畀人稱呼?",
+       "gender-unknown": "æ\88\91å\94\94æ\83³è¬\9b",
+       "gender-male": "佢寫維基",
+       "gender-female": "å§\96寫維å\9fº",
+       "prefs-help-gender": "å\91¢é \85å\8f¯ä»¥è\87ªå·±æ\8f\80å¡«å®\9aå\94\94å¡«ã\80\82\n系統æ\9c\83ç\94¨å\91¢é \85è³\87æ\96\99å\9a\9få\88¤æ\96·é»\9eç\94¨é\81©ç\95¶èª\9eæ³\95å\8e»ç¨±å\91¼ä½ ã\80\82\n呢項資料將會被公開。",
        "email": "電郵",
-       "prefs-help-realname": "真名可以唔填。\n如果你畀埋佢,有需要嘅時候會用佢來標示你嘅工夫。",
+       "prefs-help-realname": "真名可以揀填定唔填。\n如果你畀埋佢,可能會用佢嚟標示你嘅貢獻。",
        "prefs-help-email": "電郵地址可以唔填,但當你唔記得咗你個密碼嗰陣需要利用電郵地址將新密碼重設寄番畀你。",
        "prefs-help-email-others": "亦可以響人哋唔知你電郵地址嘅情況之下都可以聯絡你。",
        "prefs-help-email-required": "需要電郵地址。",
        "prefs-signature": "簽名",
        "prefs-dateformat": "日期格式",
        "prefs-timeoffset": "時間偏移",
-       "prefs-advancedediting": "進階選項",
+       "prefs-advancedediting": "普通選項",
+       "prefs-editor": "編輯",
+       "prefs-preview": "預覽",
        "prefs-advancedrc": "進階選項",
        "prefs-advancedrendering": "進階選項",
        "prefs-advancedsearchoptions": "進階選項",
        "prefs-advancedwatchlist": "進階選項",
        "prefs-displayrc": "顯示選項",
        "prefs-displaywatchlist": "顯示選項",
+       "prefs-tokenwatchlist": "密匙",
        "prefs-diffs": "差異",
+       "prefs-help-prefershttps": "呢項喜好設定會喺你下次簽到先至開始生效。",
+       "prefswarning-warning": "你改嘅喜好設定改動重未記低。\n如果你未撳「$1」就走咗,你嘅喜好設定唔會有更新。",
        "email-address-validity-valid": "電郵地址睇嚟有效",
        "email-address-validity-invalid": "請打一個有效嘅電郵地址",
        "userrights": "用戶權限管理",
        "userrights-lookup-user": "管理用戶組",
        "userrights-user-editname": "輸入一個用戶名:",
        "editusergroup": "編輯用戶組",
-       "editinguser": "改緊用戶'''[[User:$1|$1]]''' ([[User talk:$1|{{int:talkpagelinktext}}]]{{int:pipe-separator}}[[Special:Contributions/$1|{{int:contribslink}}]]) 嘅用戶權限",
+       "editinguser": "改緊<strong>[[User:$1|$1]]</strong>嘅用戶權限 $2",
        "userrights-editusergroup": "編輯用戶組",
        "saveusergroups": "儲存用戶組",
        "userrights-groupsmember": "屬於:",
        "userrights-no-interwiki": "你並無權限去編輯響其它wiki嘅用戶權限。",
        "userrights-nodatabase": "資料庫$1唔存在或者唔係本地嘅。",
        "userrights-nologin": "你一定要以操作員戶口[[Special:UserLogin|登入]]咗之後先可以指定用戶權限。",
-       "userrights-notallowed": "你嘅戶口無權限去指定用戶權限。",
+       "userrights-notallowed": "你無權限去加減用戶權限。",
        "userrights-changeable-col": "你可以改嘅組",
        "userrights-unchangeable-col": "你唔可以改嘅組",
        "group": "組:",
        "group-bureaucrat": "事務員",
        "group-suppress": "監督",
        "group-all": "(全部)",
-       "group-user-member": "用戶",
-       "group-autoconfirmed-member": "自動確認用戶",
+       "group-user-member": "{{GENDER:$1|用戶}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|自動確認用戶}}",
        "group-bot-member": "{{GENDER:$1|機械人}}",
        "group-sysop-member": "{{GENDER:$1|管理員}}",
-       "group-bureaucrat-member": "事務員",
-       "group-suppress-member": "監督",
+       "group-bureaucrat-member": "{{GENDER:$1|事務員}}",
+       "group-suppress-member": "{{GENDER:$1|監督}}",
        "grouppage-user": "{{ns:project}}:用戶",
        "grouppage-autoconfirmed": "{{ns:project}}:自動確認用戶",
        "grouppage-bot": "{{ns:project}}:機械人",
        "right-reupload-shared": "於本地無視共用媒體檔案庫上嘅檔案",
        "right-upload_by_url": "由一個URL上載檔案",
        "right-purge": "唔需要確認之下清除網站快取",
-       "right-autoconfirmed": "編輯半保護版",
+       "right-autoconfirmed": "唔受IP嘅利用率限制影響",
        "right-bot": "視為一個自動程序",
        "right-nominornewtalk": "小編輯唔引發新信息提示",
        "right-apihighlimits": "響API查詢度用更高嘅上限",
        "right-deletedtext": "睇刪咗嘅修訂度嘅已刪嘅字同更改",
        "right-browsearchive": "搵刪咗嘅版",
        "right-undelete": "反刪版",
-       "right-suppressrevision": "睇同恢復由操作員隱藏嘅修訂",
+       "right-suppressrevision": "睇下、收埋同恢復任何用戶指定頁面版本",
        "right-suppressionlog": "去睇私人嘅日誌",
        "right-block": "封鎖其他用戶唔畀編輯",
        "right-blockemail": "封鎖用戶唔畀寄電郵",
        "right-hideuser": "封鎖用戶名,對公眾隱藏",
        "right-ipblock-exempt": "繞過IP封鎖、自動封鎖同埋範圍封鎖",
        "right-proxyunbannable": "繞過Proxy嘅自動封鎖",
-       "right-unblockself": "解封佢哋自己",
-       "right-protect": "改保護等級同埋編輯保護版",
-       "right-editprotected": "編輯ä¿\9dè­·ç\89\88ï¼\88ç\84¡é\80£ä¸²ä¿\9dè­·ï¼\89",
+       "right-unblockself": "解封自己",
+       "right-protect": "改保護等級同埋編輯流水保護版",
+       "right-editprotected": "ç\94¨ã\80\8c{{int:protect-level-sysop}}ã\80\8dæ¬\8aé\99\90å\8e»ç·¨è¼¯ä¿\9dè­·ç\89\88",
        "right-editinterface": "編輯用戶界面",
        "right-editusercssjs": "編輯其他用戶嘅CSS同埋JavaScript檔",
        "right-editusercss": "編輯其他用戶嘅CSS檔",
        "action-suppressionlog": "睇呢個私有日誌",
        "action-block": "封鎖呢位用戶嘅編輯",
        "action-protect": "改呢版嘅保護等級",
-       "action-import": "ç\94±å\8f¦ä¸\80å\80\8bwikiå\80\92å\85¥å\91¢ä¸\80版",
-       "action-importupload": "由一個檔案上載倒入呢一版",
+       "action-import": "ç\94±å\85¶å®\83wiki度å\80\92å\85¥版",
+       "action-importupload": "由檔案上載度倒入版",
        "action-patrol": "標示其它嘅編輯做已巡查嘅",
        "action-autopatrol": "將你嘅編輯標示做已巡查嘅",
        "action-unwatchedpages": "睇未畀人監視嘅版",
        "action-userrights": "編輯全部嘅權限",
        "action-userrights-interwiki": "編輯響其它wiki用戶嘅權限",
        "action-siteadmin": "鎖同解鎖資料庫",
+       "action-sendemail": "送電郵",
+       "action-editmywatchlist": "改監視清單",
+       "action-viewmywatchlist": "睇監視清單",
+       "action-viewmyprivateinfo": "睇你嘅私人資料",
+       "action-editmyprivateinfo": "改你嘅私人資料",
        "nchanges": "$1次更改",
+       "enhancedrc-since-last-visit": "{{PLURAL:$1|你上次嚟之後}}有 $1 個",
        "enhancedrc-history": "歷史",
        "recentchanges": "最近改過嘅嘢",
        "recentchanges-legend": "最近更改選項",
        "recentchanges-summary": "追蹤對哩一個 wiki 嘅最後更改。",
+       "recentchanges-noresult": "喺指定時段無符合呢啲條件嘅改動。",
        "recentchanges-feed-description": "追蹤對哩一個 wiki 度呢個集合嘅最後更改。",
        "recentchanges-label-newpage": "呢次編輯開咗一個新版",
        "recentchanges-label-minor": "呢個係一個細編輯",
        "recentchanges-label-plusminus": "頁面位元組大細變化",
        "recentchanges-legend-heading": "'''標記:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (睇埋[[Special:NewPages|新開版]])",
-       "rcnotefrom": "以ä¸\8bä¿\82è\87ª'''$2'''å\98\85æ\9b´æ\94¹(顯示到'''$1''')。",
+       "rcnotefrom": "ä¸\8bé\9d¢å\98\85{{PLURAL:$5|æ\94¹å\8b\95}}ç\94± <strong>$3 $4</strong> é\96\8bå§\8b(顯示到'''$1''')。",
        "rclistfrom": "顯示由$3 $2嘅新更改",
        "rcshowhideminor": "$1小編輯",
        "rcshowhideminor-show": "顯示",
        "rcshowhidebots-show": "顯示",
        "rcshowhidebots-hide": "收埋",
        "rcshowhideliu": "$1登記咗嘅用戶",
+       "rcshowhideliu-show": "顯示",
        "rcshowhideliu-hide": "收埋",
        "rcshowhideanons": "$1匿名用戶",
        "rcshowhideanons-show": "顯示",
        "rcshowhideanons-hide": "收埋",
        "rcshowhidepatr": "$1巡邏過嘅編輯",
+       "rcshowhidepatr-show": "顯示",
+       "rcshowhidepatr-hide": "收埋",
        "rcshowhidemine": "$1我嘅編輯",
        "rcshowhidemine-show": "顯示",
        "rcshowhidemine-hide": "收埋",
        "rc_categories_any": "任何",
        "rc-change-size-new": "改完後係$1位元組",
        "newsectionsummary": "/* $1 */ 新小節",
-       "rc-enhanced-expand": "顯示細節 (需要 JavaScript)",
+       "rc-enhanced-expand": "顯示細節",
        "rc-enhanced-hide": "隱藏細節",
+       "rc-old-title": "原先標題係「$1」",
        "recentchangeslinked": "連結頁嘅更改",
        "recentchangeslinked-feed": "連結頁嘅更改",
        "recentchangeslinked-toolbox": "連結頁嘅更改",
        "reuploaddesc": "取消上載再返到去上載表格",
        "upload-tryagain": "遞交改咗嘅檔案描述",
        "uploadnologin": "重未登入",
-       "uploadnologintext": "你必須先[[Special:UserLogin|登入]]去上載檔案。",
+       "uploadnologintext": "請$1去上載檔案。",
        "upload_directory_missing": "嗰個上載嘅目錄 ($1) 唔見咗,唔可以由網頁伺服器建立。",
        "upload_directory_read_only": "嗰個上載嘅目錄 ($1) 而家唔能夠被網頁伺服器寫入。",
        "uploaderror": "上載錯誤",
        "upload-recreate-warning": "'''警告:一個同名嘅檔案曾經被刪除過或者搬走咗。'''\n\n呢版嘅刪除同移動日誌響呢度提供以便參考:",
        "uploadtext": "用下面嘅表格嚟上載檔案。\n要睇或者搵嘢之前上載嘅圖像請去[[Special:FileList|已上載檔案一覽]],(再)上載嘅動作會喺[[Special:Log/upload|上載日誌]]裏面記錄落嚟,而刪除嘅動作會喺[[Special:Log/delete|刪除日誌]]裏面記錄落嚟。\n\n如果要喺頁面度引入呢張圖像,可以使用以下其中一種方式嘅連結:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}:file.jpg<nowiki>]]</nowiki></code>'''去用檔案嘅完整版\n* '''<code><nowiki>[[</nowiki>{{ns:file}}:file.png|200px|thumb|left|替代文字<nowiki>]]</nowiki></code>'''去用200像素比例闊,靠左邊加盒,響描述度加'替代文字'\n* '''<code><nowiki>[[</nowiki>{{ns:media}}:file.ogg<nowiki>]]</nowiki></code>''' 直接連結到檔案而唔顯示個檔案。",
-       "upload-permitted": "准許嘅檔案類型: $1。",
-       "upload-preferred": "建議嘅檔案類型: $1。",
-       "upload-prohibited": "禁止嘅檔案類型: $1。",
+       "upload-permitted": "准許嘅檔案{{PLURAL:$2|類型}}:$1。",
+       "upload-preferred": "建議嘅檔案{{PLURAL:$2|類型}}:$1。",
+       "upload-prohibited": "禁止嘅檔案{{PLURAL:$2|類型}}:$1。",
        "uploadlogpage": "上載日誌",
        "uploadlogpagetext": "以下係最近檔案上載嘅一覽表。\n睇[[Special:NewFiles|新圖像畫廊]]去睇更詳細嘅總覽。",
        "filename": "檔名",
        "ignorewarnings": "忽略任何警告",
        "minlength1": "檔名必須最少要有一個字。",
        "illegalfilename": "檔名「$1」含有頁面標題所唔允許嘅字。請試下改檔名再上載。",
+       "filename-toolong": "檔案名唔可以長過240位元組。",
        "badfilename": "檔名已經更改成「$1」。",
        "filetype-mime-mismatch": "檔案擴展名 \".$1\" 唔搭偵測到檔案嘅MIME類型 ($2)。",
        "filetype-badmime": "「$1」嘅MIME類型檔案係唔容許上載嘅。",
        "large-file": "建議檔案嘅大細唔好大過$1 bytes,呢個檔案有$2 bytes",
        "largefileserver": "呢個檔案超過咗伺服器設定允許嘅大細。",
        "emptyfile": "你上載嘅檔案似乎係空嘅。噉樣可能係因為你打錯咗個檔名。請檢查吓你係唔係真係要上載呢個檔案。",
-       "fileexists": "呢個檔名已經存在,如果你唔肯定係唔係要更改<strong>[[:$1]]</strong>,請先檢查佢。 [[$1|thumb]]",
+       "windows-nonascii-filename": "呢個維基唔支援有特殊字元嘅檔案名。",
+       "fileexists": "呢個檔名已經存在,如果你唔肯定係唔係要更改,請先檢查<strong>[[:$1]]</strong>。 [[$1|thumb]]",
        "filepageexists": "呢個檔嘅描述頁已經響<strong>[[:$1]]</strong>開咗,但係呢個名嘅檔案重未存在。你輸入咗嘅摘要係唔會顯示響個描述頁度。要令到個摘要響嗰度出現,你就要手動噉去改佢。\n[[$1|thumb]]",
-       "fileexists-extension": "一個相似檔名嘅檔案已經存在: [[$2|thumb]]\n* 上載檔案嘅檔名: <strong>[[:$1]]</strong>\n* 現有檔案嘅檔名: <strong>[[:$2]]</strong>\n請揀一個唔同嘅名。",
+       "fileexists-extension": "一個相似檔名嘅檔案已經存在: [[$2|thumb]]\n* 上載檔案嘅檔名:<strong>[[:$1]]</strong>\n* 現有檔案嘅檔名:<strong>[[:$2]]</strong>\n你係咪要揀返個唔同嘅名?",
        "fileexists-thumbnail-yes": "呢個檔案好似係一幅圖像縮細咗嘅版本''(縮圖)''。 [[$1|thumb]]\n請檢查清楚個檔案<strong>[[:$1]]</strong>。\n如果檢查咗嘅檔案係同原本幅圖個大細係一樣嘅話,就唔使再上載多一幅縮圖。",
        "file-thumbnail-no": "個檔名係以<strong>$1</strong>開始。佢好似係一幅圖像嘅縮細版本''(縮圖)''。\n如果你有呢幅圖像嘅完整大細,唔係嘅話請再改過個檔名。",
        "fileexists-forbidden": "呢個檔案嘅名已經存在,唔可以覆蓋;麻煩返轉去用第二個名嚟上載呢個檔案。[[File:$1|thumb|center|$1]]",
        "upload-http-error": "一個HTTP錯誤發生咗: $1",
        "backend-fail-notexists": "檔案$1唔存在。",
        "backend-fail-delete": "刪唔到檔案「$1」。",
+       "backend-fail-alreadyexists": "檔案「$1」已經喺度。",
+       "backend-fail-store": "檔案「$1」存唔到去「$2」。",
+       "backend-fail-copy": "檔案「$1」抄唔到去「$2」。",
+       "backend-fail-move": "檔案「$1」搬唔到去「$2」。",
+       "backend-fail-opentemp": "唔能夠開個臨時檔案。",
+       "backend-fail-writetemp": "唔能夠寫個臨時檔案。",
+       "backend-fail-closetemp": "唔能夠閂個臨時檔案。",
+       "backend-fail-read": "讀唔到檔案「$1」。",
+       "backend-fail-create": "寫唔到檔案「$1」。",
+       "backend-fail-maxsize": "寫唔到檔案「$1」,因為佢大過$2個位元組。",
+       "backend-fail-readonly": "儲存後臺「$1」而家只能夠唯讀。理由係:「<em>$2</em>」",
+       "backend-fail-synced": "檔案「$1」喺內部儲存後臺入面狀態唔一致。",
+       "backend-fail-connect": "連唔到儲存後臺「$1」",
+       "backend-fail-internal": "儲存後臺「$1」唔知點解出錯",
+       "backend-fail-contenttype": "確定唔到存喺儲存後臺「$1」嘅內容類型。",
+       "lockmanager-notlocked": "唔可以解鎖「$1」;佢都無鎖住到。",
        "zip-file-open-error": "在開啟檔案進行ZIP檢查時出錯。",
        "zip-wrong-format": "呢個唔係一個ZIP檔案。",
        "zip-bad": "呢個係不可讀嘅ZIP檔案。\n因為呢個原因,唔可以進行保安檢查。",
        "uploadstash-errclear": "清除檔案唔成功。",
        "uploadstash-refresh": "更新檔案清單",
        "img-auth-accessdenied": "拒絕通行",
-       "img-auth-nopathinfo": "PATH_INFO唔見咗。\n你嘅伺服器重未設定呢個資料。\n佢可能係CGI為本,唔支援img_auth。\n睇吓 https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization。",
+       "img-auth-nopathinfo": "PATH_INFO唔見咗。\n你嘅伺服器重未設定呢個資料。\n佢可能係CGI為本,唔支援img_auth。\n睇吓 https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization 。",
        "img-auth-notindir": "所請求嘅路徑唔響個已經設定咗嘅上載目錄。",
        "img-auth-badtitle": "唔能夠由\"$1\"整一個有效標題。",
        "img-auth-nologinnWL": "你而家無登入,\"$1\"唔響個白名單度。",
        "license": "協議:",
        "license-header": "協議",
        "nolicense": "未揀",
+       "licenses-edit": "改牌照選項",
        "license-nopreview": "(無預覽可以用得到)",
-       "upload_source_url": " (啱嘅,公開嘅網址)",
-       "upload_source_file": " (你部電腦裏面嘅一個檔案)",
-       "listfiles-summary": "呢個特別版顯示全部上載過嘅檔案。\n響預設最後上載嘅檔案會顯示響呢個表嘅最頂。\n撳一欄嘅標題去改個排列。",
+       "upload_source_url": "(你個檔案來源嚟自一個啱嘅、公開嘅網址)",
+       "upload_source_file": "(你個檔案來源嚟自你部電腦裏面)",
+       "listfiles-delete": "刪除",
+       "listfiles-summary": "呢個特別頁顯示全部上載咗嘅檔案。",
        "listfiles_search_for": "搵媒體名:",
        "imgfile": "檔案",
        "listfiles": "檔案清單",
        "listfiles_size": "大細",
        "listfiles_description": "描述",
        "listfiles_count": "版本",
+       "listfiles-show-all": "包埋圖像舊版",
+       "listfiles-latestversion": "而家嘅版本",
+       "listfiles-latestversion-yes": "係",
+       "listfiles-latestversion-no": "唔係",
        "file-anchor-link": "檔案",
        "filehist": "檔案歷史",
        "filehist-help": "撳個日期/時間去睇響嗰個時間出現過嘅檔案。",
        "linkstoimage-more": "多過$1版連過去呢個檔案。\n下面嘅表只係列示咗連去呢個檔案嘅最頭$1版。\n一個[[Special:WhatLinksHere/$2|完整嘅表]]可以提供。",
        "nolinkstoimage": "冇個頁面連結到呢個檔案。",
        "morelinkstoimage": "去睇連到呢個檔案嘅[[Special:WhatLinksHere/$1|更多連結]]。",
+       "linkstoimage-redirect": "$1(檔案跳轉)$2",
        "duplicatesoffile": "下面嘅$1個檔案係同呢個檔案重覆 ([[Special:FileDuplicateSearch/$2|更多細節]]):",
        "sharedupload": "呢個檔案係出自$1,可以喺其他計劃中使用。",
        "sharedupload-desc-there": "呢個檔案係出自$1,可以喺其他計劃中使用。\n更多資訊請睇[$2 檔案描述頁]。",
        "filedelete-reason-dropdown": "\n*常用刪除原因\n** 侵犯版權\n** 重覆檔案",
        "filedelete-edit-reasonlist": "編輯刪除原因",
        "filedelete-maintenance": "響維護嗰陣已經暫時停用檔案刪除同恢復。",
+       "filedelete-maintenance-title": "刪唔到檔案",
        "mimesearch": "MIME 搜尋",
-       "mimesearch-summary": "呢一版可以過濾有關檔案嘅MIME類型。輸入方法:contenttype/subtype,例如 <code>image/jpeg</code>。",
+       "mimesearch-summary": "呢一版可以過濾有關檔案嘅MIME類型。\n輸入方法:contenttype/subtype 或者 contenttype/*,例如 <code>image/jpeg</code>。",
        "mimetype": "MIME 類型:",
        "download": "下載",
        "unwatchedpages": "未監視嘅頁面",
        "listredirects": "彈嚟彈去一覽",
+       "listduplicatedfiles": "重覆檔案一覽",
        "unusedtemplates": "未用嘅模",
        "unusedtemplatestext": "呢一頁列示喺{{ns:template}}空間名未包括喺其它頁面嘅全部頁面。請記得喺刪除佢哋之前檢查其它連結到呢個模嘅頁面。",
        "unusedtemplateswlh": "其它連結",
        "randompage": "隨便一版",
        "randompage-nopages": "響下面嘅{{PLURAL:$2|空間名}}度搵唔到一版: $1",
+       "randomincategory": "類入面是但一版",
+       "randomincategory-invalidcategory": "「$1」唔係有效嘅類名。",
+       "randomincategory-nopages": "[[:Category:$1|$1]]類入面無嘢。",
+       "randomincategory-category": "類:",
+       "randomincategory-legend": "類入面是但一版",
        "randomredirect": "隨便彈",
        "randomredirect-nopages": "響 \"$1\" 空間名度冇一個彈去版。",
        "statistics": "統計",
        "statistics-users": "註冊咗嘅[[Special:ListUsers|用戶]]",
        "statistics-users-active": "活躍用戶",
        "statistics-users-active-desc": "響$1日前做過動作嘅用戶",
+       "pageswithprop": "有屬性嘅頁",
+       "pageswithprop-legend": "有屬性嘅頁",
+       "pageswithprop-prop": "屬性名:",
+       "pageswithprop-submit": "去",
        "doubleredirects": "雙重跳轉",
        "doubleredirectstext": "每一行都順次序寫住第一頁名,佢嘅目的頁,同埋目的頁再指去邊度。改嘅時候,應該將第一個跳轉頁轉入第三頁。\n<del>劃咗</del>嘅項目係已經解決咗嘅。",
-       "double-redirect-fixed-move": "[[$1]]已經搬好咗,佢而家跳轉過去[[$2]]。",
-       "double-redirect-fixed-maintenance": "修復[[$1]]嘅重定向到[[$2]]。",
+       "double-redirect-fixed-move": "[[$1]]已經搬好咗。\n佢自動更新咗,而家跳轉過去[[$2]]。",
+       "double-redirect-fixed-maintenance": "喺維護工作度自動修復[[$1]]嘅跳轉到[[$2]]。",
        "double-redirect-fixer": "跳轉修正器",
        "brokenredirects": "破碎嘅跳轉",
        "brokenredirectstext": "以下嘅跳轉係指向唔存在嘅頁面:",
        "fewestrevisions": "有最少修改嘅版",
        "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
        "ncategories": "$1 個分類",
+       "ninterwikis": "$1 {{PLURAL:$1|個跨維基連結}}",
        "nlinks": "$1 條連結",
        "nmembers": "$1 位成員",
+       "nmemberschanged": "$1 → $2 {{PLURAL:$2|位成員}}",
        "nrevisions": "$1 次修訂",
        "nviews": "$1 次瀏覽",
        "nimagelinks": "用響$1版",
        "wantedpages": "被徵求嘅頁面",
        "wantedpages-badtitle": "響結果組嘅無效標題: $1",
        "wantedfiles": "被徵求嘅檔案",
+       "wantedfiletext-nocat-noforeign": "下面檔案有用到,但係唔存在。",
        "wantedtemplates": "被徵求嘅模",
        "mostlinked": "有最多連結嘅頁面",
        "mostlinkedcategories": "有最多連結嘅分類",
-       "mostlinkedtemplates": "有最多連結嘅模",
+       "mostlinkedtemplates": "有最多嵌入嘅版",
        "mostcategories": "有最多分類嘅頁面",
        "mostimages": "有最多連結嘅檔案",
+       "mostinterwikis": "有最多跨維基連結嘅頁面",
        "mostrevisions": "有最多修改嘅頁面",
        "prefixindex": "全部頁嘅前綴",
        "shortpages": "短頁",
        "protectedpages": "保護頁",
        "protectedpages-indef": "只有無期保謢頁",
        "protectedpages-cascade": "只有連串保護頁",
+       "protectedpages-noredirect": "收埋跳轉",
        "protectedpagesempty": "響呢啲參數度,現時無頁面響度保護緊。",
+       "protectedpages-timestamp": "時間",
+       "protectedpages-page": "版",
+       "protectedpages-expiry": "到期",
+       "protectedpages-performer": "保護用戶",
+       "protectedpages-params": "保護參數",
        "protectedpages-reason": "原因",
+       "protectedpages-unknown-timestamp": "唔知",
+       "protectedpages-unknown-performer": "未知嘅用戶",
        "protectedtitles": "保護咗嘅標題",
        "protectedtitlesempty": "響呢啲參數之下並無標題保護住。",
        "listusers": "用戶一覽",
        "listusers-editsonly": "只顯示有編輯嘅用戶",
        "listusers-creationsort": "按建立日期排序",
+       "listusers-desc": "反向排序",
        "usereditcount": "$1次編輯",
        "usercreated": "響$1 $2{{GENDER:$3|建立}}",
        "newpages": "新頁",
        "pager-older-n": "舊$1次",
        "suppress": "監督",
        "querypage-disabled": "呢個特別版基於效能嘅原因停用咗。",
+       "apihelp": "API幫手",
+       "apihelp-no-such-module": "搵唔到模組「$1」。",
        "booksources": "書籍來源",
        "booksources-search-legend": "搵書源",
        "booksources-search": "搵",
        "booksources-text": "以下嘅連結清單列出其它一啲賣新書同二手書嘅網站,可能可以提供到有關你想搵嘅書嘅更多資料:",
        "booksources-invalid-isbn": "個ISBN無效;請檢查原來源複製落來嘅錯。",
-       "specialloguserlabel": "用戶:",
+       "specialloguserlabel": "執行人:",
        "speciallogtitlelabel": "目標(題目或者用戶):",
        "log": "日誌",
        "all-logs-page": "全部嘅公共日誌",
        "allpagesprefix": "用以下開頭嘅頁面:",
        "allpagesbadtitle": "提供嘅頁面名無效,又或者有一個跨語言或跨wiki嘅字頭。佢可能包括一個或多個字係唔可以用響標題度嘅。",
        "allpages-bad-ns": "{{SITENAME}}係無一個空間名叫做\"$1\"。",
+       "allpages-hide-redirects": "收埋跳轉",
+       "cachedspecial-refresh-now": "睇最新。",
        "categories": "類",
        "categoriespagetext": "下面嘅{{PLURAL:$1|類}}有版或媒體。\n[[Special:UnusedCategories|未用類]]唔會響呢度列示。\n請同時參閱[[Special:WantedCategories|需要嘅分類]]。",
        "categoriesfrom": "顯示由呢項起嘅類:",
        "deletedcontributions": "已經刪除咗嘅用戶貢獻",
        "deletedcontributions-title": "已經刪除咗嘅用戶貢獻",
        "sp-deletedcontributions-contribs": "貢獻",
-       "linksearch": "外部連結",
+       "linksearch": "搵出面嘅連結",
        "linksearch-pat": "搵嘅形態:",
        "linksearch-ns": "空間名",
        "linksearch-ok": "搵",
-       "linksearch-text": "可以用類似\"*.wikipedia.org\"嘅萬用字元。<br />\n支援嘅協議: <code>$1</code>",
+       "linksearch-text": "可以用類似「*.wikipedia.org」嘅萬用字元。\n需要至少一個頂級域名,好似「*.org」。<br />\n支援嘅{{PLURAL:$2|協議}}:<code>$1</code> (預設用 http:// 如果唔指定協議)",
        "linksearch-line": "$1 連自 $2",
        "linksearch-error": "萬用字元只可以響主機名嘅開頭度用。",
        "listusersfrom": "顯示由呢個字開始嘅用戶:",
        "listusers-blocked": "(封鎖咗)",
        "activeusers": "活躍用戶名單",
        "activeusers-intro": "呢個係響最近$1日之內有一啲動作嘅用戶名單。",
-       "activeusers-count": "響$3日之內嘅$1次編輯",
+       "activeusers-count": "響{{PLURAL:$3|$3日}}之內嘅$1次{{PLURAL:$1|編輯}}",
        "activeusers-from": "顯示用戶開始於:",
        "activeusers-hidebots": "隱藏機械人",
        "activeusers-hidesysops": "隱藏管理員",
        "activeusers-noresult": "搵唔到用戶。",
        "listgrouprights": "用戶組權限",
        "listgrouprights-summary": "下面係一個響呢個wiki定義咗嘅用戶權限一覽,同埋佢哋嘅存取權。\n更多有關個別權限嘅[[{{MediaWiki:Listgrouprights-helppage}}|更多細節]]可以響嗰度搵到。",
-       "listgrouprights-key": "* <span class=\"listgrouprights-granted\">畀咗嘅權限</span>\n* <span class=\"listgrouprights-revoked\">拎咗嘅權限</span>",
+       "listgrouprights-key": "說明:\n* <span class=\"listgrouprights-granted\">畀咗嘅權限</span>\n* <span class=\"listgrouprights-revoked\">拎咗嘅權限</span>",
        "listgrouprights-group": "組",
        "listgrouprights-rights": "權",
        "listgrouprights-helppage": "Help:組權限",
        "listgrouprights-removegroup-self": "響自己嘅戶口度拎走嘅{{PLURAL:$2|一|多}}組: $1",
        "listgrouprights-addgroup-self-all": "加入全部組到自己嘅戶口度",
        "listgrouprights-removegroup-self-all": "響自己嘅戶口度可以拎走全部組",
+       "listgrouprights-namespaceprotection-header": "空間名限制",
+       "listgrouprights-namespaceprotection-namespace": "空間名",
+       "listgrouprights-namespaceprotection-restrictedto": "容許用戶改文嘅權",
+       "trackingcategories": "追蹤類",
+       "trackingcategories-msg": "追蹤類",
+       "trackingcategories-name": "訊息名",
+       "trackingcategories-nodesc": "冇解說資料",
+       "trackingcategories-disabled": "類停用咗",
        "mailnologin": "冇傳送地址",
        "mailnologintext": "你一定要[[Special:UserLogin|登入咗]]同埋喺你嘅[[Special:Preferences|喜好設定]]度有個有效嘅電郵地址先可以傳送電郵畀其他用戶。",
        "emailuser": "發電郵畀呢位用戶",
+       "emailuser-title-target": "電郵畀呢個{{GENDER:$1|用戶}}",
+       "emailuser-title-notarget": "發電郵畀用戶",
        "emailpage": "發電郵畀用戶",
-       "emailpagetext": "你可以用下面嘅表去寄一封電郵畀呢位用戶。\n你喺[[Special:Preferences|你嘅用戶喜好設定]]入面填寫嘅電郵地址會出現喺呢封電郵「由」嘅地址度,以便收件人可以回覆到。",
-       "defemailsubject": "{{SITENAME}} 電郵",
+       "emailpagetext": "你可以用下面嘅表去寄一封電郵畀呢位{{GENDER:$1|用戶}}。\n你喺[[Special:Preferences|你嘅用戶喜好設定]]入面填寫嘅電郵地址會出現喺呢封電郵「由」嘅地址度,方便收件人可以直接回覆你。",
+       "defemailsubject": "由用戶「$1」送嘅 {{SITENAME}} 電郵",
        "usermaildisabled": "用戶電郵已停用",
        "usermaildisabledtext": "你唔可以發送電郵到響呢個wiki度嘅其他用戶",
        "noemailtitle": "無電郵地址",
        "noemailtext": "呢個用戶重未指定一個有效嘅電郵地址。",
        "nowikiemailtext": "呢位用戶揀咗唔收其他用戶畀佢嘅電郵。",
+       "emailnotarget": "收件人填錯名。",
+       "emailtarget": "入收件人嘅用戶名",
+       "emailusername": "用戶名:",
+       "emailusernamesubmit": "遞交",
        "email-legend": "寄電郵畀另一位{{SITENAME}}用戶",
        "emailfrom": "由:",
        "emailto": "到:",
        "mywatchlist": "監視清單",
        "watchlistfor2": "$1嘅監視清單 $2",
        "nowatchlist": "你嘅監視清單度並冇任何項目。",
-       "watchlistanontext": "請先$1去睇或者改響你監視清單度嘅項目。",
+       "watchlistanontext": "請先簽到去睇或者改響你監視清單度嘅項目。",
        "watchnologin": "未登入",
-       "addedwatchtext": "頁面「[[:$1]]」已加入到你嘅[[Special:Watchlist|監視清單]]度。\n呢個頁面以及佢個討論頁以後嘅修改都會列喺嗰度,佢喺[[Special:RecentChanges|最近更改清單]]度會以'''粗體'''顯示,等你可以容易啲睇到佢。",
+       "addwatch": "加到監視清單",
+       "addedwatchtext": "頁面「[[:$1]]」已加入到你嘅[[Special:Watchlist|監視清單]]度。\n呢個頁面以及佢個討論頁以後嘅修改都會列喺嗰度。",
+       "addedwatchtext-short": "「$1」呢一版已經加咗入監視清單。",
+       "removewatch": "響監視清單度拎走",
        "removedwatchtext": "頁面「[[:$1]]」已經喺[[Special:Watchlist|你嘅監視清單]]度刪除。",
+       "removedwatchtext-short": "「$1」呢一版已經由監視清單度拎走咗。",
        "watch": "監視",
        "watchthispage": "監視呢頁",
        "unwatch": "唔使監視",
        "unwatchthispage": "停止監視",
        "notanarticle": "唔係一個內容頁",
        "notvisiblerev": "上次由唔同用戶嘅修訂已經刪除咗",
-       "watchlist-details": "唔計討論頁,有 $1 響你個監視清單度。",
-       "wlheader-enotif": "電子郵件通知已經啟用。",
-       "wlheader-showupdated": "'''粗體字'''嘅頁響你上次嚟之後被人改過",
-       "wlnote": "以ä¸\8bä¿\82最近'''$2'''個鐘之內嘅最新$1次修改。",
-       "wlshowlast": "顯示最近 $1 個鐘 $2 日  嘅修改",
+       "watchlist-details": "唔計討論頁,有 $1 {{PLURAL:$1|版}}響你個監視清單度。",
+       "wlheader-enotif": "電郵通知已經啟用咗。",
+       "wlheader-showupdated": "標'''粗體字'''嘅頁響你上次嚟之後畀人改過。",
+       "wlnote": "ä¸\8bé\9d¢ä¿\82ç\9b´å\88°$3 $4ç\82ºæ­¢ï¼\8c最近'''$2'''個鐘之內嘅最新$1次修改。",
+       "wlshowlast": "顯示最近 $1 個鐘 $2 日",
        "watchlist-options": "監視清單選項",
        "watching": "監視緊...",
        "unwatching": "唔再監視緊...",
+       "watcherrortext": "更改「$1」嘅監視清單嗰陣出錯。",
        "enotif_reset": "將所有頁面標成已視察",
        "enotif_impersonal_salutation": "{{SITENAME}}用戶",
+       "enotif_subject_deleted": "{{SITENAME}}頁面 $1 已經畀 $2 {{GENDER:$2|刪咗}}。",
+       "enotif_subject_created": "{{SITENAME}}頁面 $1 已經畀 $2 {{GENDER:$2|開咗}}。",
+       "enotif_subject_moved": "{{SITENAME}}頁面 $1 已經畀 $2 {{GENDER:$2|搬咗}}。",
+       "enotif_subject_restored": "{{SITENAME}}頁面 $1 已經畀 $2 {{GENDER:$2|恢復咗}}。",
+       "enotif_subject_changed": "{{SITENAME}}頁面 $1 已經畀 $2 {{GENDER:$2|改咗}}。",
+       "enotif_body_intro_deleted": "{{SITENAME}}頁面 $1 已經喺 $PAGEEDITDATE 畀 $2 {{GENDER:$2|刪咗}}。睇下 $3 。",
+       "enotif_body_intro_created": "{{SITENAME}}頁面 $1 已經喺 $PAGEEDITDATE 畀 $2 {{GENDER:$2|開咗}}。睇下而家個版本 $3 。",
+       "enotif_body_intro_moved": "{{SITENAME}}頁面 $1 已經喺 $PAGEEDITDATE 畀 $2 {{GENDER:$2|搬咗}}。睇下而家個版本 $3 。",
+       "enotif_body_intro_restored": "{{SITENAME}}頁面 $1 已經喺 $PAGEEDITDATE 畀 $2 {{GENDER:$2|恢復咗}}。睇下而家個版本 $3 。",
+       "enotif_body_intro_changed": "{{SITENAME}}頁面 $1 已經喺 $PAGEEDITDATE 畀 $2 {{GENDER:$2|改咗}}。睇下而家個版本 $3 。",
        "enotif_lastvisited": "你上次視察以嚟嘅修改請睇$1。",
        "enotif_lastdiff": "睇$1去睇吓呢一次更改。",
        "enotif_anon_editor": "匿名用戶$1",
        "exbeforeblank": "喺清空之前嘅內容係:「$1」",
        "delete-confirm": "刪除\"$1\"",
        "delete-legend": "刪除",
-       "historywarning": "警告:你要刪除嘅頁面有大約$1次嘅修訂:",
+       "historywarning": "<strong>警告:</strong>你要刪除嘅頁面有大約$1次嘅修訂:",
        "confirmdeletetext": "你準備刪除一個頁面或者圖像,包括佢嘅所有歷史版本。\n請確認你打算噉做,而且你知道後果係點,加上確認你噉做冇違反到[[{{MediaWiki:Policy-url}}]]。",
        "actioncomplete": "操作完成",
        "actionfailed": "操作失敗",
        "deletecomment": "原因:",
        "deleteotherreason": "其它/附加嘅原因:",
        "deletereasonotherlist": "其它原因",
-       "deletereason-dropdown": "*常用刪除原因\n** 作者請求\n** 侵犯版權\n** 破壞",
+       "deletereason-dropdown": "*常用刪除原因\n** 垃圾訊息\n** 破壞\n** 侵犯版權\n** 作者請求\n** 壞咗嘅跳轉",
        "delete-edit-reasonlist": "編輯刪除原因",
        "delete-toobig": "呢一版有一個好大量嘅編輯歷史,過咗$1次修訂。刪除呢類版嘅動作已經限制咗,以防止響{{SITENAME}}嘅意外擾亂。",
        "delete-warning-toobig": "呢一版有一個好大量嘅編輯歷史,過咗$1次修訂。刪除佢可能會擾亂{{SITENAME}}嘅資料庫操作;響繼續嗰陣請小心。",
+       "deleteprotected": "你唔可以刪呢版,因為佢畀人保護咗。",
        "rollback": "反轉修改",
        "rollbacklink": "反轉",
        "rollbacklinkcount": "反轉 $1 次修改",
        "alreadyrolled": "無法反轉[[User:$2|$2]]([[User talk:$2|留言]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])對[[:$1]]嘅最後編輯;有人已經修改過或者反轉咗呢個頁面。\n\n上次對呢版嘅編輯係由[[User:$3|$3]]([[User talk:$3|留言]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])做嘅。",
        "editcomment": "編輯摘要係:「'''$1'''」。",
        "revertpage": "已經反轉由[[Special:Contributions/$2|$2]]([[User talk:$2|對話]])所寫嘅編輯到[[User:$1|$1]]嘅最後修訂。",
-       "revertpage-nouser": "已經反轉由(刪咗用戶名)所寫嘅編輯到[[User:$1|$1]]所寫嘅最後修訂。",
+       "revertpage-nouser": "已經反轉咗由收埋咗嘅用戶名所寫嘅編輯,到[[User:$1|$1]]所寫嘅最後修訂版本。",
        "rollback-success": "已經反轉由$1所寫嘅編輯;恢復到$2嘅最後修訂。",
        "sessionfailure-title": "會話失敗",
        "sessionfailure": "你嘅登入會話 (session) 好似有啲問題;\n為咗防止會話劫持,呢個操作已經取消。\n請返去之前嗰版,重新載入嗰版然後再試。",
        "protectlogpage": "保護日誌",
-       "protectlogtext": "下面係一個保護同埋解除保護頁面嘅一覽表。睇吓[[Special:ProtectedPages|保護頁面一覽]]去搵鎖咗嘅頁。",
+       "protectlogtext": "下面係一個保護同埋解除保護頁面改動嘅一覽表。\n睇吓[[Special:ProtectedPages|保護頁面一覽]]去搵而家鎖咗嘅頁。",
        "protectedarticle": "已經保護 \"[[$1]]\"",
        "modifiedarticleprotection": "已經改咗 \"[[$1]]\" 嘅保護等級",
-       "unprotectedarticle": "已經唔再保護 \"[[$1]]\"",
+       "unprotectedarticle": "已經唔再保護「[[$1]]」",
        "movedarticleprotection": "已經改咗由「[[$2]]」到「[[$1]]」嘅保護設定",
        "protect-title": "改緊「$1」嘅保護等級",
+       "protect-title-notallowed": "睇下「$1」嘅保護等級",
        "prot_1movedto2": "[[$1]]搬到去[[$2]]",
+       "protect-badnamespace-title": "保護唔到嘅空間名",
+       "protect-badnamespace-text": "呢個空間名嘅版面保護唔到。",
+       "protect-norestrictiontypes-title": "保護唔到嘅頁",
        "protect-legend": "確認保護",
        "protectcomment": "原因:",
        "protectexpiry": "到期:",
        "protect-locked-blocked": "當你響被封鎖嗰陣唔可以改呢版嘅保護等級。\n呢個係'''$1'''版嘅現時設定:",
        "protect-locked-dblock": "響資料庫主動鎖住咗嗰陣係唔可以改呢版嘅保護等級。\n呢個係'''$1'''版嘅現時設定:",
        "protect-locked-access": "你嘅戶口係無權限去改呢版嘅保護等級。\n呢個係'''$1'''版嘅現時設定:",
-       "protect-cascadeon": "呢一版現時正響度保護緊,因為佢係響以下嘅{{PLURAL:$1|一|幾}}頁度包含咗,而當中又開咗連串保護。你可以更改呢一版嘅保護等級,但係呢個修改係唔會影響到嗰個連串保護。",
+       "protect-cascadeon": "呢一版現時正響度保護緊,因為佢係響以下嘅{{PLURAL:$1|一|幾}}頁度包含咗,而當中又開咗連串保護。更改呢一版嘅保護等級唔會影響到嗰個連串保護。",
        "protect-default": "容許全部用戶",
-       "protect-fallback": "需要\"$1\"嘅許可",
+       "protect-fallback": "只容許有「$1」許可嘅用戶",
        "protect-level-autoconfirmed": "只限已經自動確認嘅用戶",
        "protect-level-sysop": "只限管理員",
        "protect-summary-cascade": "連串保護",
        "protect-expiring": "響 $1 (UTC) 到期",
+       "protect-expiring-local": "$1 到期",
        "protect-expiry-indefinite": "唔定",
        "protect-cascade": "保護包含響呢一版嘅頁面 (連串保護)",
        "protect-cantedit": "你唔可以改呢版嘅保護等級,因為你無權限去編輯佢。",
        "protect-othertime": "其它時間:",
        "protect-othertime-op": "其它時間",
        "protect-existing-expiry": "現時到期嘅時間: $2 $3",
+       "protect-existing-expiry-infinity": "到期時間:無限期",
        "protect-otherreason": "其它/附加嘅原因:",
        "protect-otherreason-op": "其它原因",
        "protect-dropdown": "*通用保護原因\n** 過量嘅破壞\n** 過量嘅灌水\n** 反生產性編輯戰\n** 高流量頁",
        "viewdeletedpage": "去睇被刪除咗嘅頁面",
        "undeletepagetext": "以下嘅$1個頁面已經刪除,但係重喺檔庫度可以恢復。檔案庫可能會定時清理。",
        "undelete-fieldset-title": "恢復修訂",
-       "undeleteextrahelp": "要恢復成個頁面,唔好剔任何嘅核選盒,再撳'''''{{int:undeletebtn}}'''''。\n要恢復已經選擇咗嘅修訂,將要恢復代表有關修訂嘅核選盒剔上,再撳'''''{{int:undeletebtn}}'''''。\n撳'''''{{int:undeletereset}}'''''會清除註解文字同埋全部嘅核選盒。",
+       "undeleteextrahelp": "要恢復成個頁面,唔好剔任何嘅核選盒,再撳<strong><em>{{int:undeletebtn}}</em></strong>。\n要恢復已經選擇咗嘅修訂,將要恢復代表有關修訂嘅核選盒剔上,再撳<strong><em>{{int:undeletebtn}}</em></strong>。",
        "undeleterevisions": "$1個修訂都已經存檔",
        "undeletehistory": "如果你恢復呢個頁面,佢嘅所有修改歷史都會恢復返到嗰篇頁面嘅歷史度。如果喺佢刪除之後又新開咗同名嘅頁面,你恢復嘅修改歷史會顯示喺先前歷史度。",
        "undeleterevdel": "如果響最新修訂度部份刪除,噉就反刪除唔到。如果遇到呢種情況,你一定要反選或者反隱藏最新刪除咗嘅修訂。",
        "undeletedrevisions": "$1個修訂已經救返",
        "undeletedrevisions-files": "$1個修訂同$2個檔案已經救返",
        "undeletedfiles": "$1個檔案已經救返",
-       "cannotundelete": "æ\95\91å\94\94å\88°ï¼\9bå\8f¯è\83½æ\9c\89å\85¶ä»\96人已ç¶\93æ\95\91è¿\94å\97°é \81ã\80\82",
+       "cannotundelete": "æ\95\91å\94\94å\88°ï¼\9a\n$1",
        "undeletedpage": "'''$1已經成功救返'''\n\n最近嘅刪除同恢復記錄請睇[[Special:Log/delete]]。",
        "undelete-header": "睇吓[[Special:Log/delete|刪除日誌]]去睇之前刪除嘅頁頁。",
+       "undelete-search-title": "搵刪咗嘅版",
        "undelete-search-box": "搵刪除咗嘅頁面",
        "undelete-search-prefix": "顯示由以下開頭嘅頁面:",
        "undelete-search-submit": "搵嘢",
        "undelete-bad-store-key": "唔能夠刪除帶有時間截記嘅檔案修訂 $1: 檔案響刪除之前唔見咗。",
        "undelete-cleanup-error": "刪除無用嘅歸檔檔案 \"$1\" 時出錯。",
        "undelete-missing-filearchive": "由於檔案歸檔 ID $1 唔響個數據庫度,唔能夠響個檔案歸檔恢復。佢可能已經反刪除咗。",
+       "undelete-error": "還原刪版出錯",
        "undelete-error-short": "反刪除檔案嗰陣出錯: $1",
        "undelete-error-long": "當反刪除緊個檔案嗰陣遇到錯誤:\n\n$1",
        "undelete-show-file-confirm": "你係咪肯定你想去睇響 $2 $3 嘅 \"<nowiki>$1</nowiki>\" 檔案?",
        "contributions": "{{GENDER:$1|用戶}}貢獻",
        "contributions-title": "$1嘅用戶貢獻",
        "mycontris": "個人貢獻",
-       "contribsub2": "$1嘅貢獻 ($2)",
+       "contribsub2": "{{GENDER:$3|$1}}嘅貢獻 ($2)",
+       "contributions-userdoesnotexist": "用戶「$1」未有註冊。",
        "nocontribs": "搵唔到符合呢啲條件嘅修改。",
-       "uctop": "(最頂)",
+       "uctop": "(而家)",
        "month": "由呢個月 (同更早):",
        "year": "由呢一年 (同更早):",
        "sp-contributions-newbies": "只顯示新戶口嘅貢獻",
        "sp-contributions-newbies-sub": "新戶口嘅貢獻",
        "sp-contributions-newbies-title": "新戶口嘅用戶貢獻",
        "sp-contributions-blocklog": "封鎖日誌",
+       "sp-contributions-suppresslog": "壓制咗嘅用戶貢獻",
        "sp-contributions-deleted": "已經刪除咗嘅用戶貢獻",
        "sp-contributions-uploads": "上載",
        "sp-contributions-logs": "日誌",
        "sp-contributions-search": "搵貢獻",
        "sp-contributions-username": "IP地址或用戶名:",
        "sp-contributions-toponly": "只顯示最新修訂嘅編輯",
+       "sp-contributions-newonly": "只顯示開新版嘅編輯",
        "sp-contributions-submit": "搵",
        "whatlinkshere": "有乜嘢連結來呢度",
        "whatlinkshere-title": "連到「$1」嘅頁",
        "whatlinkshere-hidelinks": "$1連結",
        "whatlinkshere-hideimages": "$1檔案連結",
        "whatlinkshere-filters": "過濾器",
-       "blockip": "封鎖用戶",
+       "autoblockid": "自動封鎖 #$1",
+       "block": "封鎖用戶",
+       "unblock": "解封用戶",
+       "blockip": "封鎖{{GENDER:$1|用戶}}",
        "blockip-legend": "封鎖用戶",
        "blockiptext": "使用以下嘅表格嚟去阻止指定嘅IP地址或用戶名嘅寫權限。\n僅當僅當為咗避免有版畀人惡意破壞嘅時候先可以使用,而且唔可以違反[[{{MediaWiki:Policy-url}}|政策]]。\n喺下面填寫阻止嘅確切原因(比如:引用咗某啲已經破壞咗嘅頁面)。",
        "ipaddressorusername": "IP地址或用戶名:",
        "ipbexpiry": "期限:",
        "ipbreason": "原因:",
        "ipbreason-dropdown": "*共用封鎖原因\n** 插入錯嘅資料\n** 響頁面度拎走\n** 亂加入外部連結\n** 響頁度加入冇意義嘅嘢\n** 嚇人/騷擾\n** 濫用多個戶口\n** 唔能夠接受嘅用戶名",
+       "ipb-hardblock": "唔畀簽到用戶用呢個IP位址去改文",
        "ipbcreateaccount": "防止開新戶口",
        "ipbemailban": "防止用戶傳送電郵",
        "ipbenableautoblock": "自動封鎖呢個用戶上次用過嘅IP地址,同埋佢地做過編輯嘅IP地址",
        "ipboptions": "兩個鐘頭:2 hours,一日:1 day,三日:3 days,一個禮拜:1 week,兩個禮拜:2 weeks,一個月:1 month,三個月:3 months,六個月:6 months,一年:1 year,終身:infinite",
        "ipbhidename": "響編輯同名單度隱藏用戶名",
        "ipbwatchuser": "監視呢位用戶嘅用戶頁同埋佢嘅討論頁",
+       "ipb-disableusertalk": "唔畀封鎖緊嘅用戶去改自己個用戶討論頁",
        "ipb-change-block": "用呢啲設定重新封鎖用戶",
+       "ipb-confirm": "確認封鎖",
        "badipaddress": "無效嘅IP地址",
        "blockipsuccesssub": "封鎖成功",
-       "blockipsuccesstext": "[[Special:Contributions/$1|$1]]已經封鎖。<br />\n去[[Special:BlockList|IP封鎖清單]]睇返封鎖名單。",
+       "blockipsuccesstext": "[[Special:Contributions/$1|$1]]已經封鎖。<br />\n去[[Special:BlockList|封鎖清單]]睇返封鎖。",
+       "ipb-blockingself": "你將會封鎖自己!你肯定要咁做?",
+       "ipb-confirmaction": "如果你肯定要咁做,請剔下低嘅「{{int:ipb-confirm}}」格。",
        "ipb-edit-dropdown": "改封鎖原因",
        "ipb-unblock-addr": "解封$1",
        "ipb-unblock": "解封一個用戶名或IP地址",
        "ipb-blocklist": "去睇現時嘅封鎖",
-       "ipb-blocklist-contribs": "$1嘅貢獻",
+       "ipb-blocklist-contribs": "{{GENDER:$1|$1}}嘅貢獻",
        "unblockip": "解封用戶",
        "unblockiptext": "使用以下表格恢復之前阻止嘅某個IP地址或者某個用戶名嘅寫權限。",
        "ipusubmit": "拎走呢個封鎖",
        "unblocked": "\"[[User:$1|$1]]\"已經解封",
+       "unblocked-range": "$1 已經解鎖咗。",
        "unblocked-id": "$1嘅封鎖已經拎走咗",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] 已經解鎖咗。",
+       "blocklist": "封鎖用戶",
        "ipblocklist": "封咗嘅用戶",
        "ipblocklist-legend": "搵一位封咗嘅用戶",
+       "blocklist-userblocks": "收埋戶口封鎖",
+       "blocklist-tempblocks": "收埋臨時封鎖",
+       "blocklist-addressblocks": "收埋單一IP封鎖",
+       "blocklist-rangeblocks": "收埋大範圍IP封鎖",
+       "blocklist-timestamp": "時間",
+       "blocklist-target": "目標",
+       "blocklist-expiry": "到期",
+       "blocklist-by": "封鎖管理員",
+       "blocklist-params": "封鎖參數",
+       "blocklist-reason": "原因",
        "ipblocklist-submit": "搵",
        "ipblocklist-localblock": "本地封鎖",
        "ipblocklist-otherblocks": "其他{{PLURAL:$1|封鎖|封鎖}}",
        "unblocklink": "解封",
        "change-blocklink": "改封",
        "contribslink": "貢獻",
-       "autoblocker": "已經自動封鎖,因為你嘅IP地址冇幾耐之前\"[[User:$1|$1]]\"使用過。$1\\嘅封鎖原因係: 「$2」",
+       "emaillink": "送電郵",
+       "autoblocker": "已經自動封鎖咗,因為你嘅IP地址冇幾耐之前畀「[[User:$1|$1]]」用過。\n$1嘅封鎖原因係「$2」",
        "blocklogpage": "封鎖日誌",
        "blocklog-showlog": "呢位用戶已經響之前被封鎖過。響下面提供咗封鎖紀錄以便參考:",
        "blocklog-showsuppresslog": "呢位用戶已經響之前被封鎖同隱藏過。響下面提供咗廢止紀錄以便參考:",
        "blocklogentry": "已封鎖[[$1]],到期時間為$2 $3",
        "reblock-logentry": "已改[[$1]]嘅封鎖設定,到期時間為$2 $3",
-       "blocklogtext": "呢個係封鎖同埋解封動作嘅日誌。自動封鎖IP地址嘅動作冇列出嚟。去[[Special:BlockList|IP封鎖名單]]睇現時生效嘅封鎖名單",
+       "blocklogtext": "呢個係封鎖同埋解封動作嘅日誌。\n自動封鎖IP地址嘅動作冇列出嚟。\n去[[Special:BlockList|封鎖名單]]睇現時生效嘅封鎖名單",
        "unblocklogentry": "已經解封$1",
        "block-log-flags-anononly": "只限匿名用戶",
        "block-log-flags-nocreate": "停用開新戶口",
        "range_block_disabled": "操作員嘅建立範圍封鎖已經停用。",
        "ipb_expiry_invalid": "無效嘅期限。",
        "ipb_expiry_temp": "隱藏用戶名封鎖定一定係要永久性嘅。",
-       "ipb_hide_invalid": "唔能夠壓止呢個戶口;佢可能有太多編輯。",
+       "ipb_hide_invalid": "唔能夠壓止呢個戶口;佢有多過{{PLURAL:$1|一次編輯|$1次編輯}}。",
        "ipb_already_blocked": "\"$1\"已經封鎖咗",
        "ipb-needreblock": "$1已經被封鎖。你係咪想更改呢個設定?",
        "ipb-otherblocks-header": "其他{{PLURAL:$1|封鎖|封鎖}}",
+       "unblock-hideuser": "你唔可以解鎖呢個用戶,因為佢個用戶名收埋咗。",
        "ipb_cant_unblock": "錯誤:搵唔到封鎖ID$1。可能已經解封咗。",
        "ipb_blocked_as_range": "錯誤:個IP $1 無直接封鎖,唔可以解封。但係佢係響 $2 嘅封鎖範圍之內,嗰段範圍係可以解封嘅。",
        "ip_range_invalid": "無效嘅IP範圍",
        "delete_and_move": "刪除並移動",
        "delete_and_move_text": "==需要刪除==\n\n目標頁「[[:$1]]」已經存在。你要唔要刪咗佢空個位出嚟畀個搬文動作?",
        "delete_and_move_confirm": "好,刪咗嗰個頁面",
-       "delete_and_move_reason": "已經刪咗嚟畀位畀個搬文動作",
+       "delete_and_move_reason": "已經刪咗「[[$1]]」嚟畀位畀個搬文動作",
        "selfmove": "原始標題同目的標題一樣;唔可以將個頁面搬返去自己度。",
        "immobile-source-namespace": "唔可以響空間名「$1」度搬版",
        "immobile-target-namespace": "唔可以將版搬到「$1」度",
        "thumbnail_gd-library": "未完成嘅GD設定: 功能唔見咗 $1",
        "thumbnail_image-missing": "檔案似乎唔見咗: $1",
        "import": "倒入頁面",
-       "importinterwiki": "Transwiki 倒入",
+       "importinterwiki": "由其它wiki度倒入",
        "import-interwiki-text": "揀一個 wiki 同埋一頁去倒入。\n修訂日期同編輯者會被保存落嚟。\n所有 transwiki 嘅倒入動作會響[[Special:Log/import|倒入日誌]]度記錄落嚟。",
        "import-interwiki-history": "複製呢一頁所有嘅歷史修訂",
        "import-interwiki-templates": "包含全部嘅模",
        "import-interwiki-namespace": "目的空間名:",
        "import-upload-filename": "檔名:",
        "import-comment": "註解:",
-       "importtext": "請由原 wiki 嘅[[Special:Export|匯出工具]]匯出成檔案。\n儲存喺你個磁碟度,然後再上載到呢度。",
+       "importtext": "請由原 wiki 嘅[[Special:Export|匯出工具]]匯出成檔案。\n儲存喺你部電腦度,然後再上載到呢度。",
        "importstart": "倒入緊...",
        "import-revision-count": "$1次修訂",
        "importnopages": "冇頁面去倒入。",
        "importcantopen": "唔能夠開個倒入檔案",
        "importbadinterwiki": "壞嘅跨 wiki 連結",
        "importsuccess": "已經完成倒入!",
-       "importnosources": "未定義 transwiki 嘅匯入來源,同埋歷史嘅直接上載已經停用。",
+       "importnosources": "未定義匯入來源,同埋歷史嘅直接上載已經停用。",
        "importnofile": "冇上載到任何要倒入嘅檔案。",
        "importuploaderrorsize": "上載要倒入嘅檔案失敗。個檔案大過可以容許嘅上載大細。",
        "importuploaderrorpartial": "上載要倒入嘅檔案失敗。個檔案只係部份上載咗。",
        "importuploaderrortemp": "上載要倒入嘅檔案失敗。個臨時資料夾唔見咗。",
        "import-parse-failure": "XML倒入語法失敗",
        "import-noarticle": "無版去倒入!",
-       "import-nonewrevisions": "全部嘅修訂已經響之前倒入咗。",
+       "import-nonewrevisions": "無修訂倒入(全部嘅修訂已經響之前倒入咗,或者因為出錯而跳咗唔做)。",
        "xml-error-string": "$1 響行$2,欄$3 ($4 bytes): $5",
        "import-upload": "上載XML資料",
        "import-token-mismatch": "小節資料遺失。請再試過。",
        "import-invalid-interwiki": "唔能夠響指定嘅wiki倒入。",
        "importlogpage": "倒入日誌",
        "importlogpagetext": "管理員由其它嘅 wiki 倒入頁面同埋佢哋嘅編輯歷史記錄。",
-       "import-logentry-upload-detail": "$1個修訂",
-       "import-logentry-interwiki-detail": "由$2嘅$1個修訂",
+       "import-logentry-upload-detail": "$1個修訂都已經倒入咗",
+       "import-logentry-interwiki-detail": "ç\94±$2å\80\92å\85¥å\98\85$1å\80\8bä¿®è¨\82",
        "tooltip-pt-userpage": "你嘅用戶頁",
        "tooltip-pt-anonuserpage": "你編輯呢個IP嘅對應用戶頁",
        "tooltip-pt-mytalk": "你嘅對話頁",
        "tooltip-ca-viewsource": "呢一頁已經被保護。你可以睇吓呢一頁呢原始碼。",
        "tooltip-ca-history": "呢一頁之前嘅修訂",
        "tooltip-ca-protect": "保護呢一頁",
-       "tooltip-ca-unprotect": "唔再保護呢一頁",
+       "tooltip-ca-unprotect": "改呢版保護",
        "tooltip-ca-delete": "刪除呢一頁",
        "tooltip-ca-undelete": "將呢個頁面還原到被刪除之前嘅狀態",
        "tooltip-ca-move": "移動呢一頁",
        "exif-colorspace": "色彩空間",
        "exif-componentsconfiguration": "每個部份嘅意思",
        "exif-compressedbitsperpixel": "影像壓縮模式",
-       "exif-pixelydimension": "影像有效闊度",
-       "exif-pixelxdimension": "影像有效高度",
+       "exif-pixelydimension": "影像闊度",
+       "exif-pixelxdimension": "影像高度",
        "exif-usercomment": "用家註腳",
        "exif-relatedsoundfile": "相關聲音檔",
        "exif-datetimeoriginal": "原創日期時間",
        "exif-exposureprogram": "曝光程序",
        "exif-spectralsensitivity": "光譜敏感度",
        "exif-isospeedratings": "ISO 速率",
-       "exif-shutterspeedvalue": "快門速度",
-       "exif-aperturevalue": "光圈",
-       "exif-brightnessvalue": "光度",
+       "exif-shutterspeedvalue": "APEX快門速度",
+       "exif-aperturevalue": "APEX光圈",
+       "exif-brightnessvalue": "APEX光度",
        "exif-exposurebiasvalue": "曝光偏壓",
        "exif-maxaperturevalue": "最大陸地孔徑",
        "exif-subjectdistance": "主體距離",
        "exif-orientation-3": "轉一百八十度",
        "exif-orientation-4": "上下倒轉",
        "exif-orientation-5": "逆時針轉九十度,再上下倒轉",
-       "exif-orientation-6": "é \86æ\99\82é\87\9dè½\89ä¹\9då\8d\81度",
+       "exif-orientation-6": "é\80\86æ\99\82é\87\9dè½\89ä¹\9då\8d\81度",
        "exif-orientation-7": "順時針轉九十度,再上下倒轉",
-       "exif-orientation-8": "é\80\86æ\99\82é\87\9dè½\89ä¹\9då\8d\81度",
+       "exif-orientation-8": "é \86æ\99\82é\87\9dè½\89ä¹\9då\8d\81度",
        "exif-planarconfiguration-1": "chunky 格式",
        "exif-planarconfiguration-2": "planar 格式",
        "exif-componentsconfiguration-0": "根本無",
        "duplicate-defaultsort": "警告: 預設嘅排序鍵 \"$2\" 覆蓋之前嘅預設排序鍵 \"$1\"。",
        "version": "版本",
        "version-extensions": "裝咗嘅擴展",
-       "version-skins": "畫面",
+       "version-skins": "裝咗嘅畫面",
        "version-specialpages": "特別頁",
        "version-parserhooks": "語法鈎",
        "version-variables": "變數",
        "version-hook-name": "鈎名",
        "version-hook-subscribedby": "利用於",
        "version-version": "($1)",
-       "version-license": "牌照",
+       "version-license": "MediaWiki牌照",
        "version-poweredby-credits": "呢個 Wiki 係由 '''[https://www.mediawiki.org/ MediaWiki]''' 驅動,版權所有 © 2001-$1 $2。",
        "version-poweredby-others": "其他",
        "version-license-info": "MediaWiki係自由軟件;你可以根據Free Software Foundation所發表嘅GNU General Public License條款規定,就本程式再發佈同/或修改;無論你根據嘅係呢個牌照嘅第二版或(任你揀)任一日之後發行嘅版本。\n\nMediaWiki是基於使用目的而加以發佈,但係就唔會負上任何嘅責任;亦都唔會對適售性或都係特定目的適用性嘅默示性擔保。詳情請目睇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 上網睇]。",
        "fileduplicatesearch-result-n": "個檔案 \"$1\" 有$2項完全相同嘅重覆。",
        "fileduplicatesearch-noresults": "檔案名\"$1\"找不到",
        "specialpages": "特別頁",
-       "specialpages-note": "* 標準特別頁。\n* <strong class=\"mw-specialpagerestricted\">有限制嘅特別頁。</strong>",
+       "specialpages-note": "* 標準特別頁。\n* <span class=\"mw-specialpagerestricted\">有限制嘅特別頁。</span>",
        "specialpages-group-maintenance": "維護報告",
        "specialpages-group-other": "其它特別頁",
-       "specialpages-group-login": "ç\99»å\85¥ï¼\8fé\96\8b戶口",
+       "specialpages-group-login": "ç°½å\88°ï¼\8fé\96\8bæ\96°戶口",
        "specialpages-group-changes": "最近更改同日誌",
        "specialpages-group-media": "媒體報告同上載",
        "specialpages-group-users": "用戶同權限",
        "specialpages-group-highuse": "高度使用頁",
        "specialpages-group-pages": "頁面一覽",
        "specialpages-group-pagetools": "版工具",
-       "specialpages-group-wiki": "Wiki資料同工具",
+       "specialpages-group-wiki": "資料同工具",
        "specialpages-group-redirects": "跳轉特別頁",
        "specialpages-group-spam": "反垃圾工具",
        "specialpages-group-developer": "開發者工具",
        "compare-submit": "比較",
        "dberr-problems": "對唔住!呢一版出現咗一啲技術性問題。",
        "dberr-again": "試吓等多幾分種然後開試。",
-       "dberr-info": "(唔能夠連繫個資料伺服器: $1)",
+       "dberr-info": "(唔能夠連繫個資料庫:$1)",
        "dberr-usegoogle": "響現階段你可以用 Google 去搵嘢。",
        "dberr-outofdate": "留意佢哋索引嘅內容可能會過時。",
        "dberr-cachederror": "呢個係所要求版嘅快取複本,可能會過時。",
        "searchsuggest-containing": "名單傳送緊...",
        "duration-hours": "$1{{PLURAL:$1|個鐘}}",
        "expandtemplates": "展開模",
-       "expand_templates_intro": "呢個特別頁係用於將一啲文字中嘅模展開,包括響個模度引用嘅模。同時亦都展開解譯器函數好似<nowiki>{{</nowiki>#language:...}},以及一啲變數好似<nowiki>{{</nowiki>CURRENTDAY}}&mdash;實際上,幾乎所有響雙括弧中嘅內容都會被展開。呢個特別頁係通過使用MediaWiki嘅相關解釋階段嘅功能完成嘅。",
+       "expand_templates_intro": "呢個特別頁係用於將一啲文字中嘅模展開,包括響個模度引用嘅模。\n同時亦都展開解譯器函數好似\n<code><nowiki>{{</nowiki>#language:...}}</code>,同埋一啲變數好似\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>。\n實際上,幾乎所有響雙括弧中嘅內容都會被展開。",
        "expand_templates_title": "內容標題,用於 {{FULLPAGENAME}} 等頁面:",
        "expand_templates_input": "輸入文字:",
        "expand_templates_output": "結果:",
index 83bc074..98c2ba3 100644 (file)
@@ -1,11 +1,13 @@
 <?php
-/** Western Balochi
+/** Western Balochi (بلوچی رخشانی)
  *
  * To improve a translation please visit https://translatewiki.net
  *
  * @ingroup Language
  * @file
  *
+ * @author Ibrahim khashrowdi
+ * @author Mjbmr
  */
 
 $fallback = 'fa';
index 4d964fb..dd1cc55 100644 (file)
@@ -50,10 +50,10 @@ $specialPageAliases = array(
        'Booksources'               => array( 'منابع_کتاب' ),
        'BrokenRedirects'           => array( 'تغییرمسیرهای_خراب' ),
        'Categories'                => array( 'رده‌ها' ),
-       'ChangeEmail'               => array( 'تغییر_رایانامه' ),
+       'ChangeEmail'               => array( 'تغÛ\8cÛ\8cر_اÛ\8cÙ\85Û\8cÙ\84', 'تغÛ\8cÛ\8cر_راÛ\8cاÙ\86اÙ\85Ù\87' ),
        'ChangePassword'            => array( 'از_نو_کردن_گذرواژه' ),
        'ComparePages'              => array( 'مقایسهٔ_صفحات' ),
-       'Confirmemail'              => array( 'تأیید_رایانامه' ),
+       'Confirmemail'              => array( 'تأÛ\8cÛ\8cد_اÛ\8cÙ\85Û\8cÙ\84', 'تأÛ\8cÛ\8cد_راÛ\8cاÙ\86اÙ\85Ù\87' ),
        'Contributions'             => array( 'مشارکت‌ها' ),
        'CreateAccount'             => array( 'ایجاد_حساب_کاربری' ),
        'Deadendpages'              => array( 'صفحه‌های_بن‌بست' ),
@@ -61,14 +61,14 @@ $specialPageAliases = array(
        'Diff'                      => array( 'تفاوت' ),
        'DoubleRedirects'           => array( 'تغییرمسیرهای_دوتایی' ),
        'EditWatchlist'             => array( 'ویرایش_فهرست_پی‌گیری‌ها' ),
-       'Emailuser'                 => array( 'نامه_به_کاربر' ),
+       'Emailuser'                 => array( 'ایمیل_به_کاربر', 'نامه_به_کاربر' ),
        'ExpandTemplates'           => array( 'گسترش_الگوها' ),
        'Export'                    => array( 'برون‌بری_صفحه' ),
        'Fewestrevisions'           => array( 'کمترین_نسخه' ),
        'FileDuplicateSearch'       => array( 'جستجوی_پروندهٔ_تکراری' ),
        'Filepath'                  => array( 'مسیر_پرونده' ),
        'Import'                    => array( 'درون‌ریزی_صفحه' ),
-       'Invalidateemail'           => array( 'باطل‌کردن_رایانامه' ),
+       'Invalidateemail'           => array( 'باطÙ\84â\80\8cکردÙ\86§Û\8cÙ\85Û\8cÙ\84', 'باطÙ\84â\80\8cکردÙ\86±Ø§Û\8cاÙ\86اÙ\85Ù\87' ),
        'JavaScriptTest'            => array( 'تست_جاوااسکریپت' ),
        'BlockList'                 => array( 'فهرست_بسته‌شده‌ها', 'فهرست_بستن_نشانی_آی‌پی' ),
        'LinkSearch'                => array( 'جستجوی_پیوند' ),
index 3d579c5..ada5dc2 100644 (file)
@@ -48,7 +48,7 @@ $specialPageAliases = array(
        'ChangePassword'            => array( 'آلشت_دئن_رازینه_گواردن' ),
        'ComparePages'              => array( 'تی_یک_نیائن_بلگه_یا' ),
        'Confirmemail'              => array( 'پشت_راس_کاری_ایمیل' ),
-       'Contributions'             => array( 'هومیاریا' ),
+       'Contributions'             => array( 'هومیاری_کردنیا' ),
        'CreateAccount'             => array( 'راس_کردن_حساو' ),
        'Deadendpages'              => array( 'بلگه_یا_بی_ویرگار' ),
        'DeletedContributions'      => array( 'هومیاریا_پاکسا_بیه' ),
index 732bdc0..eab2b63 100644 (file)
@@ -23,6 +23,7 @@
                                "classes": [
                                        "mw.Title",
                                        "mw.Uri",
+                                       "mw.messagePoster.*",
                                        "mw.notification",
                                        "mw.Notification_",
                                        "mw.user",
index f9d2eac..e56d557 100644 (file)
@@ -823,6 +823,7 @@ return array(
                        'mediawiki.Title',
                        'user.tokens',
                ),
+               'targets' => array( 'desktop', 'mobile' ),
        ),
        'mediawiki.api.login' => array(
                'scripts' => 'resources/src/mediawiki.api/mediawiki.api.login.js',
@@ -877,7 +878,7 @@ return array(
                'scripts' => 'resources/src/mediawiki/mediawiki.feedback.js',
                'styles' => 'resources/src/mediawiki/mediawiki.feedback.css',
                'dependencies' => array(
-                       'mediawiki.api.edit',
+                       'mediawiki.messagePoster',
                        'mediawiki.Title',
                        'oojs-ui',
                ),
@@ -896,6 +897,7 @@ return array(
                        'feedback-error1',
                        'feedback-error2',
                        'feedback-error3',
+                       'feedback-error4',
                        'feedback-message',
                        'feedback-subject',
                        'feedback-submit',
@@ -955,6 +957,27 @@ return array(
                ),
                'targets' => array( 'desktop', 'mobile' ),
        ),
+       'mediawiki.messagePoster' => array(
+               'scripts' => array(
+                       'resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js',
+                       'resources/src/mediawiki.messagePoster/mediawiki.messagePoster.MessagePoster.js',
+               ),
+               'dependencies' => array(
+                       'oojs',
+                       'mediawiki.api',
+               ),
+               'targets' => array( 'desktop', 'mobile' ),
+       ),
+       'mediawiki.messagePoster.wikitext' => array(
+               'scripts' => array(
+                       'resources/src/mediawiki.messagePoster/mediawiki.messagePoster.WikitextMessagePoster.js',
+               ),
+               'dependencies' => array(
+                       'mediawiki.api.edit',
+                       'mediawiki.messagePoster',
+               ),
+               'targets' => array( 'desktop', 'mobile' ),
+       ),
        'mediawiki.notification' => array(
                'styles' => array(
                        'resources/src/mediawiki/mediawiki.notification.css',
diff --git a/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.MessagePoster.js b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.MessagePoster.js
new file mode 100644 (file)
index 0000000..91366ff
--- /dev/null
@@ -0,0 +1,38 @@
+/*global OO*/
+( function ( mw ) {
+       /**
+        * This is the abstract base class for MessagePoster implementations.
+        *
+        * @abstract
+        * @class
+        *
+        * @constructor
+        * @param {mw.Title} title Title to post to
+        */
+       mw.messagePoster.MessagePoster = function MwMessagePoster() {};
+
+       OO.initClass( mw.messagePoster.MessagePoster );
+
+       /**
+        * Post a message (with subject and body) to a talk page.
+        *
+        * @param {string} subject Subject/topic title; plaintext only (no wikitext or HTML)
+        * @param {string} body Body, as wikitext.  Signature code will automatically be added
+        *   by MessagePosters that require one, unless the message already contains the string
+        *   ~~~.
+        * @return {jQuery.Promise} Promise completing when the post succeeds or fails.
+        *   For failure, will be rejected with three arguments:
+        *
+        *   - primaryError - Primary error code.  For a mw.Api failure,
+        *       this should be 'api-fail'.
+        *   - secondaryError - Secondary error code.  For a mw.Api failure,
+        *       this, should be mw.Api's code, e.g. 'http', 'ok-but-empty', or the error passed through
+        *       from the server.
+        *   - details - Further details about the error
+        *
+        * @localdoc
+        * The base class currently does nothing, but could be used for shared analytics or
+        * something.
+        */
+       mw.messagePoster.MessagePoster.prototype.post = function () {};
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.WikitextMessagePoster.js b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.WikitextMessagePoster.js
new file mode 100644 (file)
index 0000000..296576b
--- /dev/null
@@ -0,0 +1,53 @@
+/*global OO*/
+( function ( mw, $ ) {
+       /**
+        * This is an implementation of MessagePoster for wikitext talk pages.
+        *
+        * @class mw.messagePoster.WikitextMessagePoster
+        * @extends mw.messagePoster.MessagePoster
+        *
+        * @constructor
+        * @param {mw.Title} title Wikitext page in a talk namespace, to post to
+        */
+       function WikitextMessagePoster( title ) {
+               this.api = new mw.Api();
+               this.title = title;
+       }
+
+       OO.inheritClass(
+               WikitextMessagePoster,
+               mw.messagePoster.MessagePoster
+       );
+
+       /**
+        * @inheritdoc
+        */
+       WikitextMessagePoster.prototype.post = function ( subject, body ) {
+               mw.messagePoster.WikitextMessagePoster.parent.prototype.post.call( this, subject, body );
+
+               // Add signature if needed
+               if ( body.indexOf( '~~~' ) === -1 ) {
+                       body += '\n\n~~~~';
+               }
+
+               return this.api.newSection(
+                       this.title,
+                       subject,
+                       body,
+                       { redirect: true }
+               ).then( function ( resp, jqXHR ) {
+                       if ( resp.edit.result === 'Success' ) {
+                               return $.Deferred().resolve( resp, jqXHR );
+                       } else {
+                               // mediawiki.api.js checks for resp.error.  Are there actually cases where the
+                               // request fails, but it's not caught there?
+                               return $.Deferred().reject( 'api-unexpected' );
+                       }
+               }, function ( code, details ) {
+                       return $.Deferred().reject( 'api-fail', code, details );
+               } ).promise();
+       };
+
+       mw.messagePoster.factory.register( 'wikitext', WikitextMessagePoster );
+       mw.messagePoster.WikitextMessagePoster = WikitextMessagePoster;
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js
new file mode 100644 (file)
index 0000000..9d28080
--- /dev/null
@@ -0,0 +1,109 @@
+/*global OO*/
+( function ( mw, $ ) {
+       /**
+        * This is a factory for MessagePoster objects, which allows a pluggable to way to script leaving a
+        * talk page message.
+        *
+        * @class mw.messagePoster.factory
+        * @singleton
+        */
+       function MwMessagePosterFactory() {
+               this.api = new mw.Api();
+               this.contentModelToClass = {};
+       }
+
+       OO.initClass( MwMessagePosterFactory );
+
+       // Note: This registration scheme is currently not compatible with LQT, since that doesn't
+       // have its own content model, just islqttalkpage.  LQT pages will be passed to the wikitext
+       // MessagePoster.
+       /**
+        * Registers a MessagePoster subclass for a given content model.
+        *
+        * @param {string} contentModel Content model of pages this MessagePoster can post to
+        * @param {Function} messagePosterConstructor Constructor for MessagePoster
+        */
+       MwMessagePosterFactory.prototype.register = function ( contentModel, messagePosterConstructor ) {
+               if ( this.contentModelToClass[contentModel] !== undefined ) {
+                       throw new Error( 'The content model \'' + contentModel + '\' is already registered.' );
+               }
+
+               this.contentModelToClass[contentModel] = messagePosterConstructor;
+       };
+
+       /**
+        * Unregisters a given content model
+        * This is exposed for testing and should not normally be needed.
+        *
+        * @param {string} contentModel Content model to unregister
+        */
+       MwMessagePosterFactory.prototype.unregister = function ( contentModel ) {
+               delete this.contentModelToClass[contentModel];
+       };
+
+       /**
+        * Creates a MessagePoster, given a title.  A promise for this is returned.
+        * This works by determining the content model, then loading the corresponding
+        * module (which will register the MessagePoster class), and finally constructing it.
+        *
+        * This does not require the message and should be called as soon as possible, so it does the
+        * API and ResourceLoader requests in the background.
+        *
+        * @param {mw.Title} title Title that will be posted to
+        * @return {jQuery.Promise} Promise resolving to a mw.messagePoster.MessagePoster.
+        *   For failure, rejected with up to three arguments:
+        *
+        *   - errorCode Error code string
+        *   - error Error explanation
+        *   - details Further error details
+        */
+       MwMessagePosterFactory.prototype.create = function ( title ) {
+               var pageId, page, contentModel, moduleName,
+                       factory = this;
+
+               return this.api.get( {
+                       action: 'query',
+                       prop: 'info',
+                       indexpageids: 1,
+                       titles: title.getPrefixedDb()
+               } ).then( function ( result ) {
+                       if ( result.query.pageids.length > 0 ) {
+                               pageId = result.query.pageids[0];
+                               page = result.query.pages[pageId];
+
+                               contentModel = page.contentmodel;
+                               moduleName = 'mediawiki.messagePoster.' + contentModel;
+                               return mw.loader.using( moduleName ).then( function () {
+                                       return factory.createForContentModel(
+                                               contentModel,
+                                               title
+                                       );
+                               }, function () {
+                                       return $.Deferred().reject( 'failed-to-load-module', 'Failed to load the \'' + moduleName + '\' module' );
+                               } );
+                       } else {
+                               return $.Deferred().reject( 'unexpected-response', 'Unexpected API response' );
+                       }
+               }, function ( errorCode, details ) {
+                       return $.Deferred().reject( 'content-model-query-failed', errorCode, details );
+               } ).promise();
+       };
+
+       /**
+        * Creates a MessagePoster instance, given a title and content model
+        *
+        * @private
+        *
+        * @param {string} contentModel Content model of title
+        * @param {mw.Title} title Title being posted to
+        * @return {mw.messagePoster.MessagePoster}
+        *
+        */
+       MwMessagePosterFactory.prototype.createForContentModel = function ( contentModel, title ) {
+               return new this.contentModelToClass[contentModel]( title );
+       };
+
+       mw.messagePoster = {
+               factory: new MwMessagePosterFactory()
+       };
+}( mediaWiki, jQuery ) );
index 9a671c0..d940100 100644 (file)
@@ -36,7 +36,6 @@
         * @class
         * @constructor
         * @param {Object} [config] Configuration object
-        * @cfg {mw.Api} [api] if omitted, will just create a standard API
         * @cfg {mw.Title} [title="Feedback"] The title of the page where you collect
         *  feedback.
         * @cfg {string} [dialogTitleMessageKey="feedback-dialog-title"] Message key for the
        mw.Feedback = function MwFeedback( config ) {
                config = config || {};
 
-               this.api = config.api || new mw.Api();
                this.dialogTitleMessageKey = config.dialogTitleMessageKey || 'feedback-dialog-title';
 
                // Feedback page title
                this.feedbackPageTitle = config.title || new mw.Title( 'Feedback' );
 
+               this.messagePosterPromise = mw.messagePoster.factory.create( this.feedbackPageTitle );
+
                // Links
                this.bugsTaskSubmissionLink = config.bugsLink || '//phabricator.wikimedia.org/maniphest/task/create/';
                this.bugsTaskListLink = config.bugsListLink || '//phabricator.wikimedia.org/maniphest/query/advanced';
                        case 'error1':
                        case 'error2':
                        case 'error3':
+                       case 'error4':
                                dialogConfig = {
                                        title: mw.msg( 'feedback-error-title' ),
                                        message: mw.msg( 'feedback-' + status ),
         * Modify the display form, and then open it, focusing interface on the subject.
         *
         * @param {Object} [contents] Prefilled contents for the feedback form.
-        * @param {string} [contents.subject] The subject of the feedback
-        * @param {string} [contents.message] The content of the feedback
+        * @param {string} [contents.subject] The subject of the feedback, as plaintext
+        * @param {string} [contents.message] The content of the feedback, as wikitext
         */
        mw.Feedback.prototype.launch = function ( contents ) {
                // Dialog
                        {
                                title: mw.msg( this.dialogTitleMessageKey ),
                                settings: {
-                                       api: this.api,
+                                       messagePosterPromise: this.messagePosterPromise,
                                        title: this.feedbackPageTitle,
                                        dialogTitleMessageKey: this.dialogTitleMessageKey,
                                        bugsTaskSubmissionLink: this.bugsTaskSubmissionLink,
                                this.feedbackMessageInput.setValue( data.contents.message );
 
                                this.status = '';
-                               this.api = settings.api;
+                               this.messagePosterPromise = settings.messagePosterPromise;
                                this.setBugReportLink( settings.bugsTaskSubmissionLink );
                                this.feedbackPageTitle = settings.title;
                                this.feedbackPageName = settings.title.getNameText();
                                        message = userAgentMessage + message;
                                }
 
-                               // Add signature if needed
-                               if ( message.indexOf( '~~~' ) === -1 ) {
-                                       message += '\n\n~~~~';
-                               }
-
-                               // Post the message, resolving redirects
-                               this.pushPending();
-                               this.api.newSection(
-                                       this.feedbackPageTitle,
-                                       subject,
-                                       message,
-                                       { redirect: true }
-                               )
-                               .done( function ( result ) {
-                                       if ( result.edit.result === 'Success' ) {
-                                               fb.status = 'submitted';
-                                       } else {
-                                               fb.status = 'error1';
-                                       }
-                                       fb.popPending();
-                                       fb.close();
-                               } )
-                               .fail( function ( code, result ) {
-                                       if ( code === 'http' ) {
-                                               fb.status = 'error3';
-                                               // ajax request failed
-                                               mw.log.warn( 'Feedback report failed with HTTP error: ' +  result.textStatus );
-                                       } else {
-                                               fb.status = 'error2';
-                                               mw.log.warn( 'Feedback report failed with API error: ' +  code );
-                                       }
-                                       fb.popPending();
+                               // Post the message
+                               return this.messagePosterPromise.then( function ( poster ) {
+                                       return fb.postMessage( poster, subject, message );
+                               }, function () {
+                                       fb.status = 'error4';
+                                       mw.log.warn( 'Feedback report failed because MessagePoster could not be fetched' );
+                               } ).always( function () {
                                        fb.close();
                                } );
                        }, this );
                return mw.Feedback.Dialog.super.prototype.getActionProcess.call( this, action );
        };
 
+       /**
+        * Posts the message
+        *
+        * @private
+        *
+        * @param {mw.messagePoster.MessagePoster} poster Poster implementation used to leave feedback
+        * @param {string} subject Subject of message
+        * @param {string} message Body of message
+        * @return {jQuery.Promise} Promise representing success of message posting action
+        */
+       mw.Feedback.Dialog.prototype.postMessage = function ( poster, subject, message ) {
+               var fb = this;
+
+               return poster.post(
+                       subject,
+                       message
+               ).then( function () {
+                       fb.status = 'submitted';
+               }, function ( mainCode, secondaryCode, details ) {
+                       if ( mainCode === 'api-fail' ) {
+                               if ( secondaryCode === 'http' ) {
+                                       fb.status = 'error3';
+                                       // ajax request failed
+                                       mw.log.warn( 'Feedback report failed with HTTP error: ' +  details.textStatus );
+                               } else {
+                                       fb.status = 'error2';
+                                       mw.log.warn( 'Feedback report failed with API error: ' +  secondaryCode );
+                               }
+                       } else {
+                               fb.status = 'error1';
+                       }
+               } );
+       };
+
        /**
         * @inheritdoc
         */
index ee6a8cf..6c6d95e 100644 (file)
@@ -172,7 +172,7 @@ mw.test.baz({token:123});mw.loader.state({"test.quux":"ready"});
                        array(
                                array( 'test.quux', ResourceLoaderModule::TYPE_COMBINED ),
                                '<script>if(window.mw){
-mw.loader.implement("test.quux",function($,jQuery){mw.test.baz({token:123});},{"css":[".mw-icon{transition:none}\n"]},{},{});
+mw.loader.implement("test.quux",function($,jQuery){mw.test.baz({token:123});},{"css":[".mw-icon{transition:none}\n"]});
 
 }</script>
 '
index 987b6e6..4516bb4 100644 (file)
@@ -1,8 +1,6 @@
 <?php
 /**
- * This class will test BagOStuff.
- *
- * @author     Matthias Mullie <mmullie@wikimedia.org>
+ * @author Matthias Mullie <mmullie@wikimedia.org>
  */
 class BagOStuffTest extends MediaWikiTestCase {
        private $cache;
@@ -23,6 +21,10 @@ class BagOStuffTest extends MediaWikiTestCase {
                $this->cache->delete( wfMemcKey( 'test' ) );
        }
 
+       /**
+        * @covers BagOStuff::merge
+        * @covers BagOStuff::mergeViaLock
+        */
        public function testMerge() {
                $key = wfMemcKey( 'test' );
 
@@ -100,6 +102,9 @@ class BagOStuffTest extends MediaWikiTestCase {
                }
        }
 
+       /**
+        * @covers BagOStuff::add
+        */
        public function testAdd() {
                $key = wfMemcKey( 'test' );
                $this->assertTrue( $this->cache->add( $key, 'test' ) );
@@ -125,6 +130,9 @@ class BagOStuffTest extends MediaWikiTestCase {
                $this->assertEquals( $expectedValue, $actualValue, 'Value should be 1 after incrementing' );
        }
 
+       /**
+        * @covers BagOStuff::getMulti
+        */
        public function testGetMulti() {
                $value1 = array( 'this' => 'is', 'a' => 'test' );
                $value2 = array( 'this' => 'is', 'another' => 'test' );
index 8410663..d0bc210 100644 (file)
@@ -31,7 +31,7 @@ class ResourceLoaderImageModuleTest extends ResourceLoaderTestCase {
                                'default' => 'bold-a.svg',
                                'lang' => array(
                                        'en' => 'bold-b.svg',
-                                       'de' => 'bold-f.svg',
+                                       'ar,de' => 'bold-f.svg',
                                )
                        ),
                )
index 404ae9d..758cfe1 100644 (file)
@@ -33,6 +33,7 @@ class ResourceLoaderImageTest extends ResourceLoaderTestCase {
                        array( 'help', 'he', 'help-ltr.svg' ),
                        array( 'bold', 'en', 'bold-b.svg' ),
                        array( 'bold', 'de', 'bold-f.svg' ),
+                       array( 'bold', 'ar', 'bold-f.svg' ),
                        array( 'bold', 'fr', 'bold-a.svg' ),
                        array( 'bold', 'he', 'bold-a.svg' ),
                );
index e43db78..ca7307e 100644 (file)
@@ -186,6 +186,106 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                );
        }
 
+       public static function provideLoaderImplement() {
+               return array(
+                       array( array(
+                               'title' => 'Implement scripts, styles and messages',
+
+                               'name' => 'test.example',
+                               'scripts' => 'mw.example();',
+                               'styles' => array( 'css' => array( '.mw-example {}' ) ),
+                               'messages' => array( 'example' => '' ),
+                               'templates' => array(),
+
+                               'expected' => 'mw.loader.implement( "test.example", function ( $, jQuery ) {
+mw.example();
+}, {
+    "css": [
+        ".mw-example {}"
+    ]
+}, {
+    "example": ""
+} );',
+                       ) ),
+                       array( array(
+                               'title' => 'Implement scripts',
+
+                               'name' => 'test.example',
+                               'scripts' => 'mw.example();',
+                               'styles' => array(),
+                               'messages' => new XmlJsCode( '{}' ),
+                               'templates' => array(),
+                               'title' => 'scripts, styles and messags',
+
+                               'expected' => 'mw.loader.implement( "test.example", function ( $, jQuery ) {
+mw.example();
+} );',
+                       ) ),
+                       array( array(
+                               'title' => 'Implement styles',
+
+                               'name' => 'test.example',
+                               'scripts' => array(),
+                               'styles' => array( 'css' => array( '.mw-example {}' ) ),
+                               'messages' => new XmlJsCode( '{}' ),
+                               'templates' => array(),
+
+                               'expected' => 'mw.loader.implement( "test.example", [], {
+    "css": [
+        ".mw-example {}"
+    ]
+} );',
+                       ) ),
+                       array( array(
+                               'title' => 'Implement scripts and messages',
+
+                               'name' => 'test.example',
+                               'scripts' => 'mw.example();',
+                               'styles' => array(),
+                               'messages' => array( 'example' => '' ),
+                               'templates' => array(),
+
+                               'expected' => 'mw.loader.implement( "test.example", function ( $, jQuery ) {
+mw.example();
+}, {}, {
+    "example": ""
+} );',
+                       ) ),
+                       array( array(
+                               'title' => 'Implement scripts and templates',
+
+                               'name' => 'test.example',
+                               'scripts' => 'mw.example();',
+                               'styles' => array(),
+                               'messages' => new XmlJsCode( '{}' ),
+                               'templates' => array( 'example.html' => '' ),
+
+                               'expected' => 'mw.loader.implement( "test.example", function ( $, jQuery ) {
+mw.example();
+}, {}, {}, {
+    "example.html": ""
+} );',
+                       ) ),
+               );
+       }
+
+       /**
+        * @dataProvider provideLoaderImplement
+        * @covers ResourceLoader::makeLoaderImplementScript
+        */
+       public function testMakeLoaderImplementScript( $case ) {
+               $this->assertEquals(
+                       $case['expected'],
+                       ResourceLoader::makeLoaderImplementScript(
+                               $case['name'],
+                               $case['scripts'],
+                               $case['styles'],
+                               $case['messages'],
+                               $case['templates']
+                       )
+               );
+       }
+
        /**
         * @covers ResourceLoader::getLoadScript
         */
index 9a3dab6..17b8b63 100644 (file)
@@ -65,6 +65,7 @@ return array(
                        'tests/qunit/suites/resources/mediawiki/mediawiki.errorLogger.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js',
+                       'tests/qunit/suites/resources/mediawiki/mediawiki.messagePoster.factory.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.template.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js',
@@ -106,6 +107,7 @@ return array(
                        'mediawiki.api.parse',
                        'mediawiki.api.watch',
                        'mediawiki.jqueryMsg',
+                       'mediawiki.messagePoster',
                        'mediawiki.Title',
                        'mediawiki.toc',
                        'mediawiki.Uri',
diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.messagePoster.factory.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.messagePoster.factory.test.js
new file mode 100644 (file)
index 0000000..61bab03
--- /dev/null
@@ -0,0 +1,28 @@
+( function ( mw ) {
+       var TEST_MODEL = 'test-content-model';
+
+       QUnit.module( 'mediawiki.messagePoster', QUnit.newMwEnvironment( {
+               teardown: function () {
+                       mw.messagePoster.factory.unregister( TEST_MODEL );
+               }
+       } ) );
+
+       QUnit.test( 'register', 2, function ( assert ) {
+               var testMessagePosterConstructor = function () {};
+
+               mw.messagePoster.factory.register( TEST_MODEL, testMessagePosterConstructor );
+               assert.strictEqual(
+                       mw.messagePoster.factory.contentModelToClass[TEST_MODEL],
+                       testMessagePosterConstructor,
+                       'Constructor is registered'
+               );
+
+               assert.throws(
+                       function () {
+                               mw.messagePoster.factory.register( TEST_MODEL, testMessagePosterConstructor );
+                       },
+                       new RegExp( 'The content model \'' + TEST_MODEL + '\' is already registered.' ),
+                       'Throws exception is same model is registered a second time'
+               );
+       } );
+}( mediaWiki ) );