Merge "MediaWikiServices: Don't assume, that old and new instances contains the same...
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 30 Aug 2016 14:31:14 +0000 (14:31 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 30 Aug 2016 14:31:14 +0000 (14:31 +0000)
82 files changed:
RELEASE-NOTES-1.28
autoload.php
docs/hooks.txt
includes/DefaultSettings.php
includes/EditPage.php
includes/MediaWiki.php
includes/OutputPage.php
includes/Preferences.php
includes/WebRequest.php
includes/actions/ViewAction.php
includes/api/ApiBase.php
includes/api/ApiPageSet.php
includes/api/ApiQueryBlocks.php
includes/api/ApiResult.php
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/mr.json
includes/auth/TemporaryPasswordPrimaryAuthenticationProvider.php
includes/db/Database.php
includes/db/DatabaseError.php
includes/db/loadbalancer/LBFactory.php
includes/db/loadbalancer/LBFactoryMulti.php
includes/db/loadbalancer/LBFactorySimple.php
includes/deferred/LinksUpdate.php
includes/installer/i18n/diq.json
includes/objectcache/MemcachedPeclBagOStuff.php
includes/page/Article.php
includes/page/WikiPage.php
includes/resourceloader/ResourceLoaderContext.php
includes/session/SessionBackend.php
includes/specials/SpecialBlockList.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialPreferences.php
languages/Language.php
languages/i18n/aeb-arab.json
languages/i18n/ar.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/bg.json
languages/i18n/br.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dty.json
languages/i18n/egl.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/fa.json
languages/i18n/fr.json
languages/i18n/ga.json
languages/i18n/gl.json
languages/i18n/gu.json
languages/i18n/hu.json
languages/i18n/it.json
languages/i18n/jv.json
languages/i18n/lb.json
languages/i18n/mai.json
languages/i18n/ne.json
languages/i18n/ru.json
languages/i18n/sv.json
languages/i18n/te.json
languages/i18n/th.json
languages/i18n/tr.json
maintenance/updateCollation.php
resources/src/mediawiki.special/mediawiki.special.apisandbox.js
resources/src/mediawiki.widgets/mw.widgets.CategoryCapsuleItemWidget.js
resources/src/mediawiki/api.js
resources/src/mediawiki/api/messages.js
resources/src/mediawiki/api/options.js
tests/phpunit/includes/api/ApiBaseTest.php
tests/phpunit/includes/api/ApiPageSetTest.php
tests/phpunit/includes/api/MockApi.php
tests/phpunit/includes/api/query/ApiQueryTest.php
tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
tests/phpunit/includes/db/DatabaseTestHelper.php
tests/phpunit/includes/resourceloader/DerivativeResourceLoaderContextTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderContextTest.php [new file with mode: 0644]
tests/phpunit/includes/resourceloader/ResourceLoaderImageModuleTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.options.test.js

index 1463c6d..6639a95 100644 (file)
@@ -26,9 +26,9 @@ production.
   https://www.mediawiki.org/beacon with basic information about the local
   MediaWiki installation. This data includes, for example, the type of system,
   PHP version, and chosen database backend. This behavior is off by default.
-* When $wgEditButtonPublishNotSave is true, MediaWiki will label the button to
-  store-to-database-and-show-to-others as "Publish page"/"Publish changes"; if
-  false, the default, they will be "Save page"/"Save changes".
+* When $EditSubmitButtonLabelPublish is true, MediaWiki will label the button
+  to store-to-database-and-show-to-others as "Publish page"/"Publish changes";
+  if false, the default, they will be "Save page"/"Save changes".
 
 === New features in 1.28 ===
 * User::isBot() method for checking if an account is a bot role account.
@@ -45,6 +45,11 @@ production.
   to 'uca-default-u-kn' or 'uca-<langcode>-u-kn'. If you can't use UCA collations,
   a 'numeric' collation is also available. If migrating from another
   collation, you will need to run the updateCollation.php maintenance script.
+* Two new codes have been added to #time parser function: "xit" for days in current
+  month, and "xiz" for days passed in the year, both in Iranian calendar.
+* mw.Api has a new option, useUS, to use U+001F (Unit Separator) when
+  appropriate for sending multi-valued parameters. This defaults to true when
+  the mw.Api instance seems to be for the local wiki.
 
 === External library changes in 1.28 ===
 
@@ -82,6 +87,15 @@ production.
   action=createaccount, action=linkaccount, and action=changeauthenticationdata
   in the query string is now deprecated and outputs a warning. They should be
   submitted in the POST body instead.
+* (T141960) Multi-valued parameters may now be separated using U+001F (Unit Separator)
+  instead of the pipe character. This will be useful if some of the multiple
+  values need to contain pipes, e.g. for action=options.
+* The API will now warn if input is not NFC-normalized Unicode or if it
+  contains invalid characters.
+* The 'normalized' list output by action=query and other modules that use
+  ApiPageSet may contain entries where the 'from' value is percent-encoded as
+  the raw value cannot be represented in a valid API response. These are
+  indicated by a 'fromencoded' boolean alongside the existing 'from' parameter.
 
 === Action API internal changes in 1.28 ===
 * Added a new hook, 'ApiMakeParserOptions', to allow extensions to better
index 39102fd..dec7219 100644 (file)
@@ -297,7 +297,7 @@ $wgAutoloadLocalClasses = [
        'CsvStatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
        'CurlHttpRequest' => __DIR__ . '/includes/HttpFunctions.php',
        'DBAccessBase' => __DIR__ . '/includes/dao/DBAccessBase.php',
-       'DBAccessError' => __DIR__ . '/includes/db/loadbalancer/LBFactory.php',
+       'DBAccessError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBAccessObjectUtils' => __DIR__ . '/includes/dao/DBAccessObjectUtils.php',
        'DBConnRef' => __DIR__ . '/includes/db/DBConnRef.php',
        'DBConnectionError' => __DIR__ . '/includes/db/DatabaseError.php',
@@ -308,7 +308,7 @@ $wgAutoloadLocalClasses = [
        'DBMasterPos' => __DIR__ . '/includes/db/DatabaseUtility.php',
        'DBQueryError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBReadOnlyError' => __DIR__ . '/includes/db/DatabaseError.php',
-       'DBReplicationWaitError' => __DIR__ . '/includes/db/loadbalancer/LBFactory.php',
+       'DBReplicationWaitError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBSiteStore' => __DIR__ . '/includes/site/DBSiteStore.php',
        'DBTransactionError' => __DIR__ . '/includes/db/DatabaseError.php',
        'DBUnexpectedError' => __DIR__ . '/includes/db/DatabaseError.php',
index 1e3cf1e..a7fb873 100644 (file)
@@ -596,7 +596,7 @@ $outputPage: OutputPage that can be used to append the output.
 &$user: the user that deleted the article
 $reason: the reason the article was deleted
 $id: id of the article that was deleted
-$content: the Content of the deleted page
+$content: the Content of the deleted page (or null, when deleting a broken page)
 $logEntry: the ManualLogEntry used to record the deletion
 $archivedRevisionCount: the number of revisions archived during the deletion
 
@@ -3732,7 +3732,8 @@ a page is deleted. Called in WikiPage::getDeletionUpdates(). Note that updates
 specific to a content model should be provided by the respective Content's
 getDeletionUpdates() method.
 $page: the WikiPage
-$content: the Content to generate updates for
+$content: the Content to generate updates for (or null, if the Content could not be loaded
+due to an error)
 &$updates: the array of DataUpdate objects. Hook function may want to add to it.
 
 'XmlDumpWriterOpenPage': Called at the end of XmlDumpWriter::openPage, to allow
index 828c8e7..fa6df8d 100644 (file)
@@ -3200,7 +3200,7 @@ $wgUseMediaWikiUIEverywhere = false;
  *
  * @since 1.28
  */
-$wgEditButtonPublishNotSave = false;
+$wgEditSubmitButtonLabelPublish = false;
 
 /**
  * Permit other namespaces in addition to the w3.org default.
index f954529..e0080fa 100644 (file)
@@ -507,6 +507,7 @@ class EditPage {
         * the newly-edited page.
         */
        function edit() {
+               global $wgOut, $wgRequest, $wgUser;
                // Allow extensions to modify/prevent this form or submission
                if ( !Hooks::run( 'AlternateEdit', [ $this ] ) ) {
                        return;
@@ -514,15 +515,13 @@ class EditPage {
 
                wfDebug( __METHOD__ . ": enter\n" );
 
-               $request = $this->context->getRequest();
-               $out = $this->context->getOutput();
                // If they used redlink=1 and the page exists, redirect to the main article
-               if ( $request->getBool( 'redlink' ) && $this->mTitle->exists() ) {
-                       $out->redirect( $this->mTitle->getFullURL() );
+               if ( $wgRequest->getBool( 'redlink' ) && $this->mTitle->exists() ) {
+                       $wgOut->redirect( $this->mTitle->getFullURL() );
                        return;
                }
 
-               $this->importFormData( $request );
+               $this->importFormData( $wgRequest );
                $this->firsttime = false;
 
                if ( wfReadOnly() && $this->save ) {
@@ -551,7 +550,7 @@ class EditPage {
                        wfDebug( __METHOD__ . ": User can't edit\n" );
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
-                               $user = $this->context->getUser();
+                               $user = $wgUser;
                                DeferredUpdates::addCallableUpdate( function () use ( $user ) {
                                        $user->spreadAnyEditBlock();
                                } );
@@ -625,14 +624,15 @@ class EditPage {
         * @return array
         */
        protected function getEditPermissionErrors( $rigor = 'secure' ) {
-               $user = $this->context->getUser();
-               $permErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $user, $rigor );
+               global $wgUser;
+
+               $permErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $wgUser, $rigor );
                # Can this title be created?
                if ( !$this->mTitle->exists() ) {
                        $permErrors = array_merge(
                                $permErrors,
                                wfArrayDiff2(
-                                       $this->mTitle->getUserPermissionsErrors( 'create', $user, $rigor ),
+                                       $this->mTitle->getUserPermissionsErrors( 'create', $wgUser, $rigor ),
                                        $permErrors
                                )
                        );
@@ -665,12 +665,13 @@ class EditPage {
         * @throws PermissionsError
         */
        protected function displayPermissionsError( array $permErrors ) {
-               $out = $this->context->getOutput();
-               if ( $this->context->getRequest()->getBool( 'redlink' ) ) {
+               global $wgRequest, $wgOut;
+
+               if ( $wgRequest->getBool( 'redlink' ) ) {
                        // The edit page was reached via a red link.
                        // Redirect to the article page and let them click the edit tab if
                        // they really want a permission error.
-                       $out->redirect( $this->mTitle->getFullURL() );
+                       $wgOut->redirect( $this->mTitle->getFullURL() );
                        return;
                }
 
@@ -685,7 +686,7 @@ class EditPage {
 
                $this->displayViewSourcePage(
                        $content,
-                       $out->formatPermissionsErrorMessage( $permErrors, 'edit' )
+                       $wgOut->formatPermissionsErrorMessage( $permErrors, 'edit' )
                );
        }
 
@@ -695,28 +696,29 @@ class EditPage {
         * @param string $errorMessage additional wikitext error message to display
         */
        protected function displayViewSourcePage( Content $content, $errorMessage = '' ) {
-               $out = $this->context->getOutput();
-               Hooks::run( 'EditPage::showReadOnlyForm:initial', [ $this, &$out ] );
+               global $wgOut;
 
-               $out->setRobotPolicy( 'noindex,nofollow' );
-               $out->setPageTitle( wfMessage(
+               Hooks::run( 'EditPage::showReadOnlyForm:initial', [ $this, &$wgOut ] );
+
+               $wgOut->setRobotPolicy( 'noindex,nofollow' );
+               $wgOut->setPageTitle( wfMessage(
                        'viewsource-title',
                        $this->getContextTitle()->getPrefixedText()
                ) );
-               $out->addBacklinkSubtitle( $this->getContextTitle() );
-               $out->addHTML( $this->editFormPageTop );
-               $out->addHTML( $this->editFormTextTop );
+               $wgOut->addBacklinkSubtitle( $this->getContextTitle() );
+               $wgOut->addHTML( $this->editFormPageTop );
+               $wgOut->addHTML( $this->editFormTextTop );
 
                if ( $errorMessage !== '' ) {
-                       $out->addWikiText( $errorMessage );
-                       $out->addHTML( "<hr />\n" );
+                       $wgOut->addWikiText( $errorMessage );
+                       $wgOut->addHTML( "<hr />\n" );
                }
 
                # If the user made changes, preserve them when showing the markup
                # (This happens when a user is blocked during edit, for instance)
                if ( !$this->firsttime ) {
                        $text = $this->textbox1;
-                       $out->addWikiMsg( 'viewyourtext' );
+                       $wgOut->addWikiMsg( 'viewyourtext' );
                } else {
                        try {
                                $text = $this->toEditText( $content );
@@ -725,21 +727,21 @@ class EditPage {
                                # (e.g. for an old revision with a different model)
                                $text = $content->serialize();
                        }
-                       $out->addWikiMsg( 'viewsourcetext' );
+                       $wgOut->addWikiMsg( 'viewsourcetext' );
                }
 
-               $out->addHTML( $this->editFormTextBeforeContent );
+               $wgOut->addHTML( $this->editFormTextBeforeContent );
                $this->showTextbox( $text, 'wpTextbox1', [ 'readonly' ] );
-               $out->addHTML( $this->editFormTextAfterContent );
+               $wgOut->addHTML( $this->editFormTextAfterContent );
 
-               $out->addHTML( Html::rawElement( 'div', [ 'class' => 'templatesUsed' ],
+               $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'templatesUsed' ],
                        Linker::formatTemplates( $this->getTemplates() ) ) );
 
-               $out->addModules( 'mediawiki.action.edit.collapsibleFooter' );
+               $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' );
 
-               $out->addHTML( $this->editFormTextBottom );
+               $wgOut->addHTML( $this->editFormTextBottom );
                if ( $this->mTitle->exists() ) {
-                       $out->returnToMain( null, $this->mTitle );
+                       $wgOut->returnToMain( null, $this->mTitle );
                }
        }
 
@@ -749,19 +751,18 @@ class EditPage {
         * @return bool
         */
        protected function previewOnOpen() {
-               global $wgPreviewOnOpenNamespaces;
-               $request = $this->context->getRequest();
-               if ( $request->getVal( 'preview' ) == 'yes' ) {
+               global $wgRequest, $wgUser, $wgPreviewOnOpenNamespaces;
+               if ( $wgRequest->getVal( 'preview' ) == 'yes' ) {
                        // Explicit override from request
                        return true;
-               } elseif ( $request->getVal( 'preview' ) == 'no' ) {
+               } elseif ( $wgRequest->getVal( 'preview' ) == 'no' ) {
                        // Explicit override from request
                        return false;
                } elseif ( $this->section == 'new' ) {
                        // Nothing *to* preview for new sections
                        return false;
-               } elseif ( ( $request->getVal( 'preload' ) !== null || $this->mTitle->exists() )
-                       && $this->context->getUser()->getOption( 'previewonfirst' )
+               } elseif ( ( $wgRequest->getVal( 'preload' ) !== null || $this->mTitle->exists() )
+                       && $wgUser->getOption( 'previewonfirst' )
                ) {
                        // Standard preference behavior
                        return true;
@@ -814,7 +815,7 @@ class EditPage {
         * @throws ErrorPageError
         */
        function importFormData( &$request ) {
-               global $wgContLang;
+               global $wgContLang, $wgUser;
 
                # Section edit can come from either the form or a link
                $this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
@@ -926,14 +927,13 @@ class EditPage {
                        $this->watchthis = $request->getCheck( 'wpWatchthis' );
 
                        # Don't force edit summaries when a user is editing their own user or talk page
-                       $user = $this->context->getUser();
                        if ( ( $this->mTitle->mNamespace == NS_USER || $this->mTitle->mNamespace == NS_USER_TALK )
-                               && $this->mTitle->getText() == $user->getName()
+                               && $this->mTitle->getText() == $wgUser->getName()
                        ) {
                                $this->allowBlankSummary = true;
                        } else {
                                $this->allowBlankSummary = $request->getBool( 'wpIgnoreBlankSummary' )
-                                       || !$user->getOption( 'forceeditsummary' );
+                                       || !$wgUser->getOption( 'forceeditsummary' );
                        }
 
                        $this->autoSumm = $request->getText( 'wpAutoSummary' );
@@ -1039,6 +1039,7 @@ class EditPage {
         * @return bool If the requested section is valid
         */
        function initialiseForm() {
+               global $wgUser;
                $this->edittime = $this->page->getTimestamp();
                $this->editRevId = $this->page->getLatest();
 
@@ -1047,21 +1048,20 @@ class EditPage {
                        return false;
                }
                $this->textbox1 = $this->toEditText( $content );
-               $user = $this->context->getUser();
 
                // activate checkboxes if user wants them to be always active
                # Sort out the "watch" checkbox
-               if ( $user->getOption( 'watchdefault' ) ) {
+               if ( $wgUser->getOption( 'watchdefault' ) ) {
                        # Watch all edits
                        $this->watchthis = true;
-               } elseif ( $user->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
+               } elseif ( $wgUser->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
                        # Watch creations
                        $this->watchthis = true;
-               } elseif ( $user->isWatched( $this->mTitle ) ) {
+               } elseif ( $wgUser->isWatched( $this->mTitle ) ) {
                        # Already watched
                        $this->watchthis = true;
                }
-               if ( $user->getOption( 'minordefault' ) && !$this->isNew ) {
+               if ( $wgUser->getOption( 'minordefault' ) && !$this->isNew ) {
                        $this->minoredit = true;
                }
                if ( $this->textbox1 === false ) {
@@ -1078,11 +1078,9 @@ class EditPage {
         * @since 1.21
         */
        protected function getContentObject( $def_content = null ) {
-               global $wgContLang;
+               global $wgOut, $wgRequest, $wgUser, $wgContLang;
 
                $content = false;
-               $request = $this->context->getRequest();
-               $user = $this->context->getUser();
 
                // For message page not locally set, use the i18n message.
                // For other non-existent articles, use preload text if any.
@@ -1095,10 +1093,10 @@ class EditPage {
                        }
                        if ( $content === false ) {
                                # If requested, preload some text.
-                               $preload = $request->getVal( 'preload',
+                               $preload = $wgRequest->getVal( 'preload',
                                        // Custom preload text for new sections
                                        $this->section === 'new' ? 'MediaWiki:addsection-preload' : '' );
-                               $params = $request->getArray( 'preloadparams', [] );
+                               $params = $wgRequest->getArray( 'preloadparams', [] );
 
                                $content = $this->getPreloadedContent( $preload, $params );
                        }
@@ -1106,15 +1104,15 @@ class EditPage {
                } else {
                        if ( $this->section != '' ) {
                                // Get section edit text (returns $def_text for invalid sections)
-                               $orig = $this->getOriginalContent( $user );
+                               $orig = $this->getOriginalContent( $wgUser );
                                $content = $orig ? $orig->getSection( $this->section ) : null;
 
                                if ( !$content ) {
                                        $content = $def_content;
                                }
                        } else {
-                               $undoafter = $request->getInt( 'undoafter' );
-                               $undo = $request->getInt( 'undo' );
+                               $undoafter = $wgRequest->getInt( 'undoafter' );
+                               $undo = $wgRequest->getInt( 'undo' );
 
                                if ( $undo > 0 && $undoafter > 0 ) {
                                        $undorev = Revision::newFromId( $undo );
@@ -1134,8 +1132,8 @@ class EditPage {
                                                        $undoMsg = 'failure';
                                                } else {
                                                        $oldContent = $this->page->getContent( Revision::RAW );
-                                                       $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang );
-                                                       $newContent = $content->preSaveTransform( $this->mTitle, $user, $popts );
+                                                       $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
+                                                       $newContent = $content->preSaveTransform( $this->mTitle, $wgUser, $popts );
 
                                                        if ( $newContent->equals( $oldContent ) ) {
                                                                # Tell the user that the undo results in no change,
@@ -1182,13 +1180,12 @@ class EditPage {
 
                                        // Messages: undo-success, undo-failure, undo-norev, undo-nochange
                                        $class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
-                                       $this->editFormPageTop .= $this->context->getOutput()->parse(
-                                               "<div class=\"{$class}\">" .
+                                       $this->editFormPageTop .= $wgOut->parse( "<div class=\"{$class}\">" .
                                                wfMessage( 'undo-' . $undoMsg )->plain() . '</div>', true, /* interface */true );
                                }
 
                                if ( $content === false ) {
-                                       $content = $this->getOriginalContent( $user );
+                                       $content = $this->getOriginalContent( $wgUser );
                                }
                        }
                }
@@ -1385,10 +1382,10 @@ class EditPage {
         * @private
         */
        function tokenOk( &$request ) {
+               global $wgUser;
                $token = $request->getVal( 'wpEditToken' );
-               $user = $this->context->getUser();
-               $this->mTokenOk = $user->matchEditToken( $token );
-               $this->mTokenOkExceptSuffix = $user->matchEditTokenNoSuffix( $token );
+               $this->mTokenOk = $wgUser->matchEditToken( $token );
+               $this->mTokenOkExceptSuffix = $wgUser->matchEditTokenNoSuffix( $token );
                return $this->mTokenOk;
        }
 
@@ -1419,7 +1416,7 @@ class EditPage {
                        $val = 'restored';
                }
 
-               $response = $this->context->getRequest()->response();
+               $response = RequestContext::getMain()->getRequest()->response();
                $response->setCookie( $postEditKey, $val, time() + self::POST_EDIT_COOKIE_DURATION, [
                        'httpOnly' => false,
                ] );
@@ -1432,8 +1429,10 @@ class EditPage {
         * @return Status The resulting status object.
         */
        public function attemptSave( &$resultDetails = false ) {
+               global $wgUser;
+
                # Allow bots to exempt some edits from bot flagging
-               $bot = $this->context->getUser()->isAllowed( 'bot' ) && $this->bot;
+               $bot = $wgUser->isAllowed( 'bot' ) && $this->bot;
                $status = $this->internalAttemptSave( $resultDetails, $bot );
 
                Hooks::run( 'EditPage::attemptSave:after', [ $this, $status, $resultDetails ] );
@@ -1451,6 +1450,8 @@ class EditPage {
         * @return bool False, if output is done, true if rest of the form should be displayed
         */
        private function handleStatus( Status $status, $resultDetails ) {
+               global $wgUser, $wgOut;
+
                /**
                 * @todo FIXME: once the interface for internalAttemptSave() is made
                 *   nicer, this should use the message in $status
@@ -1464,11 +1465,9 @@ class EditPage {
                        }
                }
 
-               $out = $this->context->getOutput();
-
                // "wpExtraQueryRedirect" is a hidden input to modify
                // after save URL and is not used by actual edit form
-               $request = $this->context->getRequest();
+               $request = RequestContext::getMain()->getRequest();
                $extraQueryRedirect = $request->getVal( 'wpExtraQueryRedirect' );
 
                switch ( $status->value ) {
@@ -1489,7 +1488,7 @@ class EditPage {
 
                        case self::AS_CANNOT_USE_CUSTOM_MODEL:
                        case self::AS_PARSE_ERROR:
-                               $out->addWikiText( '<div class="error">' . "\n" . $status->getWikiText() . '</div>' );
+                               $wgOut->addWikiText( '<div class="error">' . "\n" . $status->getWikiText() . '</div>' );
                                return true;
 
                        case self::AS_SUCCESS_NEW_ARTICLE:
@@ -1502,7 +1501,7 @@ class EditPage {
                                        }
                                }
                                $anchor = isset( $resultDetails['sectionanchor'] ) ? $resultDetails['sectionanchor'] : '';
-                               $out->redirect( $this->mTitle->getFullURL( $query ) . $anchor );
+                               $wgOut->redirect( $this->mTitle->getFullURL( $query ) . $anchor );
                                return false;
 
                        case self::AS_SUCCESS_UPDATE:
@@ -1530,7 +1529,7 @@ class EditPage {
                                        }
                                }
 
-                               $out->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
+                               $wgOut->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
                                return false;
 
                        case self::AS_SPAM_ERROR:
@@ -1538,7 +1537,7 @@ class EditPage {
                                return false;
 
                        case self::AS_BLOCKED_PAGE_FOR_USER:
-                               throw new UserBlockedError( $this->context->getUser()->getBlock() );
+                               throw new UserBlockedError( $wgUser->getBlock() );
 
                        case self::AS_IMAGE_REDIRECT_ANON:
                        case self::AS_IMAGE_REDIRECT_LOGGED:
@@ -1599,7 +1598,7 @@ class EditPage {
 
                // Run new style post-section-merge edit filter
                if ( !Hooks::run( 'EditFilterMergedContent',
-                               [ $this->context, $content, $status, $this->summary,
+                               [ $this->mArticle->getContext(), $content, $status, $this->summary,
                                $user, $this->minoredit ] )
                ) {
                        # Error messages etc. could be handled within the hook...
@@ -1684,11 +1683,10 @@ class EditPage {
         * time.
         */
        function internalAttemptSave( &$result, $bot = false ) {
-               global $wgParser, $wgMaxArticleSize, $wgContentHandlerUseDB;
+               global $wgUser, $wgRequest, $wgParser, $wgMaxArticleSize;
+               global $wgContentHandlerUseDB;
 
                $status = Status::newGood();
-               $user = $this->context->getUser();
-               $request = $this->context->getRequest();
 
                if ( !Hooks::run( 'EditPage::attemptSave', [ $this ] ) ) {
                        wfDebug( "Hook 'EditPage::attemptSave' aborted article saving\n" );
@@ -1697,11 +1695,11 @@ class EditPage {
                        return $status;
                }
 
-               $spam = $request->getText( 'wpAntispam' );
+               $spam = $wgRequest->getText( 'wpAntispam' );
                if ( $spam !== '' ) {
                        wfDebugLog(
                                'SimpleAntiSpam',
-                               $user->getName() .
+                               $wgUser->getName() .
                                ' editing "' .
                                $this->mTitle->getPrefixedText() .
                                '" submitted bogus field "' .
@@ -1730,9 +1728,9 @@ class EditPage {
                # Check image redirect
                if ( $this->mTitle->getNamespace() == NS_FILE &&
                        $textbox_content->isRedirect() &&
-                       !$user->isAllowed( 'upload' )
+                       !$wgUser->isAllowed( 'upload' )
                ) {
-                               $code = $user->isAnon() ? self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
+                               $code = $wgUser->isAnon() ? self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
                                $status->setResult( false, $code );
 
                                return $status;
@@ -1757,7 +1755,7 @@ class EditPage {
                }
                if ( $match !== false ) {
                        $result['spam'] = $match;
-                       $ip = $request->getIP();
+                       $ip = $wgRequest->getIP();
                        $pdbk = $this->mTitle->getPrefixedDBkey();
                        $match = str_replace( "\n", '', $match );
                        wfDebugLog( 'SpamRegex', "$ip spam regex hit [[$pdbk]]: \"$match\"" );
@@ -1780,10 +1778,10 @@ class EditPage {
                        return $status;
                }
 
-               if ( $user->isBlockedFrom( $this->mTitle, false ) ) {
+               if ( $wgUser->isBlockedFrom( $this->mTitle, false ) ) {
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
-                               $user->spreadAnyEditBlock();
+                               $wgUser->spreadAnyEditBlock();
                        }
                        # Check block state against master, thus 'false'.
                        $status->setResult( false, self::AS_BLOCKED_PAGE_FOR_USER );
@@ -1798,8 +1796,8 @@ class EditPage {
                        return $status;
                }
 
-               if ( !$user->isAllowed( 'edit' ) ) {
-                       if ( $user->isAnon() ) {
+               if ( !$wgUser->isAllowed( 'edit' ) ) {
+                       if ( $wgUser->isAnon() ) {
                                $status->setResult( false, self::AS_READ_ONLY_PAGE_ANON );
                                return $status;
                        } else {
@@ -1815,7 +1813,7 @@ class EditPage {
                                $status->fatal( 'editpage-cannot-use-custom-model' );
                                $status->value = self::AS_CANNOT_USE_CUSTOM_MODEL;
                                return $status;
-                       } elseif ( !$user->isAllowed( 'editcontentmodel' ) ) {
+                       } elseif ( !$wgUser->isAllowed( 'editcontentmodel' ) ) {
                                $status->setResult( false, self::AS_NO_CHANGE_CONTENT_MODEL );
                                return $status;
 
@@ -1826,7 +1824,7 @@ class EditPage {
 
                if ( $this->changeTags ) {
                        $changeTagsStatus = ChangeTags::canAddTagsAccompanyingChange(
-                               $this->changeTags, $user );
+                               $this->changeTags, $wgUser );
                        if ( !$changeTagsStatus->isOK() ) {
                                $changeTagsStatus->value = self::AS_CHANGE_TAG_ERROR;
                                return $changeTagsStatus;
@@ -1838,7 +1836,7 @@ class EditPage {
                        $status->value = self::AS_READ_ONLY_PAGE;
                        return $status;
                }
-               if ( $user->pingLimiter() || $user->pingLimiter( 'linkpurge', 0 ) ) {
+               if ( $wgUser->pingLimiter() || $wgUser->pingLimiter( 'linkpurge', 0 ) ) {
                        $status->fatal( 'actionthrottledtext' );
                        $status->value = self::AS_RATE_LIMITED;
                        return $status;
@@ -1858,7 +1856,7 @@ class EditPage {
 
                if ( $new ) {
                        // Late check for create permission, just in case *PARANOIA*
-                       if ( !$this->mTitle->userCan( 'create', $user ) ) {
+                       if ( !$this->mTitle->userCan( 'create', $wgUser ) ) {
                                $status->fatal( 'nocreatetext' );
                                $status->value = self::AS_NO_CREATE_PERMISSION;
                                wfDebug( __METHOD__ . ": no create permission\n" );
@@ -1882,7 +1880,7 @@ class EditPage {
                                return $status;
                        }
 
-                       if ( !$this->runPostMergeFilters( $textbox_content, $status, $user ) ) {
+                       if ( !$this->runPostMergeFilters( $textbox_content, $status, $wgUser ) ) {
                                return $status;
                        }
 
@@ -1918,7 +1916,7 @@ class EditPage {
                        ) {
                                $this->isConflict = true;
                                if ( $this->section == 'new' ) {
-                                       if ( $this->page->getUserText() == $user->getName() &&
+                                       if ( $this->page->getUserText() == $wgUser->getName() &&
                                                $this->page->getComment() == $this->newSectionSummary()
                                        ) {
                                                // Probably a duplicate submission of a new comment.
@@ -1934,7 +1932,7 @@ class EditPage {
                                } elseif ( $this->section == ''
                                        && Revision::userWasLastToEdit(
                                                DB_MASTER, $this->mTitle->getArticleID(),
-                                               $user->getId(), $this->edittime
+                                               $wgUser->getId(), $this->edittime
                                        )
                                ) {
                                        # Suppress edit conflict with self, except for section edits where merging is required.
@@ -2004,7 +2002,7 @@ class EditPage {
                                return $status;
                        }
 
-                       if ( !$this->runPostMergeFilters( $content, $status, $user ) ) {
+                       if ( !$this->runPostMergeFilters( $content, $status, $wgUser ) ) {
                                return $status;
                        }
 
@@ -2025,7 +2023,7 @@ class EditPage {
                                        return $status;
                                }
                        } elseif ( !$this->allowBlankSummary
-                               && !$content->equals( $this->getOriginalContent( $user ) )
+                               && !$content->equals( $this->getOriginalContent( $wgUser ) )
                                && !$content->isRedirect()
                                && md5( $this->summary ) == $this->autoSumm
                        ) {
@@ -2095,7 +2093,7 @@ class EditPage {
                        $this->summary,
                        $flags,
                        false,
-                       $user,
+                       $wgUser,
                        $content->getDefaultFormat(),
                        $this->changeTags
                );
@@ -2118,7 +2116,7 @@ class EditPage {
                $result['nullEdit'] = $doEditStatus->hasMessage( 'edit-no-change' );
                if ( $result['nullEdit'] ) {
                        // We don't know if it was a null edit until now, so increment here
-                       $user->pingLimiter( 'linkpurge' );
+                       $wgUser->pingLimiter( 'linkpurge' );
                }
                $result['redirect'] = $content->isRedirect();
 
@@ -2127,7 +2125,7 @@ class EditPage {
                // If the content model changed, add a log entry
                if ( $changingContentModel ) {
                        $this->addContentModelChangeLogEntry(
-                               $user,
+                               $wgUser,
                                $new ? false : $oldContentModel,
                                $this->contentModel,
                                $this->summary
@@ -2161,12 +2159,13 @@ class EditPage {
         * Register the change of watch status
         */
        protected function updateWatchlist() {
-               $user = $this->context->getUser();
+               global $wgUser;
 
-               if ( !$user->isLoggedIn() ) {
+               if ( !$wgUser->isLoggedIn() ) {
                        return;
                }
 
+               $user = $wgUser;
                $title = $this->mTitle;
                $watch = $this->watchthis;
                // Do this in its own transaction to reduce contention...
@@ -2281,32 +2280,29 @@ class EditPage {
        }
 
        function setHeaders() {
-               global $wgAjaxEditStash;
-
-               $out = $this->context->getOutput();
-               $user = $this->context->getUser();
+               global $wgOut, $wgUser, $wgAjaxEditStash;
 
-               $out->addModules( 'mediawiki.action.edit' );
-               $out->addModuleStyles( 'mediawiki.action.edit.styles' );
+               $wgOut->addModules( 'mediawiki.action.edit' );
+               $wgOut->addModuleStyles( 'mediawiki.action.edit.styles' );
 
-               if ( $user->getOption( 'showtoolbar' ) ) {
+               if ( $wgUser->getOption( 'showtoolbar' ) ) {
                        // The addition of default buttons is handled by getEditToolbar() which
                        // has its own dependency on this module. The call here ensures the module
                        // is loaded in time (it has position "top") for other modules to register
                        // buttons (e.g. extensions, gadgets, user scripts).
-                       $out->addModules( 'mediawiki.toolbar' );
+                       $wgOut->addModules( 'mediawiki.toolbar' );
                }
 
-               if ( $user->getOption( 'uselivepreview' ) ) {
-                       $out->addModules( 'mediawiki.action.edit.preview' );
+               if ( $wgUser->getOption( 'uselivepreview' ) ) {
+                       $wgOut->addModules( 'mediawiki.action.edit.preview' );
                }
 
-               if ( $user->getOption( 'useeditwarning' ) ) {
-                       $out->addModules( 'mediawiki.action.edit.editWarning' );
+               if ( $wgUser->getOption( 'useeditwarning' ) ) {
+                       $wgOut->addModules( 'mediawiki.action.edit.editWarning' );
                }
 
                # Enabled article-related sidebar, toplinks, etc.
-               $out->setArticleRelated( true );
+               $wgOut->setArticleRelated( true );
 
                $contextTitle = $this->getContextTitle();
                if ( $this->isConflict ) {
@@ -2329,10 +2325,10 @@ class EditPage {
                if ( $displayTitle === false ) {
                        $displayTitle = $contextTitle->getPrefixedText();
                }
-               $out->setPageTitle( wfMessage( $msg, $displayTitle ) );
+               $wgOut->setPageTitle( wfMessage( $msg, $displayTitle ) );
                # Transmit the name of the message to JavaScript for live preview
                # Keep Resources.php/mediawiki.action.edit.preview in sync with the possible keys
-               $out->addJsConfigVars( [
+               $wgOut->addJsConfigVars( [
                        'wgEditMessage' => $msg,
                        'wgAjaxEditStash' => $wgAjaxEditStash,
                ] );
@@ -2342,16 +2338,16 @@ class EditPage {
         * Show all applicable editing introductions
         */
        protected function showIntro() {
+               global $wgOut, $wgUser;
                if ( $this->suppressIntro ) {
                        return;
                }
 
-               $out = $this->context->getOutput();
                $namespace = $this->mTitle->getNamespace();
 
                if ( $namespace == NS_MEDIAWIKI ) {
                        # Show a warning if editing an interface message
-                       $out->wrapWikiMsg( "<div class='mw-editinginterface'>\n$1\n</div>", 'editinginterface' );
+                       $wgOut->wrapWikiMsg( "<div class='mw-editinginterface'>\n$1\n</div>", 'editinginterface' );
                        # If this is a default message (but not css or js),
                        # show a hint that it is translatable on translatewiki.net
                        if ( !$this->mTitle->hasContentModel( CONTENT_MODEL_CSS )
@@ -2359,7 +2355,7 @@ class EditPage {
                        ) {
                                $defaultMessageText = $this->mTitle->getDefaultMessageText();
                                if ( $defaultMessageText !== false ) {
-                                       $out->wrapWikiMsg( "<div class='mw-translateinterface'>\n$1\n</div>",
+                                       $wgOut->wrapWikiMsg( "<div class='mw-translateinterface'>\n$1\n</div>",
                                                'translateinterface' );
                                }
                        }
@@ -2371,11 +2367,11 @@ class EditPage {
                                # there must be a description url to show a hint to shared repo
                                if ( $descUrl ) {
                                        if ( !$this->mTitle->exists() ) {
-                                               $out->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-create\">\n$1\n</div>", [
+                                               $wgOut->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-create\">\n$1\n</div>", [
                                                                        'sharedupload-desc-create', $file->getRepo()->getDisplayName(), $descUrl
                                                ] );
                                        } else {
-                                               $out->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-edit\">\n$1\n</div>", [
+                                               $wgOut->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-edit\">\n$1\n</div>", [
                                                                        'sharedupload-desc-edit', $file->getRepo()->getDisplayName(), $descUrl
                                                ] );
                                        }
@@ -2391,12 +2387,12 @@ class EditPage {
                        $ip = User::isIP( $username );
                        $block = Block::newFromTarget( $user, $user );
                        if ( !( $user && $user->isLoggedIn() ) && !$ip ) { # User does not exist
-                               $out->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n$1\n</div>",
+                               $wgOut->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n$1\n</div>",
                                        [ 'userpage-userdoesnotexist', wfEscapeWikiText( $username ) ] );
                        } elseif ( !is_null( $block ) && $block->getType() != Block::TYPE_AUTO ) {
                                # Show log extract if the user is currently blocked
                                LogEventsList::showLogExtract(
-                                       $out,
+                                       $wgOut,
                                        'block',
                                        MWNamespace::getCanonicalName( NS_USER ) . ':' . $block->getTarget(),
                                        '',
@@ -2416,8 +2412,8 @@ class EditPage {
                        $helpLink = wfExpandUrl( Skin::makeInternalOrExternalUrl(
                                wfMessage( 'helppage' )->inContentLanguage()->text()
                        ) );
-                       if ( $this->context->getUser()->isLoggedIn() ) {
-                               $out->wrapWikiMsg(
+                       if ( $wgUser->isLoggedIn() ) {
+                               $wgOut->wrapWikiMsg(
                                        // Suppress the external link icon, consider the help url an internal one
                                        "<div class=\"mw-newarticletext plainlinks\">\n$1\n</div>",
                                        [
@@ -2426,7 +2422,7 @@ class EditPage {
                                        ]
                                );
                        } else {
-                               $out->wrapWikiMsg(
+                               $wgOut->wrapWikiMsg(
                                        // Suppress the external link icon, consider the help url an internal one
                                        "<div class=\"mw-newarticletextanon plainlinks\">\n$1\n</div>",
                                        [
@@ -2438,7 +2434,7 @@ class EditPage {
                }
                # Give a notice if the user is editing a deleted/moved page...
                if ( !$this->mTitle->exists() ) {
-                       LogEventsList::showLogExtract( $out, [ 'delete', 'move' ], $this->mTitle,
+                       LogEventsList::showLogExtract( $wgOut, [ 'delete', 'move' ], $this->mTitle,
                                '',
                                [
                                        'lim' => 10,
@@ -2459,8 +2455,9 @@ class EditPage {
                if ( $this->editintro ) {
                        $title = Title::newFromText( $this->editintro );
                        if ( $title instanceof Title && $title->exists() && $title->userCan( 'read' ) ) {
+                               global $wgOut;
                                // Added using template syntax, to take <noinclude>'s into account.
-                               $this->context->getOutput()->addWikiTextTitleTidy(
+                               $wgOut->addWikiTextTitleTidy(
                                        '<div class="mw-editintro">{{:' . $title->getFullText() . '}}</div>',
                                        $this->mTitle
                                );
@@ -2540,6 +2537,8 @@ class EditPage {
         * use the EditPage::showEditForm:fields hook instead.
         */
        function showEditForm( $formCallback = null ) {
+               global $wgOut, $wgUser;
+
                # need to parse the preview early so that we know which templates are used,
                # otherwise users with "show preview after edit box" will get a blank list
                # we parse this near the beginning so that setHeaders can do the title
@@ -2549,8 +2548,7 @@ class EditPage {
                        $previewOutput = $this->getPreviewText();
                }
 
-               $out = $this->context->getOutput();
-               Hooks::run( 'EditPage::showEditForm:initial', [ &$this, &$out ] );
+               Hooks::run( 'EditPage::showEditForm:initial', [ &$this, &$wgOut ] );
 
                $this->setHeaders();
 
@@ -2558,14 +2556,13 @@ class EditPage {
                        return;
                }
 
-               $out->addHTML( $this->editFormPageTop );
+               $wgOut->addHTML( $this->editFormPageTop );
 
-               $user = $this->context->getUser();
-               if ( $user->getOption( 'previewontop' ) ) {
+               if ( $wgUser->getOption( 'previewontop' ) ) {
                        $this->displayPreviewArea( $previewOutput, true );
                }
 
-               $out->addHTML( $this->editFormTextTop );
+               $wgOut->addHTML( $this->editFormTextTop );
 
                $showToolbar = true;
                if ( $this->wasDeletedSinceLastEdit() ) {
@@ -2574,14 +2571,14 @@ class EditPage {
                                // Add an confirmation checkbox and explanation.
                                $showToolbar = false;
                        } else {
-                               $out->wrapWikiMsg( "<div class='error mw-deleted-while-editing'>\n$1\n</div>",
+                               $wgOut->wrapWikiMsg( "<div class='error mw-deleted-while-editing'>\n$1\n</div>",
                                        'deletedwhileediting' );
                        }
                }
 
                // @todo add EditForm plugin interface and use it here!
                //       search for textarea1 and textares2, and allow EditForm to override all uses.
-               $out->addHTML( Html::openElement(
+               $wgOut->addHTML( Html::openElement(
                        'form',
                        [
                                'id' => self::EDITFORM_ID,
@@ -2594,11 +2591,11 @@ class EditPage {
 
                if ( is_callable( $formCallback ) ) {
                        wfWarn( 'The $formCallback parameter to ' . __METHOD__ . 'is deprecated' );
-                       call_user_func_array( $formCallback, [ &$out ] );
+                       call_user_func_array( $formCallback, [ &$wgOut ] );
                }
 
                // Add an empty field to trip up spambots
-               $out->addHTML(
+               $wgOut->addHTML(
                        Xml::openElement( 'div', [ 'id' => 'antispam-container', 'style' => 'display: none;' ] )
                        . Html::rawElement(
                                'label',
@@ -2617,7 +2614,7 @@ class EditPage {
                        . Xml::closeElement( 'div' )
                );
 
-               Hooks::run( 'EditPage::showEditForm:fields', [ &$this, &$out ] );
+               Hooks::run( 'EditPage::showEditForm:fields', [ &$this, &$wgOut ] );
 
                // Put these up at the top to ensure they aren't lost on early form submission
                $this->showFormBeforeText();
@@ -2631,7 +2628,7 @@ class EditPage {
                        $key = $comment === ''
                                ? 'confirmrecreate-noreason'
                                : 'confirmrecreate';
-                       $out->addHTML(
+                       $wgOut->addHTML(
                                '<div class="mw-confirm-recreate">' .
                                        wfMessage( $key, $username, "<nowiki>$comment</nowiki>" )->parse() .
                                Xml::checkLabel( wfMessage( 'recreate' )->text(), 'wpRecreate', 'wpRecreate', false,
@@ -2643,7 +2640,7 @@ class EditPage {
 
                # When the summary is hidden, also hide them on preview/show changes
                if ( $this->nosummary ) {
-                       $out->addHTML( Html::hidden( 'nosummary', true ) );
+                       $wgOut->addHTML( Html::hidden( 'nosummary', true ) );
                }
 
                # If a blank edit summary was previously provided, and the appropriate
@@ -2654,15 +2651,15 @@ class EditPage {
                # For a bit more sophisticated detection of blank summaries, hash the
                # automatic one and pass that in the hidden field wpAutoSummary.
                if ( $this->missingSummary || ( $this->section == 'new' && $this->nosummary ) ) {
-                       $out->addHTML( Html::hidden( 'wpIgnoreBlankSummary', true ) );
+                       $wgOut->addHTML( Html::hidden( 'wpIgnoreBlankSummary', true ) );
                }
 
                if ( $this->undidRev ) {
-                       $out->addHTML( Html::hidden( 'wpUndidRevision', $this->undidRev ) );
+                       $wgOut->addHTML( Html::hidden( 'wpUndidRevision', $this->undidRev ) );
                }
 
                if ( $this->selfRedirect ) {
-                       $out->addHTML( Html::hidden( 'wpIgnoreSelfRedirect', true ) );
+                       $wgOut->addHTML( Html::hidden( 'wpIgnoreSelfRedirect', true ) );
                }
 
                if ( $this->hasPresetSummary ) {
@@ -2673,27 +2670,27 @@ class EditPage {
                }
 
                $autosumm = $this->autoSumm ? $this->autoSumm : md5( $this->summary );
-               $out->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) );
+               $wgOut->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) );
 
-               $out->addHTML( Html::hidden( 'oldid', $this->oldid ) );
-               $out->addHTML( Html::hidden( 'parentRevId', $this->getParentRevId() ) );
+               $wgOut->addHTML( Html::hidden( 'oldid', $this->oldid ) );
+               $wgOut->addHTML( Html::hidden( 'parentRevId', $this->getParentRevId() ) );
 
-               $out->addHTML( Html::hidden( 'format', $this->contentFormat ) );
-               $out->addHTML( Html::hidden( 'model', $this->contentModel ) );
+               $wgOut->addHTML( Html::hidden( 'format', $this->contentFormat ) );
+               $wgOut->addHTML( Html::hidden( 'model', $this->contentModel ) );
 
                if ( $this->section == 'new' ) {
                        $this->showSummaryInput( true, $this->summary );
-                       $out->addHTML( $this->getSummaryPreview( true, $this->summary ) );
+                       $wgOut->addHTML( $this->getSummaryPreview( true, $this->summary ) );
                }
 
-               $out->addHTML( $this->editFormTextBeforeContent );
+               $wgOut->addHTML( $this->editFormTextBeforeContent );
 
-               if ( !$this->isCssJsSubpage && $showToolbar && $user->getOption( 'showtoolbar' ) ) {
-                       $out->addHTML( EditPage::getEditToolbar( $this->mTitle ) );
+               if ( !$this->isCssJsSubpage && $showToolbar && $wgUser->getOption( 'showtoolbar' ) ) {
+                       $wgOut->addHTML( EditPage::getEditToolbar( $this->mTitle ) );
                }
 
                if ( $this->blankArticle ) {
-                       $out->addHTML( Html::hidden( 'wpIgnoreBlankArticle', true ) );
+                       $wgOut->addHTML( Html::hidden( 'wpIgnoreBlankArticle', true ) );
                }
 
                if ( $this->isConflict ) {
@@ -2711,7 +2708,7 @@ class EditPage {
                        $this->showContentForm();
                }
 
-               $out->addHTML( $this->editFormTextAfterContent );
+               $wgOut->addHTML( $this->editFormTextAfterContent );
 
                $this->showStandardInputs();
 
@@ -2721,19 +2718,19 @@ class EditPage {
 
                $this->showEditTools();
 
-               $out->addHTML( $this->editFormTextAfterTools . "\n" );
+               $wgOut->addHTML( $this->editFormTextAfterTools . "\n" );
 
-               $out->addHTML( Html::rawElement( 'div', [ 'class' => 'templatesUsed' ],
+               $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'templatesUsed' ],
                        Linker::formatTemplates( $this->getTemplates(), $this->preview, $this->section != '' ) ) );
 
-               $out->addHTML( Html::rawElement( 'div', [ 'class' => 'hiddencats' ],
+               $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'hiddencats' ],
                        Linker::formatHiddenCategories( $this->page->getHiddenCategories() ) ) );
 
                if ( $this->mParserOutput ) {
-                       $out->setLimitReportData( $this->mParserOutput->getLimitReportData() );
+                       $wgOut->setLimitReportData( $this->mParserOutput->getLimitReportData() );
                }
 
-               $out->addModules( 'mediawiki.action.edit.collapsibleFooter' );
+               $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' );
 
                if ( $this->isConflict ) {
                        try {
@@ -2746,7 +2743,7 @@ class EditPage {
                                        $this->contentFormat,
                                        $ex->getMessage()
                                );
-                               $out->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
+                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
 
@@ -2760,14 +2757,14 @@ class EditPage {
                } else {
                        $mode = 'text';
                }
-               $out->addHTML( Html::hidden( 'mode', $mode, [ 'id' => 'mw-edit-mode' ] ) );
+               $wgOut->addHTML( Html::hidden( 'mode', $mode, [ 'id' => 'mw-edit-mode' ] ) );
 
                // Marker for detecting truncated form data.  This must be the last
                // parameter sent in order to be of use, so do not move me.
-               $out->addHTML( Html::hidden( 'wpUltimateParam', true ) );
-               $out->addHTML( $this->editFormTextBottom . "\n</form>\n" );
+               $wgOut->addHTML( Html::hidden( 'wpUltimateParam', true ) );
+               $wgOut->addHTML( $this->editFormTextBottom . "\n</form>\n" );
 
-               if ( !$user->getOption( 'previewontop' ) ) {
+               if ( !$wgUser->getOption( 'previewontop' ) ) {
                        $this->displayPreviewArea( $previewOutput, false );
                }
 
@@ -2793,23 +2790,21 @@ class EditPage {
         * @return bool
         */
        protected function showHeader() {
-               global $wgMaxArticleSize, $wgAllowUserCss, $wgAllowUserJs;
-
-               $out = $this->context->getOutput();
-               $user = $this->context->getUser();
+               global $wgOut, $wgUser, $wgMaxArticleSize, $wgLang;
+               global $wgAllowUserCss, $wgAllowUserJs;
 
                if ( $this->mTitle->isTalkPage() ) {
-                       $out->addWikiMsg( 'talkpagetext' );
+                       $wgOut->addWikiMsg( 'talkpagetext' );
                }
 
                // Add edit notices
                $editNotices = $this->mTitle->getEditNotices( $this->oldid );
                if ( count( $editNotices ) ) {
-                       $out->addHTML( implode( "\n", $editNotices ) );
+                       $wgOut->addHTML( implode( "\n", $editNotices ) );
                } else {
                        $msg = wfMessage( 'editnotice-notext' );
                        if ( !$msg->isDisabled() ) {
-                               $out->addHTML(
+                               $wgOut->addHTML(
                                        '<div class="mw-editnotice-notext">'
                                        . $msg->parseAsBlock()
                                        . '</div>'
@@ -2818,14 +2813,14 @@ class EditPage {
                }
 
                if ( $this->isConflict ) {
-                       $out->wrapWikiMsg( "<div class='mw-explainconflict'>\n$1\n</div>", 'explainconflict' );
+                       $wgOut->wrapWikiMsg( "<div class='mw-explainconflict'>\n$1\n</div>", 'explainconflict' );
                        $this->editRevId = $this->page->getLatest();
                } else {
                        if ( $this->section != '' && !$this->isSectionEditSupported() ) {
                                // We use $this->section to much before this and getVal('wgSection') directly in other places
                                // at this point we can't reset $this->section to '' to fallback to non-section editing.
                                // Someone is welcome to try refactoring though
-                               $out->showErrorPage( 'sectioneditnotsupported-title', 'sectioneditnotsupported-text' );
+                               $wgOut->showErrorPage( 'sectioneditnotsupported-title', 'sectioneditnotsupported-text' );
                                return false;
                        }
 
@@ -2839,31 +2834,31 @@ class EditPage {
                        }
 
                        if ( $this->missingComment ) {
-                               $out->wrapWikiMsg( "<div id='mw-missingcommenttext'>\n$1\n</div>", 'missingcommenttext' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-missingcommenttext'>\n$1\n</div>", 'missingcommenttext' );
                        }
 
                        if ( $this->missingSummary && $this->section != 'new' ) {
-                               $out->wrapWikiMsg( "<div id='mw-missingsummary'>\n$1\n</div>", 'missingsummary' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-missingsummary'>\n$1\n</div>", 'missingsummary' );
                        }
 
                        if ( $this->missingSummary && $this->section == 'new' ) {
-                               $out->wrapWikiMsg( "<div id='mw-missingcommentheader'>\n$1\n</div>", 'missingcommentheader' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-missingcommentheader'>\n$1\n</div>", 'missingcommentheader' );
                        }
 
                        if ( $this->blankArticle ) {
-                               $out->wrapWikiMsg( "<div id='mw-blankarticle'>\n$1\n</div>", 'blankarticle' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-blankarticle'>\n$1\n</div>", 'blankarticle' );
                        }
 
                        if ( $this->selfRedirect ) {
-                               $out->wrapWikiMsg( "<div id='mw-selfredirect'>\n$1\n</div>", 'selfredirect' );
+                               $wgOut->wrapWikiMsg( "<div id='mw-selfredirect'>\n$1\n</div>", 'selfredirect' );
                        }
 
                        if ( $this->hookError !== '' ) {
-                               $out->addWikiText( $this->hookError );
+                               $wgOut->addWikiText( $this->hookError );
                        }
 
                        if ( !$this->checkUnicodeCompliantBrowser() ) {
-                               $out->addWikiMsg( 'nonunicodebrowser' );
+                               $wgOut->addWikiMsg( 'nonunicodebrowser' );
                        }
 
                        if ( $this->section != 'new' ) {
@@ -2871,13 +2866,13 @@ class EditPage {
                                if ( $revision ) {
                                        // Let sysop know that this will make private content public if saved
 
-                                       if ( !$revision->userCan( Revision::DELETED_TEXT, $user ) ) {
-                                               $out->wrapWikiMsg(
+                                       if ( !$revision->userCan( Revision::DELETED_TEXT, $wgUser ) ) {
+                                               $wgOut->wrapWikiMsg(
                                                        "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                                        'rev-deleted-text-permission'
                                                );
                                        } elseif ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
-                                               $out->wrapWikiMsg(
+                                               $wgOut->wrapWikiMsg(
                                                        "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                                        'rev-deleted-text-view'
                                                );
@@ -2885,25 +2880,25 @@ class EditPage {
 
                                        if ( !$revision->isCurrent() ) {
                                                $this->mArticle->setOldSubtitle( $revision->getId() );
-                                               $out->addWikiMsg( 'editingold' );
+                                               $wgOut->addWikiMsg( 'editingold' );
                                        }
                                } elseif ( $this->mTitle->exists() ) {
                                        // Something went wrong
 
-                                       $out->wrapWikiMsg( "<div class='errorbox'>\n$1\n</div>\n",
+                                       $wgOut->wrapWikiMsg( "<div class='errorbox'>\n$1\n</div>\n",
                                                [ 'missing-revision', $this->oldid ] );
                                }
                        }
                }
 
                if ( wfReadOnly() ) {
-                       $out->wrapWikiMsg(
+                       $wgOut->wrapWikiMsg(
                                "<div id=\"mw-read-only-warning\">\n$1\n</div>",
                                [ 'readonlywarning', wfReadOnlyReason() ]
                        );
-               } elseif ( $user->isAnon() ) {
+               } elseif ( $wgUser->isAnon() ) {
                        if ( $this->formtype != 'preview' ) {
-                               $out->wrapWikiMsg(
+                               $wgOut->wrapWikiMsg(
                                        "<div id='mw-anon-edit-warning' class='warningbox'>\n$1\n</div>",
                                        [ 'anoneditwarning',
                                                // Log-in link
@@ -2917,7 +2912,7 @@ class EditPage {
                                        ]
                                );
                        } else {
-                               $out->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\" class=\"warningbox\">\n$1</div>",
+                               $wgOut->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\" class=\"warningbox\">\n$1</div>",
                                        'anonpreviewwarning'
                                );
                        }
@@ -2925,25 +2920,25 @@ class EditPage {
                        if ( $this->isCssJsSubpage ) {
                                # Check the skin exists
                                if ( $this->isWrongCaseCssJsPage ) {
-                                       $out->wrapWikiMsg(
+                                       $wgOut->wrapWikiMsg(
                                                "<div class='error' id='mw-userinvalidcssjstitle'>\n$1\n</div>",
                                                [ 'userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage() ]
                                        );
                                }
-                               if ( $this->getTitle()->isSubpageOf( $user->getUserPage() ) ) {
-                                       $out->wrapWikiMsg( '<div class="mw-usercssjspublic">$1</div>',
+                               if ( $this->getTitle()->isSubpageOf( $wgUser->getUserPage() ) ) {
+                                       $wgOut->wrapWikiMsg( '<div class="mw-usercssjspublic">$1</div>',
                                                $this->isCssSubpage ? 'usercssispublic' : 'userjsispublic'
                                        );
                                        if ( $this->formtype !== 'preview' ) {
                                                if ( $this->isCssSubpage && $wgAllowUserCss ) {
-                                                       $out->wrapWikiMsg(
+                                                       $wgOut->wrapWikiMsg(
                                                                "<div id='mw-usercssyoucanpreview'>\n$1\n</div>",
                                                                [ 'usercssyoucanpreview' ]
                                                        );
                                                }
 
                                                if ( $this->isJsSubpage && $wgAllowUserJs ) {
-                                                       $out->wrapWikiMsg(
+                                                       $wgOut->wrapWikiMsg(
                                                                "<div id='mw-userjsyoucanpreview'>\n$1\n</div>",
                                                                [ 'userjsyoucanpreview' ]
                                                        );
@@ -2963,7 +2958,7 @@ class EditPage {
                                # Then it must be protected based on static groups (regular)
                                $noticeMsg = 'protectedpagewarning';
                        }
-                       LogEventsList::showLogExtract( $out, 'protect', $this->mTitle, '',
+                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
                                [ 'lim' => 1, 'msgKey' => [ $noticeMsg ] ] );
                }
                if ( $this->mTitle->isCascadeProtected() ) {
@@ -2979,10 +2974,10 @@ class EditPage {
                                }
                        }
                        $notice .= '</div>';
-                       $out->wrapWikiMsg( $notice, [ 'cascadeprotectedwarning', $cascadeSourcesCount ] );
+                       $wgOut->wrapWikiMsg( $notice, [ 'cascadeprotectedwarning', $cascadeSourcesCount ] );
                }
                if ( !$this->mTitle->exists() && $this->mTitle->getRestrictions( 'create' ) ) {
-                       LogEventsList::showLogExtract( $out, 'protect', $this->mTitle, '',
+                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
                                [ 'lim' => 1,
                                        'showIfEmpty' => false,
                                        'msgKey' => [ 'titleprotectedwarning' ],
@@ -2993,21 +2988,20 @@ class EditPage {
                        $this->contentLength = strlen( $this->textbox1 );
                }
 
-               $lang = $this->context->getLanguage();
                if ( $this->tooBig || $this->contentLength > $wgMaxArticleSize * 1024 ) {
-                       $out->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
+                       $wgOut->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
                                [
                                        'longpageerror',
-                                       $lang->formatNum( round( $this->contentLength / 1024, 3 ) ),
-                                       $lang->formatNum( $wgMaxArticleSize )
+                                       $wgLang->formatNum( round( $this->contentLength / 1024, 3 ) ),
+                                       $wgLang->formatNum( $wgMaxArticleSize )
                                ]
                        );
                } else {
                        if ( !wfMessage( 'longpage-hint' )->isDisabled() ) {
-                               $out->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
+                               $wgOut->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
                                        [
                                                'longpage-hint',
-                                               $lang->formatSize( strlen( $this->textbox1 ) ),
+                                               $wgLang->formatSize( strlen( $this->textbox1 ) ),
                                                strlen( $this->textbox1 )
                                        ]
                                );
@@ -3072,6 +3066,7 @@ class EditPage {
         * @param string $summary The text of the summary to display
         */
        protected function showSummaryInput( $isSubjectPreview, $summary = "" ) {
+               global $wgOut;
                # Add a class if 'missingsummary' is triggered to allow styling of the summary line
                $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
                if ( $isSubjectPreview ) {
@@ -3090,7 +3085,7 @@ class EditPage {
                        [ 'class' => $summaryClass ],
                        []
                );
-               $this->context->getOutput()->addHTML( "{$label} {$input}" );
+               $wgOut->addHTML( "{$label} {$input}" );
        }
 
        /**
@@ -3122,9 +3117,9 @@ class EditPage {
        }
 
        protected function showFormBeforeText() {
+               global $wgOut;
                $section = htmlspecialchars( $this->section );
-               $out = $this->context->getOutput();
-               $out->addHTML( <<<HTML
+               $wgOut->addHTML( <<<HTML
 <input type='hidden' value="{$section}" name="wpSection"/>
 <input type='hidden' value="{$this->starttime}" name="wpStarttime" />
 <input type='hidden' value="{$this->edittime}" name="wpEdittime" />
@@ -3134,11 +3129,12 @@ class EditPage {
 HTML
                );
                if ( !$this->checkUnicodeCompliantBrowser() ) {
-                       $out->addHTML( Html::hidden( 'safemode', '1' ) );
+                       $wgOut->addHTML( Html::hidden( 'safemode', '1' ) );
                }
        }
 
        protected function showFormAfterText() {
+               global $wgOut, $wgUser;
                /**
                 * To make it harder for someone to slip a user a page
                 * which submits an edit form to the wiki without their
@@ -3151,10 +3147,7 @@ HTML
                 * include the constant suffix to prevent editing from
                 * broken text-mangling proxies.
                 */
-               $token = $this->context->getUser()->getEditToken();
-               $this->context->getOutput()->addHTML(
-                       "\n" . Html::hidden( "wpEditToken", $token ) . "\n"
-               );
+               $wgOut->addHTML( "\n" . Html::hidden( "wpEditToken", $wgUser->getEditToken() ) . "\n" );
        }
 
        /**
@@ -3224,6 +3217,8 @@ HTML
        }
 
        protected function showTextbox( $text, $name, $customAttribs = [] ) {
+               global $wgOut, $wgUser;
+
                $wikitext = $this->safeUnicodeOutput( $text );
                if ( strval( $wikitext ) !== '' ) {
                        // Ensure there's a newline at the end, otherwise adding lines
@@ -3233,12 +3228,11 @@ HTML
                        $wikitext .= "\n";
                }
 
-               $user = $this->context->getUser();
                $attribs = $customAttribs + [
                        'accesskey' => ',',
                        'id' => $name,
-                       'cols' => $user->getIntOption( 'cols' ),
-                       'rows' => $user->getIntOption( 'rows' ),
+                       'cols' => $wgUser->getIntOption( 'cols' ),
+                       'rows' => $wgUser->getIntOption( 'rows' ),
                        // Avoid PHP notices when appending preferences
                        // (appending allows customAttribs['style'] to still work).
                        'style' => ''
@@ -3248,10 +3242,11 @@ HTML
                $attribs['lang'] = $pageLang->getHtmlCode();
                $attribs['dir'] = $pageLang->getDir();
 
-               $this->context->getOutput()->addHTML( Html::textarea( $name, $wikitext, $attribs ) );
+               $wgOut->addHTML( Html::textarea( $name, $wikitext, $attribs ) );
        }
 
        protected function displayPreviewArea( $previewOutput, $isOnTop = false ) {
+               global $wgOut;
                $classes = [];
                if ( $isOnTop ) {
                        $classes[] = 'ontop';
@@ -3263,8 +3258,7 @@ HTML
                        $attribs['style'] = 'display: none;';
                }
 
-               $out = $this->context->getOutput();
-               $out->addHTML( Xml::openElement( 'div', $attribs ) );
+               $wgOut->addHTML( Xml::openElement( 'div', $attribs ) );
 
                if ( $this->formtype == 'preview' ) {
                        $this->showPreview( $previewOutput );
@@ -3273,10 +3267,10 @@ HTML
                        $pageViewLang = $this->mTitle->getPageViewLanguage();
                        $attribs = [ 'lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(),
                                'class' => 'mw-content-' . $pageViewLang->getDir() ];
-                       $out->addHTML( Html::rawElement( 'div', $attribs ) );
+                       $wgOut->addHTML( Html::rawElement( 'div', $attribs ) );
                }
 
-               $out->addHTML( '</div>' );
+               $wgOut->addHTML( '</div>' );
 
                if ( $this->formtype == 'diff' ) {
                        try {
@@ -3288,7 +3282,7 @@ HTML
                                        $this->contentFormat,
                                        $ex->getMessage()
                                );
-                               $out->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
+                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
        }
@@ -3300,14 +3294,14 @@ HTML
         * @param string $text The HTML to be output for the preview.
         */
        protected function showPreview( $text ) {
+               global $wgOut;
                if ( $this->mTitle->getNamespace() == NS_CATEGORY ) {
                        $this->mArticle->openShowCategory();
                }
-               $out = $this->context->getOutput();
                # This hook seems slightly odd here, but makes things more
                # consistent for extensions.
-               Hooks::run( 'OutputPageBeforeHTML', [ &$out, &$text ] );
-               $out->addHTML( $text );
+               Hooks::run( 'OutputPageBeforeHTML', [ &$wgOut, &$text ] );
+               $wgOut->addHTML( $text );
                if ( $this->mTitle->getNamespace() == NS_CATEGORY ) {
                        $this->mArticle->closeShowCategory();
                }
@@ -3321,7 +3315,7 @@ HTML
         * save and then make a comparison.
         */
        function showDiff() {
-               global $wgContLang;
+               global $wgUser, $wgContLang, $wgOut;
 
                $oldtitlemsg = 'currentrev';
                # if message does not exist, show diff against the preloaded default
@@ -3352,9 +3346,8 @@ HTML
                        ContentHandler::runLegacyHooks( 'EditPageGetDiffText', [ $this, &$newContent ] );
                        Hooks::run( 'EditPageGetDiffContent', [ $this, &$newContent ] );
 
-                       $user = $this->context->getUser();
-                       $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang );
-                       $newContent = $newContent->preSaveTransform( $this->mTitle, $user, $popts );
+                       $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
+                       $newContent = $newContent->preSaveTransform( $this->mTitle, $wgUser, $popts );
                }
 
                if ( ( $oldContent && !$oldContent->isEmpty() ) || ( $newContent && !$newContent->isEmpty() ) ) {
@@ -3378,7 +3371,7 @@ HTML
                        $difftext = '';
                }
 
-               $this->context->getOutput()->addHTML( '<div id="wikiDiff">' . $difftext . '</div>' );
+               $wgOut->addHTML( '<div id="wikiDiff">' . $difftext . '</div>' );
        }
 
        /**
@@ -3387,7 +3380,8 @@ HTML
        protected function showHeaderCopyrightWarning() {
                $msg = 'editpage-head-copy-warn';
                if ( !wfMessage( $msg )->isDisabled() ) {
-                       $this->context->getOutput()->wrapWikiMsg( "<div class='editpage-head-copywarn'>\n$1\n</div>",
+                       global $wgOut;
+                       $wgOut->wrapWikiMsg( "<div class='editpage-head-copywarn'>\n$1\n</div>",
                                'editpage-head-copy-warn' );
                }
        }
@@ -3404,15 +3398,16 @@ HTML
                $msg = 'editpage-tos-summary';
                Hooks::run( 'EditPageTosSummary', [ $this->mTitle, &$msg ] );
                if ( !wfMessage( $msg )->isDisabled() ) {
-                       $out = $this->context->getOutput();
-                       $out->addHTML( '<div class="mw-tos-summary">' );
-                       $out->addWikiMsg( $msg );
-                       $out->addHTML( '</div>' );
+                       global $wgOut;
+                       $wgOut->addHTML( '<div class="mw-tos-summary">' );
+                       $wgOut->addWikiMsg( $msg );
+                       $wgOut->addHTML( '</div>' );
                }
        }
 
        protected function showEditTools() {
-               $this->context->getOutput()->addHTML( '<div class="mw-editTools">' .
+               global $wgOut;
+               $wgOut->addHTML( '<div class="mw-editTools">' .
                        wfMessage( 'edittools' )->inContentLanguage()->parse() .
                        '</div>' );
        }
@@ -3472,24 +3467,24 @@ HTML
        }
 
        protected function showStandardInputs( &$tabindex = 2 ) {
-               $out = $this->context->getOutput();
-               $out->addHTML( "<div class='editOptions'>\n" );
+               global $wgOut;
+               $wgOut->addHTML( "<div class='editOptions'>\n" );
 
                if ( $this->section != 'new' ) {
                        $this->showSummaryInput( false, $this->summary );
-                       $out->addHTML( $this->getSummaryPreview( false, $this->summary ) );
+                       $wgOut->addHTML( $this->getSummaryPreview( false, $this->summary ) );
                }
 
                $checkboxes = $this->getCheckboxes( $tabindex,
                        [ 'minor' => $this->minoredit, 'watch' => $this->watchthis ] );
-               $out->addHTML( "<div class='editCheckboxes'>" . implode( $checkboxes, "\n" ) . "</div>\n" );
+               $wgOut->addHTML( "<div class='editCheckboxes'>" . implode( $checkboxes, "\n" ) . "</div>\n" );
 
                // Show copyright warning.
-               $out->addWikiText( $this->getCopywarn() );
-               $out->addHTML( $this->editFormTextAfterWarn );
+               $wgOut->addWikiText( $this->getCopywarn() );
+               $wgOut->addHTML( $this->editFormTextAfterWarn );
 
-               $out->addHTML( "<div class='editButtons'>\n" );
-               $out->addHTML( implode( $this->getEditButtons( $tabindex ), "\n" ) . "\n" );
+               $wgOut->addHTML( "<div class='editButtons'>\n" );
+               $wgOut->addHTML( implode( $this->getEditButtons( $tabindex ), "\n" ) . "\n" );
 
                $cancel = $this->getCancelLink();
                if ( $cancel !== '' ) {
@@ -3509,13 +3504,13 @@ HTML
                        wfMessage( 'word-separator' )->escaped() .
                        wfMessage( 'newwindow' )->parse();
 
-               $out->addHTML( "        <span class='cancelLink'>{$cancel}</span>\n" );
-               $out->addHTML( "        <span class='editHelp'>{$edithelp}</span>\n" );
-               $out->addHTML( "</div><!-- editButtons -->\n" );
+               $wgOut->addHTML( "      <span class='cancelLink'>{$cancel}</span>\n" );
+               $wgOut->addHTML( "      <span class='editHelp'>{$edithelp}</span>\n" );
+               $wgOut->addHTML( "</div><!-- editButtons -->\n" );
 
-               Hooks::run( 'EditPage::showStandardInputs:options', [ $this, $out, &$tabindex ] );
+               Hooks::run( 'EditPage::showStandardInputs:options', [ $this, $wgOut, &$tabindex ] );
 
-               $out->addHTML( "</div><!-- editOptions -->\n" );
+               $wgOut->addHTML( "</div><!-- editOptions -->\n" );
        }
 
        /**
@@ -3523,9 +3518,10 @@ HTML
         * If you want to use another entry point to this function, be careful.
         */
        protected function showConflict() {
-               $out = $this->context->getOutput();
-               if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$this, &$out ] ) ) {
-                       $stats = $this->context->getStats();
+               global $wgOut;
+
+               if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$this, &$wgOut ] ) ) {
+                       $stats = $wgOut->getContext()->getStats();
                        $stats->increment( 'edit.failures.conflict' );
                        // Only include 'standard' namespaces to avoid creating unknown numbers of statsd metrics
                        if (
@@ -3535,7 +3531,7 @@ HTML
                                $stats->increment( 'edit.failures.conflict.byNamespaceId.' . $this->mTitle->getNamespace() );
                        }
 
-                       $out->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
+                       $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
 
                        $content1 = $this->toEditContent( $this->textbox1 );
                        $content2 = $this->toEditContent( $this->textbox2 );
@@ -3548,7 +3544,7 @@ HTML
                                wfMessage( 'storedversion' )->text()
                        );
 
-                       $out->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
+                       $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
                        $this->showTextbox2();
                }
        }
@@ -3661,10 +3657,10 @@ HTML
         * @return string
         */
        function getPreviewText() {
-               global $wgRawHtml, $wgAllowUserCss, $wgAllowUserJs;
+               global $wgOut, $wgRawHtml, $wgLang;
+               global $wgAllowUserCss, $wgAllowUserJs;
 
-               $stats = $this->context->getStats();
-               $out = $this->context->getOutput();
+               $stats = $wgOut->getContext()->getStats();
 
                if ( $wgRawHtml && !$this->mTokenOk ) {
                        // Could be an offsite preview attempt. This is very unsafe if
@@ -3674,7 +3670,7 @@ HTML
                                // Do not put big scary notice, if previewing the empty
                                // string, which happens when you initially edit
                                // a category page, due to automatic preview-on-open.
-                               $parsedNote = $out->parse( "<div class='previewnote'>" .
+                               $parsedNote = $wgOut->parse( "<div class='previewnote'>" .
                                        wfMessage( 'session_fail_preview_html' )->text() . "</div>", true, /* interface */true );
                        }
                        $stats->increment( 'edit.failures.session_loss' );
@@ -3696,7 +3692,7 @@ HTML
 
                        # provide a anchor link to the editform
                        $continueEditing = '<span class="mw-continue-editing">' .
-                               '[[#' . self::EDITFORM_ID . '|' . $this->context->getLanguage()->getArrow() . ' ' .
+                               '[[#' . self::EDITFORM_ID . '|' . $wgLang->getArrow() . ' ' .
                                wfMessage( 'continue-editing' )->text() . ']]</span>';
                        if ( $this->mTriedSave && !$this->mTokenOk ) {
                                if ( $this->mTokenOkExceptSuffix ) {
@@ -3762,7 +3758,7 @@ HTML
                        $parserOutput = $parserResult['parserOutput'];
                        $previewHTML = $parserResult['html'];
                        $this->mParserOutput = $parserOutput;
-                       $out->addParserOutputMetadata( $parserOutput );
+                       $wgOut->addParserOutputMetadata( $parserOutput );
 
                        if ( count( $parserOutput->getWarnings() ) ) {
                                $note .= "\n\n" . implode( "\n\n", $parserOutput->getWarnings() );
@@ -3788,7 +3784,7 @@ HTML
 
                $previewhead = "<div class='previewnote'>\n" .
                        '<h2 id="mw-previewheader">' . wfMessage( 'preview' )->escaped() . "</h2>" .
-                       $out->parse( $note, true, /* interface */true ) . $conflict . "</div>\n";
+                       $wgOut->parse( $note, true, /* interface */true ) . $conflict . "</div>\n";
 
                $pageViewLang = $this->mTitle->getPageViewLanguage();
                $attribs = [ 'lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(),
@@ -3803,7 +3799,7 @@ HTML
         * @return ParserOptions
         */
        protected function getPreviewParserOptions() {
-               $parserOptions = $this->page->makeParserOptions( $this->context );
+               $parserOptions = $this->page->makeParserOptions( $this->mArticle->getContext() );
                $parserOptions->setIsPreview( true );
                $parserOptions->setIsSectionPreview( !is_null( $this->section ) && $this->section !== '' );
                $parserOptions->enableLimitReport();
@@ -3820,11 +3816,11 @@ HTML
         *   - html: The HTML to be displayed
         */
        protected function doPreviewParse( Content $content ) {
-               $user = $this->context->getUser();
+               global $wgUser;
                $parserOptions = $this->getPreviewParserOptions();
-               $pstContent = $content->preSaveTransform( $this->mTitle, $user, $parserOptions );
+               $pstContent = $content->preSaveTransform( $this->mTitle, $wgUser, $parserOptions );
                $scopedCallback = $parserOptions->setupFakeRevision(
-                       $this->mTitle, $pstContent, $user );
+                       $this->mTitle, $pstContent, $wgUser );
                $parserOutput = $pstContent->getParserOutput( $this->mTitle, null, $parserOptions );
                ScopedCallback::consume( $scopedCallback );
                $parserOutput->setEditSectionTokens( false ); // no section edit links
@@ -4000,16 +3996,15 @@ HTML
         * @return array
         */
        public function getCheckboxes( &$tabindex, $checked ) {
-               global $wgUseMediaWikiUIEverywhere;
+               global $wgUser, $wgUseMediaWikiUIEverywhere;
 
                $checkboxes = [];
-               $user = $this->context->getUser();
 
                // don't show the minor edit checkbox if it's a new page or section
                if ( !$this->isNew ) {
                        $checkboxes['minor'] = '';
                        $minorLabel = wfMessage( 'minoredit' )->parse();
-                       if ( $user->isAllowed( 'minoredit' ) ) {
+                       if ( $wgUser->isAllowed( 'minoredit' ) ) {
                                $attribs = [
                                        'tabindex' => ++$tabindex,
                                        'accesskey' => wfMessage( 'accesskey-minoredit' )->text(),
@@ -4033,7 +4028,7 @@ HTML
 
                $watchLabel = wfMessage( 'watchthis' )->parse();
                $checkboxes['watch'] = '';
-               if ( $user->isLoggedIn() ) {
+               if ( $wgUser->isLoggedIn() ) {
                        $attribs = [
                                'tabindex' => ++$tabindex,
                                'accesskey' => wfMessage( 'accesskey-watch' )->text(),
@@ -4067,7 +4062,9 @@ HTML
        public function getEditButtons( &$tabindex ) {
                $buttons = [];
 
-               $labelAsPublish = $this->mArticle->getContext()->getConfig()->get( 'EditButtonPublishNotSave' );
+               $labelAsPublish =
+                       $this->mArticle->getContext()->getConfig()->get( 'EditSubmitButtonLabelPublish' );
+
                // Can't use $this->isNew as that's also true if we're adding a new section to an extant page
                if ( $labelAsPublish ) {
                        $buttonLabelKey = !$this->mTitle->exists() ? 'publishpage' : 'publishchanges';
@@ -4109,14 +4106,15 @@ HTML
         * they have attempted to edit a nonexistent section.
         */
        function noSuchSectionPage() {
-               $out = $this->context->getOutput();
-               $out->prepareErrorPage( wfMessage( 'nosuchsectiontitle' ) );
+               global $wgOut;
+
+               $wgOut->prepareErrorPage( wfMessage( 'nosuchsectiontitle' ) );
 
                $res = wfMessage( 'nosuchsectiontext', $this->section )->parseAsBlock();
                Hooks::run( 'EditPageNoSuchSection', [ &$this, &$res ] );
-               $out->addHTML( $res );
+               $wgOut->addHTML( $res );
 
-               $out->returnToMain( false, $this->mTitle );
+               $wgOut->returnToMain( false, $this->mTitle );
        }
 
        /**
@@ -4125,28 +4123,28 @@ HTML
         * @param string|array|bool $match Text (or array of texts) which triggered one or more filters
         */
        public function spamPageWithContent( $match = false ) {
+               global $wgOut, $wgLang;
                $this->textbox2 = $this->textbox1;
 
                if ( is_array( $match ) ) {
-                       $match = $this->context->getLanguage()->listToText( $match );
+                       $match = $wgLang->listToText( $match );
                }
-               $out = $this->context->getOutput();
-               $out->prepareErrorPage( wfMessage( 'spamprotectiontitle' ) );
+               $wgOut->prepareErrorPage( wfMessage( 'spamprotectiontitle' ) );
 
-               $out->addHTML( '<div id="spamprotected">' );
-               $out->addWikiMsg( 'spamprotectiontext' );
+               $wgOut->addHTML( '<div id="spamprotected">' );
+               $wgOut->addWikiMsg( 'spamprotectiontext' );
                if ( $match ) {
-                       $out->addWikiMsg( 'spamprotectionmatch', wfEscapeWikiText( $match ) );
+                       $wgOut->addWikiMsg( 'spamprotectionmatch', wfEscapeWikiText( $match ) );
                }
-               $out->addHTML( '</div>' );
+               $wgOut->addHTML( '</div>' );
 
-               $out->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
+               $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
                $this->showDiff();
 
-               $out->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
+               $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
                $this->showTextbox2();
 
-               $out->addReturnTo( $this->getContextTitle(), [ 'action' => 'edit' ] );
+               $wgOut->addReturnTo( $this->getContextTitle(), [ 'action' => 'edit' ] );
        }
 
        /**
@@ -4156,9 +4154,9 @@ HTML
         * @return bool
         */
        private function checkUnicodeCompliantBrowser() {
-               global $wgBrowserBlackList;
+               global $wgBrowserBlackList, $wgRequest;
 
-               $currentbrowser = $this->context->getRequest()->getHeader( 'User-Agent' );
+               $currentbrowser = $wgRequest->getHeader( 'User-Agent' );
                if ( $currentbrowser === false ) {
                        // No User-Agent header sent? Trust it by default...
                        return true;
index 2a00900..cded064 100644 (file)
@@ -286,16 +286,6 @@ class MediaWiki {
                                // may still be a wikipage redirect to another article or URL.
                                $article = $this->initializeArticle();
                                if ( is_object( $article ) ) {
-                                       $url = $request->getFullRequestURL(); // requested URL
-                                       if (
-                                               $request->getMethod() === 'GET' &&
-                                               $url === $article->getTitle()->getCanonicalURL() &&
-                                               $article->checkTouched() &&
-                                               $output->checkLastModified( $article->getTouched() )
-                                       ) {
-                                               wfDebug( __METHOD__ . ": done 304\n" );
-                                               return;
-                                       }
                                        $this->performAction( $article, $requestTitle );
                                } elseif ( is_string( $article ) ) {
                                        $output->redirect( $article );
@@ -571,13 +561,14 @@ class MediaWiki {
                        // Abort if any transaction was too big
                        [ 'maxWriteDuration' => $config->get( 'MaxUserDBWriteDuration' ) ]
                );
-               // Record ChronologyProtector positions
-               $factory->shutdown();
-               wfDebug( __METHOD__ . ': all transactions committed' );
 
                DeferredUpdates::doUpdates( 'enqueue', DeferredUpdates::PRESEND );
                wfDebug( __METHOD__ . ': pre-send deferred updates completed' );
 
+               // Record ChronologyProtector positions
+               $factory->shutdown();
+               wfDebug( __METHOD__ . ': all transactions committed' );
+
                // Set a cookie to tell all CDN edge nodes to "stick" the user to the DC that handles this
                // POST request (e.g. the "master" data center). Also have the user briefly bypass CDN so
                // ChronologyProtector works for cacheable URLs.
index 77dbde7..1083687 100644 (file)
@@ -2547,6 +2547,7 @@ class OutputPage extends ContextSource {
        public function showLagWarning( $lag ) {
                $config = $this->getConfig();
                if ( $lag >= $config->get( 'SlaveLagWarning' ) ) {
+                       $lag = floor( $lag ); // floor to avoid nano seconds to display
                        $message = $lag < $config->get( 'SlaveLagCritical' )
                                ? 'lag-warn-normal'
                                : 'lag-warn-high';
index 70addfc..5a9f0b0 100644 (file)
@@ -1494,7 +1494,7 @@ class Preferences {
 
                        $context = $form->getContext();
                        // Set session data for the success message
-                       $context->getRequest()->setSessionData( 'specialPreferencesSaveSuccess', 1 );
+                       $context->getRequest()->getSession()->set( 'specialPreferencesSaveSuccess', 1 );
 
                        $context->getOutput()->redirect( $url );
                }
index b5c57ee..1e27f98 100644 (file)
@@ -394,6 +394,32 @@ class WebRequest {
                }
        }
 
+       /**
+        * Fetch a scalar from the input without normalization, or return $default
+        * if it's not set.
+        *
+        * Unlike self::getVal(), this does not perform any normalization on the
+        * input value.
+        *
+        * @since 1.28
+        * @param string $name
+        * @param string|null $default Optional default
+        * @return string
+        */
+       public function getRawVal( $name, $default = null ) {
+               $name = strtr( $name, '.', '_' ); // See comment in self::getGPCVal()
+               if ( isset( $this->data[$name] ) && !is_array( $this->data[$name] ) ) {
+                       $val = $this->data[$name];
+               } else {
+                       $val = $default;
+               }
+               if ( is_null( $val ) ) {
+                       return $val;
+               } else {
+                       return (string)$val;
+               }
+       }
+
        /**
         * Fetch a scalar from the input or return $default if it's not set.
         * Returns a string. Arrays are discarded. Useful for
index 3a24565..55507f5 100644 (file)
@@ -41,6 +41,30 @@ class ViewAction extends FormlessAction {
        }
 
        public function show() {
+               $config = $this->context->getConfig();
+
+               if (
+                       $config->get( 'DebugToolbar' ) == false && // don't let this get stuck on pages
+                       $this->page->checkTouched() // page exists and is not a redirect
+               ) {
+                       // Include any redirect in the last-modified calculation
+                       $redirFromTitle = $this->page->getRedirectedFrom();
+                       if ( !$redirFromTitle ) {
+                               $touched = $this->page->getTouched();
+                       } elseif ( $config->get( 'MaxRedirects' ) <= 1 ) {
+                               $touched = max( $this->page->getTouched(), $redirFromTitle->getTouched() );
+                       } else {
+                               // Don't bother following the chain and getting the max mtime
+                               $touched = null;
+                       }
+
+                       // Send HTTP 304 if the IMS matches or otherwise set expiry/last-modified headers
+                       if ( $touched && $this->getOutput()->checkLastModified( $touched ) ) {
+                               wfDebug( __METHOD__ . ": done 304\n" );
+                               return;
+                       }
+               }
+
                $this->page->view();
        }
 }
index 66c1b53..55d2430 100644 (file)
@@ -1000,6 +1000,31 @@ abstract class ApiBase extends ContextSource {
                                        $type = $this->getModuleManager()->getNames( $paramName );
                                }
                        }
+
+                       $request = $this->getMain()->getRequest();
+                       $rawValue = $request->getRawVal( $encParamName );
+                       if ( $rawValue === null ) {
+                               $rawValue = $default;
+                       }
+
+                       // Preserve U+001F for self::parseMultiValue(), or error out if that won't be called
+                       if ( isset( $value ) && substr( $rawValue, 0, 1 ) === "\x1f" ) {
+                               if ( $multi ) {
+                                       // This loses the potential $wgContLang->checkTitleEncoding() transformation
+                                       // done by WebRequest for $_GET. Let's call that a feature.
+                                       $value = join( "\x1f", $request->normalizeUnicode( explode( "\x1f", $rawValue ) ) );
+                               } else {
+                                       $this->dieUsage(
+                                               "U+001F multi-value separation may only be used for multi-valued parameters.",
+                                               'badvalue_notmultivalue'
+                                       );
+                               }
+                       }
+
+                       // Check for NFC normalization, and warn
+                       if ( $rawValue !== $value ) {
+                               $this->handleParamNormalization( $paramName, $value, $rawValue );
+                       }
                }
 
                if ( isset( $value ) && ( $multi || is_array( $type ) ) ) {
@@ -1145,6 +1170,40 @@ abstract class ApiBase extends ContextSource {
                return $value;
        }
 
+       /**
+        * Handle when a parameter was Unicode-normalized
+        * @since 1.28
+        * @param string $paramName Unprefixed parameter name
+        * @param string $value Input that will be used.
+        * @param string $rawValue Input before normalization.
+        */
+       protected function handleParamNormalization( $paramName, $value, $rawValue ) {
+               $encParamName = $this->encodeParamName( $paramName );
+               $this->setWarning(
+                       "The value passed for '$encParamName' contains invalid or non-normalized data. "
+                       . 'Textual data should be valid, NFC-normalized Unicode without '
+                       . 'C0 control characters other than HT (\\t), LF (\\n), and CR (\\r).'
+               );
+       }
+
+       /**
+        * Split a multi-valued parameter string, like explode()
+        * @since 1.28
+        * @param string $value
+        * @param int $limit
+        * @return string[]
+        */
+       protected function explodeMultiValue( $value, $limit ) {
+               if ( substr( $value, 0, 1 ) === "\x1f" ) {
+                       $sep = "\x1f";
+                       $value = substr( $value, 1 );
+               } else {
+                       $sep = '|';
+               }
+
+               return explode( $sep, $value, $limit );
+       }
+
        /**
         * Return an array of values that were given in a 'a|b|c' notation,
         * after it optionally validates them against the list allowed values.
@@ -1159,13 +1218,13 @@ abstract class ApiBase extends ContextSource {
         * @return string|string[] (allowMultiple ? an_array_of_values : a_single_value)
         */
        protected function parseMultiValue( $valueName, $value, $allowMultiple, $allowedValues ) {
-               if ( trim( $value ) === '' && $allowMultiple ) {
+               if ( ( trim( $value ) === '' || trim( $value ) === "\x1f" ) && $allowMultiple ) {
                        return [];
                }
 
                // This is a bit awkward, but we want to avoid calling canApiHighLimits()
                // because it unstubs $wgUser
-               $valuesList = explode( '|', $value, self::LIMIT_SML2 + 1 );
+               $valuesList = $this->explodeMultiValue( $value, self::LIMIT_SML2 + 1 );
                $sizeLimit = count( $valuesList ) > self::LIMIT_SML1 && $this->mMainModule->canApiHighLimits()
                        ? self::LIMIT_SML2
                        : self::LIMIT_SML1;
index 90438d4..ed229cb 100644 (file)
@@ -495,10 +495,14 @@ class ApiPageSet extends ApiBase {
         * @since 1.21
         */
        public function getNormalizedTitlesAsResult( $result = null ) {
+               global $wgContLang;
+
                $values = [];
                foreach ( $this->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
+                       $encode = ( $wgContLang->normalize( $rawTitleStr ) !== $rawTitleStr );
                        $values[] = [
-                               'from' => $rawTitleStr,
+                               'fromencoded' => $encode,
+                               'from' => $encode ? rawurlencode( $rawTitleStr ) : $rawTitleStr,
                                'to' => $titleStr
                        ];
                }
@@ -1403,6 +1407,23 @@ class ApiPageSet extends ApiBase {
                return $result;
        }
 
+       protected function handleParamNormalization( $paramName, $value, $rawValue ) {
+               parent::handleParamNormalization( $paramName, $value, $rawValue );
+
+               if ( $paramName === 'titles' ) {
+                       // For the 'titles' parameter, we want to split it like ApiBase would
+                       // and add any changed titles to $this->mNormalizedTitles
+                       $value = $this->explodeMultiValue( $value, self::LIMIT_SML2 + 1 );
+                       $l = count( $value );
+                       $rawValue = $this->explodeMultiValue( $rawValue, $l );
+                       for ( $i = 0; $i < $l; $i++ ) {
+                               if ( $value[$i] !== $rawValue[$i] ) {
+                                       $this->mNormalizedTitles[$rawValue[$i]] = $value[$i];
+                               }
+                       }
+               }
+       }
+
        private static $generators = null;
 
        /**
index 8b8bd01..5d7c664 100644 (file)
@@ -173,10 +173,8 @@ class ApiQueryBlocks extends ApiQueryBase {
                        $this->addWhereFld( 'ipb_deleted', 0 );
                }
 
-               // Purge expired entries on one in every 10 queries
-               if ( !mt_rand( 0, 10 ) ) {
-                       Block::purgeExpired();
-               }
+               # Filter out expired rows
+               $this->addWhere( 'ipb_expiry > ' . $db->addQuotes( $db->timestamp() ) );
 
                $res = $this->select( __METHOD__ );
 
index 00846f5..e308ba4 100644 (file)
@@ -415,7 +415,7 @@ class ApiResult implements ApiSerializable {
                        if ( $this->maxSize !== false && $newsize > $this->maxSize ) {
                                /// @todo Add i18n message when replacing calls to ->setWarning()
                                $msg = new ApiRawMessage( 'This result was truncated because it would otherwise ' .
-                                       ' be larger than the limit of $1 bytes', 'truncatedresult' );
+                                       'be larger than the limit of $1 bytes', 'truncatedresult' );
                                $msg->numParams( $this->maxSize );
                                $this->errorFormatter->addWarning( 'result', $msg );
                                return false;
index 1815836..a68a87f 100644 (file)
        "api-help-param-deprecated": "Deprecated.",
        "api-help-param-required": "This parameter is required.",
        "api-help-datatypes-header": "Data types",
-       "api-help-datatypes": "Some parameter types in API requests need further explanation:\n;boolean\n:Boolean parameters work like HTML checkboxes: if the parameter is specified, regardless of value, it is considered true. For a false value, omit the parameter entirely.\n;timestamp\n:Timestamps may be specified in several formats. ISO 8601 date and time is recommended. All times are in UTC, any included timezone is ignored.\n:* ISO 8601 date and time, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (punctuation and <kbd>Z</kbd> are optional)\n:* ISO 8601 date and time with (ignored) fractional seconds, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (dashes, colons, and <kbd>Z</kbd> are optional)\n:* MediaWiki format, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Generic numeric format, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (optional timezone of <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, or <kbd>-<var>##</var></kbd> is ignored)\n:* EXIF format, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*RFC 2822 format (timezone may be omitted), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850 format (timezone may be omitted), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime format, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Seconds since 1970-01-01T00:00:00Z as a 1 to 13 digit integer (excluding <kbd>0</kbd>)\n:* The string <kbd>now</kbd>",
+       "api-help-datatypes": "Input to MediaWiki should be NFC-normalized UTF-8. MediaWiki may attempt to convert other input, but this may cause some operations (such as [[Special:ApiHelp/edit|edits]] with MD5 checks) to fail.\n\nSome parameter types in API requests need further explanation:\n;boolean\n:Boolean parameters work like HTML checkboxes: if the parameter is specified, regardless of value, it is considered true. For a false value, omit the parameter entirely.\n;timestamp\n:Timestamps may be specified in several formats. ISO 8601 date and time is recommended. All times are in UTC, any included timezone is ignored.\n:* ISO 8601 date and time, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd> (punctuation and <kbd>Z</kbd> are optional)\n:* ISO 8601 date and time with (ignored) fractional seconds, <kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd> (dashes, colons, and <kbd>Z</kbd> are optional)\n:* MediaWiki format, <kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* Generic numeric format, <kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd> (optional timezone of <kbd>GMT</kbd>, <kbd>+<var>##</var></kbd>, or <kbd>-<var>##</var></kbd> is ignored)\n:* EXIF format, <kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:*RFC 2822 format (timezone may be omitted), <kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850 format (timezone may be omitted), <kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime format, <kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* Seconds since 1970-01-01T00:00:00Z as a 1 to 13 digit integer (excluding <kbd>0</kbd>)\n:* The string <kbd>now</kbd>\n;alternative multiple-value separator\n:Parameters that take multiple values are normally submitted with the values separated using the pipe character, e.g. <kbd>param=value1|value2</kbd> or <kbd>param=value1%7Cvalue2</kbd>. If a value must contain the pipe character, use U+001F (Unit Separator) as the separator ''and'' prefix the value with U+001F, e.g. <kbd>param=%1Fvalue1%1Fvalue2</kbd>.",
        "api-help-param-type-limit": "Type: integer or <kbd>max</kbd>",
        "api-help-param-type-integer": "Type: {{PLURAL:$1|1=integer|2=list of integers}}",
        "api-help-param-type-boolean": "Type: boolean ([[Special:ApiHelp/main#main/datatypes|details]])",
        "api-help-param-type-password": "",
        "api-help-param-type-timestamp": "Type: {{PLURAL:$1|1=timestamp|2=list of timestamps}} ([[Special:ApiHelp/main#main/datatypes|allowed formats]])",
        "api-help-param-type-user": "Type: {{PLURAL:$1|1=user name|2=list of user names}}",
-       "api-help-param-list": "{{PLURAL:$1|1=One of the following values|2=Values (separate with <kbd>{{!}}</kbd>)}}: $2",
+       "api-help-param-list": "{{PLURAL:$1|1=One of the following values|2=Values (separate with <kbd>{{!}}</kbd> or [[Special:ApiHelp/main#main/datatypes|alternative]])}}: $2",
        "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Must be empty|Can be empty, or $2}}",
        "api-help-param-limit": "No more than $1 allowed.",
        "api-help-param-limit2": "No more than $1 ($2 for bots) allowed.",
        "api-help-param-integer-max": "The {{PLURAL:$1|1=value|2=values}} must be no greater than $3.",
        "api-help-param-integer-minmax": "The {{PLURAL:$1|1=value|2=values}} must be between $2 and $3.",
        "api-help-param-upload": "Must be posted as a file upload using multipart/form-data.",
-       "api-help-param-multi-separate": "Separate values with <kbd>|</kbd>.",
+       "api-help-param-multi-separate": "Separate values with <kbd>|</kbd> or [[Special:ApiHelp/main#main/datatypes|alternative]].",
        "api-help-param-multi-max": "Maximum number of values is {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} for bots).",
        "api-help-param-default": "Default: $1",
        "api-help-param-default-empty": "Default: <span class=\"apihelp-empty\">(empty)</span>",
index b8756c5..059a7c5 100644 (file)
        "apihelp-query+alllinks-example-unique-generator": "Obtiene todos los títulos enlazados, marcando los que falten.",
        "apihelp-query+alllinks-example-generator": "Obtiene páginas que contienen los enlaces.",
        "apihelp-query+allmessages-description": "Devolver los mensajes de este sitio.",
-       "apihelp-query+allmessages-param-messages": "Qué mensajes mostrar. <kbd>*</kbd> (por defecto) significa todos los mensajes.",
+       "apihelp-query+allmessages-param-messages": "Qué mensajes mostrar. <kbd>*</kbd> (predeterminado) significa todos los mensajes.",
        "apihelp-query+allmessages-param-prop": "Qué propiedades se obtendrán.",
        "apihelp-query+allmessages-param-enableparser": "Establecer para habilitar el analizador, se preprocesará el wikitexto del mensaje (sustitución de palabras mágicas, uso de plantillas, etc.).",
        "apihelp-query+allmessages-param-nocontent": "Si se establece, no incluya el contenido de los mensajes en la salida.",
        "apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "Añade el comentario analizado para la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-flags": "Añade marcas para la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-timestamp": "Añade la marca de tiempo de la edición.",
-       "apihelp-query+recentchanges-paramvalue-prop-title": "Añade el título de la página de la edición.",
+       "apihelp-query+recentchanges-paramvalue-prop-title": "Añade el título de página de la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-ids": "Añade los códigos ID de la página, de los cambios recientes y de las revisiones antigua y nueva.",
        "apihelp-query+recentchanges-paramvalue-prop-sizes": "Añade la longitud antigua y la longitud nueva de la página en bytes.",
        "apihelp-query+recentchanges-paramvalue-prop-redirect": "Etiqueta la edición si la página es una redirección.",
        "apihelp-query+redirects-param-namespace": "Incluir solo páginas de estos espacios de nombres.",
        "apihelp-query+redirects-param-limit": "Cuántas redirecciones se devolverán.",
        "apihelp-query+redirects-example-simple": "Mostrar una lista de las redirecciones a la [[Main Page|Portada]]",
-       "apihelp-query+redirects-example-generator": "Obtener información sobre todas las redirecciones a la [[Main Page|Portada]]",
+       "apihelp-query+redirects-example-generator": "Obtener información sobre todas las redirecciones a la [[Main Page|Portada]].",
        "apihelp-query+revisions-param-end": "Enumerar hasta esta marca de tiempo.",
        "apihelp-query+revisions-param-user": "Incluir solo las revisiones realizadas por el usuario.",
        "apihelp-query+revisions-param-excludeuser": "Excluir las revisiones realizadas por el usuario.",
index d88e0ec..03cb2b5 100644 (file)
@@ -99,5 +99,6 @@
        "apihelp-query+watchlist-paramvalue-type-categorize": "वर्ग सदस्यता बदलते.",
        "apihelp-stashedit-param-title": "पानाच्या मथळ्याचे संपादन होत आहे.",
        "apihelp-stashedit-param-sectiontitle": "नविन विभागाचा मथळा",
-       "apihelp-stashedit-param-summary": "सारांश बदला."
+       "apihelp-stashedit-param-summary": "सारांश बदला.",
+       "api-help-examples": "{{PLURAL:$1|उदाहरण|उदाहरणे}}:"
 }
index ed94c1a..c338284 100644 (file)
@@ -126,8 +126,8 @@ class TemporaryPasswordPrimaryAuthenticationProvider
                        return AuthenticationResponse::newAbstain();
                }
 
-               $dbw = wfGetDB( DB_MASTER );
-               $row = $dbw->selectRow(
+               $dbr = wfGetDB( DB_SLAVE );
+               $row = $dbr->selectRow(
                        'user',
                        [
                                'user_id', 'user_newpassword', 'user_newpass_time',
@@ -165,8 +165,8 @@ class TemporaryPasswordPrimaryAuthenticationProvider
                        return false;
                }
 
-               $dbw = wfGetDB( DB_MASTER );
-               $row = $dbw->selectRow(
+               $dbr = wfGetDB( DB_SLAVE );
+               $row = $dbr->selectRow(
                        'user',
                        [ 'user_newpassword', 'user_newpass_time' ],
                        [ 'user_name' => $username ],
index e07836b..874e9c4 100644 (file)
@@ -201,6 +201,8 @@ abstract class DatabaseBase implements IDatabase {
        /** @var int[] Prior mFlags values */
        private $priorFlags = [];
 
+       /** @var Profiler */
+       protected $profiler;
        /** @var TransactionProfiler */
        protected $trxProfiler;
 
@@ -320,10 +322,6 @@ abstract class DatabaseBase implements IDatabase {
         * @return TransactionProfiler
         */
        protected function getTransactionProfiler() {
-               if ( !$this->trxProfiler ) {
-                       $this->trxProfiler = new TransactionProfiler();
-               }
-
                return $this->trxProfiler;
        }
 
@@ -583,13 +581,17 @@ abstract class DatabaseBase implements IDatabase {
 
                $this->mForeign = $foreign;
 
-               if ( isset( $params['trxProfiler'] ) ) {
-                       $this->trxProfiler = $params['trxProfiler']; // override
-               }
+               $this->profiler = isset( $params['profiler'] )
+                       ? $params['profiler']
+                       : Profiler::instance(); // @TODO: remove global state
+               $this->trxProfiler = isset( $params['trxProfiler'] )
+                       ? $params['trxProfiler']
+                       : new TransactionProfiler();
 
                if ( $user ) {
                        $this->open( $server, $user, $password, $dbName );
                }
+
        }
 
        /**
@@ -939,13 +941,10 @@ abstract class DatabaseBase implements IDatabase {
                # Include query transaction state
                $queryProf .= $this->mTrxShortId ? " [TRX#{$this->mTrxShortId}]" : "";
 
-               $profiler = Profiler::instance();
-               if ( !( $profiler instanceof ProfilerStub ) ) {
-                       $queryProfSection = $profiler->scopedProfileIn( $queryProf );
-               }
-
                $startTime = microtime( true );
+               $this->profiler->profileIn( $queryProf );
                $ret = $this->doQuery( $commentedSql );
+               $this->profiler->profileOut( $queryProf );
                $queryRuntime = microtime( true ) - $startTime;
 
                unset( $queryProfSection ); // profile out (if set)
index 4cd02b1..cfae74f 100644 (file)
@@ -470,3 +470,21 @@ class DBReadOnlyError extends DBExpectedError {
  */
 class DBTransactionError extends DBExpectedError {
 }
+
+/**
+ * Exception class for attempted DB access
+ * @ingroup Database
+ */
+class DBAccessError extends DBUnexpectedError {
+       public function __construct() {
+               parent::__construct( "Mediawiki tried to access the database via wfGetDB(). " .
+                       "This is not allowed, because database access has been disabled." );
+       }
+}
+
+/**
+ * Exception class for replica DB wait timeouts
+ * @ingroup Database
+ */
+class DBReplicationWaitError extends DBUnexpectedError {
+}
index f560cf1..dfa4c29 100644 (file)
@@ -196,9 +196,12 @@ abstract class LBFactory implements DestructibleService {
        /**
         * Prepare all tracked load balancers for shutdown
         * @param integer $flags Supports SHUTDOWN_* flags
-        * STUB
         */
        public function shutdown( $flags = 0 ) {
+               if ( !( $flags & self::SHUTDOWN_NO_CHRONPROT ) ) {
+                       $this->shutdownChronologyProtector( $this->chronProt );
+               }
+               $this->commitMasterChanges( __METHOD__ ); // sanity
        }
 
        /**
@@ -536,19 +539,3 @@ abstract class LBFactory implements DestructibleService {
        }
 
 }
-
-/**
- * Exception class for attempted DB access
- */
-class DBAccessError extends MWException {
-       public function __construct() {
-               parent::__construct( "Mediawiki tried to access the database via wfGetDB(). " .
-                       "This is not allowed, because database access has been disabled." );
-       }
-}
-
-/**
- * Exception class for replica DB wait timeouts
- */
-class DBReplicationWaitError extends Exception {
-}
index 4b9cccc..f201081 100644 (file)
@@ -418,11 +418,4 @@ class LBFactoryMulti extends LBFactory {
                        call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
                }
        }
-
-       public function shutdown( $flags = 0 ) {
-               if ( !( $flags & self::SHUTDOWN_NO_CHRONPROT ) ) {
-                       $this->shutdownChronologyProtector( $this->chronProt );
-               }
-               $this->commitMasterChanges( __METHOD__ ); // sanity
-       }
 }
index 3702c8b..c7c4752 100644 (file)
@@ -159,11 +159,4 @@ class LBFactorySimple extends LBFactory {
                        call_user_func_array( $callback, array_merge( [ $lb ], $params ) );
                }
        }
-
-       public function shutdown( $flags = 0 ) {
-               if ( !( $flags & self::SHUTDOWN_NO_CHRONPROT ) ) {
-                       $this->shutdownChronologyProtector( $this->chronProt );
-               }
-               $this->commitMasterChanges( __METHOD__ ); // sanity
-       }
 }
index 5e02c5c..ec7360e 100644 (file)
@@ -79,6 +79,16 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
         */
        private $linkDeletions = null;
 
+       /**
+        * @var null|array Added properties if calculated.
+        */
+       private $propertyInsertions = null;
+
+       /**
+        * @var null|array Deleted properties if calculated.
+        */
+       private $propertyDeletions = null;
+
        /**
         * @var User|null
         */
@@ -234,12 +244,13 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
 
                # Page properties
                $existing = $this->getExistingProperties();
-               $propertiesDeletes = $this->getPropertyDeletions( $existing );
-               $this->incrTableUpdate( 'page_props', 'pp', $propertiesDeletes,
+               $this->propertyDeletions = $this->getPropertyDeletions( $existing );
+               $this->incrTableUpdate( 'page_props', 'pp', $this->propertyDeletions,
                        $this->getPropertyInsertions( $existing ) );
 
                # Invalidate the necessary pages
-               $changed = $propertiesDeletes + array_diff_assoc( $this->mProperties, $existing );
+               $this->propertyInsertions = array_diff_assoc( $this->mProperties, $existing );
+               $changed = $this->propertyDeletions + $this->propertyInsertions;
                $this->invalidateProperties( $changed );
 
                # Refresh links of all pages including this page
@@ -1016,6 +1027,26 @@ class LinksUpdate extends SqlDataUpdate implements EnqueueableDataUpdate {
                return $result;
        }
 
+       /**
+        * Fetch page properties added by this LinksUpdate.
+        * Only available after the update is complete.
+        * @since 1.28
+        * @return null|array
+        */
+       public function getAddedProperties() {
+               return $this->propertyInsertions;
+       }
+
+       /**
+        * Fetch page properties removed by this LinksUpdate.
+        * Only available after the update is complete.
+        * @since 1.28
+        * @return null|array
+        */
+       public function getRemovedProperties() {
+               return $this->propertyDeletions;
+       }
+
        /**
         * Update links table freshness
         */
index b29e3bd..c9ebe32 100644 (file)
        "config-page-language": "Zıwan",
        "config-page-welcome": "Şıma xeyr ameyê MediaWiki!",
        "config-page-dbconnect": "Database rê grêdey",
+       "config-page-upgrade": "Est bıyaye versiyoni berz kı",
+       "config-page-dbsettings": "Sazê Database",
        "config-page-name": "Name",
        "config-page-options": "Weçinegi",
        "config-page-install": "Barine",
        "config-page-complete": "Temamyayo",
+       "config-page-restart": "Barkerdışi fına ser kı",
        "config-page-readme": "Mı bıwane",
        "config-page-copying": "Kopyayeno",
        "config-page-upgradedoc": "Berzkerdış",
        "config-restart": "E, fına dest pekê",
        "config-sidebar": "* [https://www.mediawiki.org MediaWiki keye]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Şınasiya Karberi]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Şınasiya İdarekaran]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Peşti]\n----\n* <doclink href=Readme>Mı buwanê</doclink>\n* <doclink href=ReleaseNotes>Notê elaqeyıni</doclink>\n* <doclink href=Copying>Kopyakerdış</doclink>\n* <doclink href=UpgradeDoc>Zêdekerdış</doclink>",
        "config-env-php": "PHP $1 i biyo saz.",
+       "config-env-hhvm": "HHVM $1 saz bi ya.",
        "config-db-type": "Database tipe:",
        "config-db-host": "Database host:",
        "config-db-host-oracle": "Database TNS:",
index bb760bd..aefda79 100644 (file)
@@ -42,6 +42,7 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
         *   - serializer:          May be either "php" or "igbinary". Igbinary produces more compact
         *                          values, but serialization is much slower unless the php.ini option
         *                          igbinary.compact_strings is off.
+        *   - use_binary_protocol  Whether to enable the binary protocol (default is ASCII) (boolean)
         * @param array $params
         * @throws InvalidArgumentException
         */
@@ -62,8 +63,8 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                        $this->client = new Memcached;
                }
 
-               if ( !isset( $params['serializer'] ) ) {
-                       $params['serializer'] = 'php';
+               if ( $params['use_binary_protocol'] ) {
+                       $this->client->setOption( Memcached::OPT_BINARY_PROTOCOL, true );
                }
 
                if ( isset( $params['retry_timeout'] ) ) {
@@ -119,6 +120,20 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
                $this->client->addServers( $servers );
        }
 
+       protected function applyDefaultParams( $params ) {
+               $params = parent::applyDefaultParams( $params );
+
+               if ( !isset( $params['use_binary_protocol'] ) ) {
+                       $params['use_binary_protocol'] = false;
+               }
+
+               if ( !isset( $params['serializer'] ) ) {
+                       $params['serializer'] = 'php';
+               }
+
+               return $params;
+       }
+
        protected function getWithToken( $key, &$casToken, $flags = 0 ) {
                $this->debugLog( "get($key)" );
                $result = $this->client->get( $this->validateKeyEncoding( $key ), null, $casToken );
index b3a97f7..e299f7e 100644 (file)
@@ -149,6 +149,15 @@ class Article implements Page {
                return $article;
        }
 
+       /**
+        * Get the page this view was redirected from
+        * @return Title|null
+        * @since 1.28
+        */
+       public function getRedirectedFrom() {
+               return $this->mRedirectedFrom;
+       }
+
        /**
         * Tell the page view functions that this view was redirected
         * from another page on the wiki.
@@ -467,7 +476,7 @@ class Article implements Page {
         * page of the given title.
         */
        public function view() {
-               global $wgUseFileCache, $wgDebugToolbar, $wgMaxRedirects;
+               global $wgUseFileCache, $wgDebugToolbar;
 
                # Get variables from query string
                # As side effect this will load the revision and update the title
@@ -520,29 +529,6 @@ class Article implements Page {
 
                # Try client and file cache
                if ( !$wgDebugToolbar && $oldid === 0 && $this->mPage->checkTouched() ) {
-                       # Use the greatest of the page's timestamp or the timestamp of any
-                       # redirect in the chain (bug 67849)
-                       $timestamp = $this->mPage->getTouched();
-                       if ( isset( $this->mRedirectedFrom ) ) {
-                               $timestamp = max( $timestamp, $this->mRedirectedFrom->getTouched() );
-
-                               # If there can be more than one redirect in the chain, we have
-                               # to go through the whole chain too in case an intermediate
-                               # redirect was changed.
-                               if ( $wgMaxRedirects > 1 ) {
-                                       $titles = Revision::newFromTitle( $this->mRedirectedFrom )
-                                               ->getContent( Revision::FOR_THIS_USER, $user )
-                                               ->getRedirectChain();
-                                       $thisTitle = $this->getTitle();
-                                       foreach ( $titles as $title ) {
-                                               if ( Title::compare( $title, $thisTitle ) === 0 ) {
-                                                       break;
-                                               }
-                                               $timestamp = max( $timestamp, $title->getTouched() );
-                                       }
-                               }
-                       }
-
                        # Try to stream the output from file cache
                        if ( $wgUseFileCache && $this->tryFileCache() ) {
                                wfDebug( __METHOD__ . ": done file cache\n" );
index 4066501..e1d9f99 100644 (file)
@@ -2883,7 +2883,14 @@ class WikiPage implements Page, IDBAccessObject {
                // unless they actually try to catch exceptions (which is rare).
 
                // we need to remember the old content so we can use it to generate all deletion updates.
-               $content = $this->getContent( Revision::RAW );
+               try {
+                       $content = $this->getContent( Revision::RAW );
+               } catch ( Exception $ex ) {
+                       wfLogWarning( __METHOD__ . ': failed to load content during deletion! '
+                               . $ex->getMessage() );
+
+                       $content = null;
+               }
 
                // Bitfields to further suppress the content
                if ( $suppress ) {
@@ -3024,8 +3031,16 @@ class WikiPage implements Page, IDBAccessObject {
         *   may already return null when the page proper was deleted.
         */
        public function doDeleteUpdates( $id, Content $content = null ) {
+               try {
+                       $countable = $this->isCountable();
+               } catch ( Exception $ex ) {
+                       // fallback for deleting broken pages for which we cannot load the content for
+                       // some reason. Note that doDeleteArticleReal() already logged this problem.
+                       $countable = false;
+               }
+
                // Update site status
-               DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 ) );
+               DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$countable, -1 ) );
 
                // Delete pagelinks, update secondary indexes, etc
                $updates = $this->getDeletionUpdates( $content );
@@ -3641,7 +3656,14 @@ class WikiPage implements Page, IDBAccessObject {
                if ( !$content ) {
                        // load content object, which may be used to determine the necessary updates.
                        // XXX: the content may not be needed to determine the updates.
-                       $content = $this->getContent( Revision::RAW );
+                       try {
+                               $content = $this->getContent( Revision::RAW );
+                       } catch ( Exception $ex ) {
+                               // If we can't load the content, something is wrong. Perhaps that's why
+                               // the user is trying to delete the page, so let's not fail in that case.
+                               // Note that doDeleteArticleReal() will already have logged an issue with
+                               // loading the content.
+                       }
                }
 
                if ( !$content ) {
index 79b71df..30fe3ae 100644 (file)
@@ -175,8 +175,7 @@ class ResourceLoaderContext {
                        // Stricter version of RequestContext::sanitizeLangCode()
                        if ( !Language::isValidBuiltInCode( $lang ) ) {
                                wfDebug( "Invalid user language code\n" );
-                               global $wgLanguageCode;
-                               $lang = $wgLanguageCode;
+                               $lang = $this->getResourceLoader()->getConfig()->get( 'LanguageCode' );
                        }
                        $this->language = $lang;
                }
index 264e1ae..0439b36 100644 (file)
@@ -716,6 +716,8 @@ final class SessionBackend {
                        }
                }
 
+               $flags = $this->persist ? 0 : CachedBagOStuff::WRITE_CACHE_ONLY;
+               $flags |= CachedBagOStuff::WRITE_SYNC; // write to all datacenters
                $this->store->set(
                        wfMemcKey( 'MWSession', (string)$this->id ),
                        [
@@ -723,7 +725,7 @@ final class SessionBackend {
                                'metadata' => $metadata,
                        ],
                        $metadata['expires'],
-                       $this->persist ? 0 : CachedBagOStuff::WRITE_CACHE_ONLY
+                       $flags
                );
 
                $this->metaDirty = false;
index 7c7f017..de58762 100644 (file)
@@ -136,8 +136,7 @@ class SpecialBlockList extends SpecialPage {
                                case Block::TYPE_IP:
                                case Block::TYPE_RANGE:
                                        list( $start, $end ) = IP::parseRange( $target );
-                                       $dbr = wfGetDB( DB_SLAVE );
-                                       $conds[] = $dbr->makeList(
+                                       $conds[] = wfGetDB( DB_SLAVE )->makeList(
                                                [
                                                        'ipb_address' => $target,
                                                        Block::getRangeCond( $start, $end )
index 5322a04..61b6a8c 100644 (file)
@@ -188,6 +188,9 @@ class SpecialPageLanguage extends FormSpecialPage {
                $logid = $entry->insert();
                $entry->publish( $logid );
 
+               // Force re-render so that language-based content (parser functions etc.) gets updated
+               $title->invalidateCache();
+
                return true;
        }
 
index f00477f..3697e5d 100644 (file)
@@ -53,10 +53,10 @@ class SpecialPreferences extends SpecialPage {
                $out->addModules( 'mediawiki.special.preferences' );
                $out->addModuleStyles( 'mediawiki.special.preferences.styles' );
 
-               $request = $this->getRequest();
-               if ( $request->getSessionData( 'specialPreferencesSaveSuccess' ) ) {
+               $session = $this->getRequest()->getSession();
+               if ( $session->get( 'specialPreferencesSaveSuccess' ) ) {
                        // Remove session data for the success message
-                       $request->setSessionData( 'specialPreferencesSaveSuccess', null );
+                       $session->remove( 'specialPreferencesSaveSuccess' );
                        $out->addModuleStyles( 'mediawiki.notification.convertmessagebox.styles' );
 
                        $out->addHtml(
@@ -146,7 +146,7 @@ class SpecialPreferences extends SpecialPage {
                $user->saveSettings();
 
                // Set session data for the success message
-               $this->getRequest()->setSessionData( 'specialPreferencesSaveSuccess', 1 );
+               $this->getRequest()->getSession()->set( 'specialPreferencesSaveSuccess', 1 );
 
                $url = $this->getPageTitle()->getFullURL();
                $this->getOutput()->redirect( $url );
index cb3b4b8..169e0ff 100644 (file)
@@ -1037,6 +1037,7 @@ class Language {
         *    xiy  y (two digit year) in Iranian calendar
         *    xiY  Y (full year) in Iranian calendar
         *    xit  t (days in month) in Iranian calendar
+        *    xiz  z (day of the year) in Iranian calendar
         *
         *    xjj  j (day number) in Hebrew calendar
         *    xjF  F (month name) in Hebrew calendar
@@ -1339,6 +1340,13 @@ class Language {
                                        }
                                        $num = self::$IRANIAN_DAYS[$iranian[1] - 1];
                                        break;
+                               case 'xiz':
+                                       $usedIranianYear = true;
+                                       if ( !$iranian ) {
+                                               $iranian = self::tsToIranian( $ts );
+                                       }
+                                       $num = $iranian[3];
+                                       break;
                                case 'a':
                                        $usedAMPM = true;
                                        $s .= intval( substr( $ts, 8, 2 ) ) < 12 ? 'am' : 'pm';
@@ -1597,6 +1605,8 @@ class Language {
                        $jDayNo = floor( ( $jDayNo - 1 ) % 365 );
                }
 
+               $jz = $jDayNo;
+
                for ( $i = 0; $i < 11 && $jDayNo >= self::$IRANIAN_DAYS[$i]; $i++ ) {
                        $jDayNo -= self::$IRANIAN_DAYS[$i];
                }
@@ -1604,7 +1614,7 @@ class Language {
                $jm = $i + 1;
                $jd = $jDayNo + 1;
 
-               return [ $jy, $jm, $jd ];
+               return [ $jy, $jm, $jd, $jz ];
        }
 
        /**
index 97a8233..cb869d0 100644 (file)
        "passwordreset-emailtext-user": "احد ما (قد يكون انت$1)طلب مذكرة تفاصيل الحساب ل{{SITENAME}} ($4).المستخدم الاتي {{PLURAL:$3|الحساب هو|الحسابات هي}} قد قرن بهذا العنوان :\n\n$2\n\n{{PLURAL:$3|كلمة المرور المؤقتة|كلمات المرور المؤقة}}سينتهي في {{PLURAL:$5|يوم|ايام$5 }}\nمن الافضل ان تسجل الدخول وتختار كلمة مرور جديدة الان .\nإذا قام شخص آخر بهذا الطلب، أو إذا  تذكرت كلمة المرور الأصلية الخاصة بك،ولم تعد ترغب في تغييره، يمكنك تجاهل هذه الرسالة ومتابعة استخدام  كلمة المرورالقديمة.",
        "passwordreset-emailelement": "اسم المستخدم: \n$1\n\nكلمة السر المؤقتة: \n$2",
        "passwordreset-emailsentemail": "أرسل بريد إلكتروني تذكيري",
-       "passwordreset-emailsent-capture": "أرسل بريد إلكتروني تذكيري وهو معروض بالأسفل.",
-       "passwordreset-emailerror-capture": "ولّد بريد إلكتروني تذكيري وهو معروض بالأسفل لكن فشل إرساله للمستخدم: $1",
        "changeemail": "تغيير عنوان البريد الإلكتروني",
        "changeemail-header": "تغيير عنوان البريد الإلكتروني للحساب",
        "changeemail-no-info": "يجب تسجيل الدخول للوصول إلى هذه الصفحة مباشرة.",
        "undo-failure": "لم يمكن استرجاع التعديل بسبب تعديلات متعارضة تمت على الصفحة.",
        "undo-norev": "فشل في الرجوع عن التعديل حيث أنه غير موجود أو تم حذفه.",
        "undo-summary": "الرجوع عن التعديل $1 بواسطة [[Special:Contributions/$2|$2]] ([[User talk:$2|نقاش]])",
-       "cantcreateaccounttitle": "لا يمكن إنشاء حساب",
        "cantcreateaccount-text": "إنشاء الحسابات من عنوان الأيبي هذا ('''$1''') تم منعه بواسطة [[User:$3|$3]].\n\nالسبب المعطى بواسطة $3 هو ''$2''",
        "viewpagelogs": "اعرض سجلات هذه الصفحة",
        "nohistory": "لا يوجد تاريخ للتعديلات لهذه الصفحة.",
        "revdel-restore": "تغيير الرؤية",
        "pagehist": "تاريخ صفحة",
        "deletedhist": "التاريخ المحذوف",
-       "revdelete-hide-current": "خطأ Ø¹Ù\86د Ø¥Ø­فاء العنصر المؤرخ في $2 $1: هذه هي المراجعة الحالية.\nلا يمكن إخفاؤها.",
+       "revdelete-hide-current": "خطأ Ø¹Ù\86د Ø¥Ø®فاء العنصر المؤرخ في $2 $1: هذه هي المراجعة الحالية.\nلا يمكن إخفاؤها.",
        "revdelete-show-no-access": "خطأ في إظهار العنصر ذا التاريخ $2 $1: هذا العنصر معلم ك\"مقيد\".\nليس لك صلاحية الوصول إليه.",
        "revdelete-modify-no-access": "خطأ في تعديل العنصر ذا التاريخ $2 $1: هذا العنصر معلم ك\"مقيد\".\nليس لك صلاحية الوصول إليه.",
        "revdelete-modify-missing": "خطأ في تعديل العنصر ذا الهوية $1: العنصر مفقود من قاعدة البيانات!",
index ea91890..1d40a9e 100644 (file)
        "tagline": "من {{SITENAME}}",
        "help": "مساعدة",
        "search": "بحث",
-       "search-ignored-headings": "# <!-- Ø£ØªØ±Ù\83 Ù\87ذا Ø§Ù\84سطر Ù\83Ù\85ا Ù\87Ù\88 --> <pre>\n# Ø³Ù\8aتÙ\85 ØªØ¬Ø§Ù\87Ù\84 Ø§Ù\84ترÙ\88Ù\8aسات Ø®Ù\84اÙ\84 Ø¹Ù\85Ù\84Ù\8aØ© Ø§Ù\84بحث\n#ا Ù\84تغÙ\8aÙ\8aرات Ø³ØªØ£Ø®Ø° Ù\85جراÙ\87ا Ù\85ا Ø£Ù\86 Ù\8aتÙ\85 Ù\81Ù\87رسة Ø§Ù\84صÙ\81حة Ø§Ù\84تÙ\8a ØªØ­ØªÙ\88Ù\8a Ø¹Ù\84Ù\89 ØªØ±Ù\88Ù\8aسات\n# Ù\8aÙ\85Ù\83Ù\86Ù\83 Ù\81رض Ø¹Ù\85Ù\84Ù\8aØ© Ù\81Ù\87رسة Ø§Ù\84صÙ\81حة Ù\85Ù\86 Ø®Ù\84اÙ\84 ØªØ¹Ø¯Ù\8aÙ\84 Ù\81ارغ\n# Ø§Ù\84صÙ\8aغة Ù\87Ù\8a Ù\83اÙ\84أتÙ\8a:\n# * Ù\83Ù\84 Ù\85ا Ù\8aÙ\83تب Ø¨Ø¹Ø¯ \"#\" Ø¥Ù\84Ù\89 Ø¢Ø®Ø± Ø§Ù\84سطر Ù\8aعتبر ØªØ¹Ù\84Ù\8aÙ\82\n# * Ù\83Ù\84 Ø³Ø·Ø± ØºÙ\8aر Ù\81ارغ Ø³Ù\8aÙ\83Ù\88Ù\86 Ø§Ù\84عÙ\86Ù\88اÙ\86 Ø§Ù\84Ø°Ù\8a Ø³Ù\8aتÙ\85 ØªØ¬Ø§Ù\87Ù\84Ù\87 (سÙ\8aأخذ Ø§Ù\84عÙ\86Ù\88اÙ\86 Ù\83Ù\85ا Ù\87Ù\88 Ø¨Ø§Ù\84ضبط Ø¨Ø§Ù\84تشÙ\83Ù\8aÙ\84 Ù\88Ø®Ù\84اÙ\81Ù\87)\nاÙ\84Ù\85راجع\nاÙ\84Ù\88صÙ\84ات Ø§Ù\84خارجÙ\8aØ©\nØ£نظر أيضا\n#</pre><!--أترك هذا السطر كما هو -->",
+       "search-ignored-headings": "# <!-- Ø§ØªØ±Ù\83 Ù\87ذا Ø§Ù\84سطر Ù\83Ù\85ا Ù\87Ù\88 --> <pre>\n# Ø³Ù\8aتÙ\85 ØªØ¬Ø§Ù\87Ù\84 Ø§Ù\84ترÙ\88Ù\8aسات Ø®Ù\84اÙ\84 Ø¹Ù\85Ù\84Ù\8aØ© Ø§Ù\84بحث\n#اÙ\84تغÙ\8aÙ\8aرات Ø³ØªØ£Ø®Ø° Ù\85جراÙ\87ا Ù\85ا Ø£Ù\86 Ù\8aتÙ\85 Ù\81Ù\87رسة Ø§Ù\84صÙ\81حة Ø§Ù\84تÙ\8a ØªØ­ØªÙ\88Ù\8a Ø¹Ù\84Ù\89 ØªØ±Ù\88Ù\8aسات\n# Ù\8aÙ\85Ù\83Ù\86Ù\83 Ù\81رض Ø¹Ù\85Ù\84Ù\8aØ© Ù\81Ù\87رسة Ø§Ù\84صÙ\81حة Ù\85Ù\86 Ø®Ù\84اÙ\84 ØªØ¹Ø¯Ù\8aÙ\84 Ù\81ارغ\n# Ø§Ù\84صÙ\8aغة Ù\87Ù\8a Ù\83اÙ\84أتÙ\8a:\n# * Ù\83Ù\84 Ù\85ا Ù\8aÙ\83تب Ø¨Ø¹Ø¯ \"#\" Ø¥Ù\84Ù\89 Ø¢Ø®Ø± Ø§Ù\84سطر Ù\8aعتبر ØªØ¹Ù\84Ù\8aÙ\82\n# * Ù\83Ù\84 Ø³Ø·Ø± ØºÙ\8aر Ù\81ارغ Ø³Ù\8aÙ\83Ù\88Ù\86 Ø§Ù\84عÙ\86Ù\88اÙ\86 Ø§Ù\84Ø°Ù\8a Ø³Ù\8aتÙ\85 ØªØ¬Ø§Ù\87Ù\84Ù\87 (سÙ\8aأخذ Ø§Ù\84عÙ\86Ù\88اÙ\86 Ù\83Ù\85ا Ù\87Ù\88 Ø¨Ø§Ù\84ضبط Ø¨Ø§Ù\84تشÙ\83Ù\8aÙ\84 Ù\88Ø®Ù\84اÙ\81Ù\87)\nاÙ\84Ù\85راجع\nاÙ\84Ù\88صÙ\84ات Ø§Ù\84خارجÙ\8aØ©\nانظر أيضا\n#</pre><!--أترك هذا السطر كما هو -->",
        "searchbutton": "ابحث",
        "go": "اذهب",
        "searcharticle": "اذهب",
        "databaseerror": "عطل في قاعدة البيانات",
        "databaseerror-text": "حدث خطأ في إستعلام قاعدة البيانات. قد يشير هذا إلى خطأ في البرنامج.",
        "databaseerror-textcl": "حدث خطأ في إستعلام قاعدة البيانات.",
-       "databaseerror-query": "Ø¥ستعلام: $1",
+       "databaseerror-query": "استعلام: $1",
        "databaseerror-function": "دالة: $1",
        "databaseerror-error": "خطأ: $1",
+       "transaction-duration-limit-exceeded": "لتفادي إنشاء تأخير نسخ عالي، هذا الفعل تم إنهاؤه لأن فترة الكتابة ($1) تجاوزت حد $2 ثانية.\nلو أنك تغير عناصر عديدة في نفس الوقت، حاول تجربة عمليا عديدة أصغر بدلا من ذلك.",
        "laggedslavemode": "'''تحذير:''' الصفحة قد لا تحتوي على أحدث التحديثات.",
        "readonly": "قاعدة البيانات مقفلة",
        "enterlockreason": "أدخل سببا للقفل ذاكرا تقديرا لوقت إزالة الغلق",
        "missingarticle-rev": "(رقم المراجعة: $1)",
        "missingarticle-diff": "(فرق: $1، $2)",
        "readonly_lag": "تم قفل قاعدة البيانات تلقائيا حتى تستطيع الخواديم التابعة ملاحقة الخادوم الرئيسي",
+       "nonwrite-api-promise-error": "'Promise-Non-Write-API-Action' HTTP header تم إرساله لكن الطلب كان لAPI write module.",
        "internalerror": "عطل داخلي",
        "internalerror_info": "عطل داخلي: $1",
        "internalerror-fatal-exception": "استثناء مميت من النوع \"$1\"",
        "title-invalid-interwiki": "عنوان الصفحة المطلوب يتضمن وصلة لحلقة لغة وهو ما لا يمكن استخدامه في العناوين.",
        "title-invalid-talk-namespace": "عنوان الصفحة المطلوبة يشير إلى صفحة نقاش غير موجودة.",
        "title-invalid-characters": "عنوان الصفحة المطلوب يتضمن رموزًا غير صالحة: \"$1\"",
+       "title-invalid-relative": "العنوان به مسار نسبي. عنوان الصفحات النسبية (./, ../) هي غير صحيحة، لأنها ستكون غاليا لا يمكن الوصول لها عندما يتم التعامل معها بواسطة متصفح المستخدم.",
+       "title-invalid-magic-tilde": "عنوان الصفحة المطلوب يحتوي على تتابع الشر السحري غير الصحيح (<nowiki>~~~</nowiki>).",
+       "title-invalid-too-long": "عنوان الصفحة المطلوبة طويل جدا. يجب أن يكون ليس أطول من $1 {{PLURAL:$1|بايت}} باستخدام ترميز UTF-8.",
        "title-invalid-leading-colon": "عنوان الصفحة المطلوب يتضمن فاصلة غير صالحة في بدايته.",
        "perfcached": "البيانات التالية مخبأة و قد لا تكون محدثة. {{PLURAL:$1||نتيجة واحدة|نتيجتان|$1 نتائج|$1 نتيجة}} على الأكثر {{PLURAL:$1||مخبّأة|مخبّأتان|مخبّأة}}.",
        "perfcachedts": "البيانات التالية مخزنة، وكان آخر تحديث لها في $1. العدد الأقصى للنتائج المخزنة هو {{PLURAL:$4||نتيجة واحدة|نتيجتان|$4 نتائج|$4 نتيجة}}.",
        "nocookiesnew": "تم إنشاء حساب المستخدم، ولكنك لست مسجل الدخول بعد.\nيستخدم {{SITENAME}} كوكيز لتسجيل الدخول.\nلديك الكوكيز معطلة.\nمن فضلك فعلها، ثم سجل الدخول باسم المستخدم وكلمة السر الجديدين.",
        "nocookieslogin": "يستخدم {{SITENAME}} الكوكيز لتسجيل الدخول.\nالكوكيز معطلة لديك.\nمن فضلك فعلها ثم حاول مرة أخرى.",
        "nocookiesfornew": "لم يتم إنشاء حساب المستخدم، لأننا لم نستطع تأكيد مصدره. \nتأكد من أن ملفات تعريف الارتباط (الكوكيز) مفعلة عندك، ثم أعد تحميل الصفحة وحاول مرة أخرى.",
+       "createacct-loginerror": "الحساب تم إنشاؤه تلقائيا لكن لم يمكن تسجيل دخولك تلقائيا. من فضلك اذهب إلى [[Special:UserLogin|تسجيل الدخول اليدوي]].",
        "noname": "لم تحدد اسم مستخدم صحيح.",
        "loginsuccesstitle": "تم الدخول",
        "loginsuccess": "'''لقد سجلت الدخول ل{{SITENAME}} باسم \"$1\".'''",
        "changepassword-success": "تم تغيير كلمة السر !",
        "changepassword-throttled": "لديك محاولات تسجيل دخول كثيرة حديثة. من فضلك انتظر $1 قبل المحاولة ثانية.",
        "botpasswords": "كلمات مرور البوت",
+       "botpasswords-summary": "<em>كلمات سر البوت</em> يسمح بالوصول لحساب مستخدم من خلال API بدون استخدام اعتمادات تسجيل الدخول الرئيسية للحساب. صلاحيات المستخدم المتوفرة عند تسجيل الدخول باستخدام كلمة سر بوت ربما تكون مقيدة.\n\nلو أنك لا تعرف لماذا تريد فعل هذا، فأنت ينبغي على الأرجح ألا تففعله. لا أحد ينبغي أن يسألك أبدا أن تولد واحدة من هذه وإعطاؤهم إياها.",
        "botpasswords-disabled": "كلمات السر الخاصة بالبوت معطلة.",
        "botpasswords-no-central-id": "لاستخدام كلمة السر الخاصة بالبوت، يجب أن تقوم بتسجيل الدخول من خلال حساب موحد.",
        "botpasswords-existing": "كلمات مرور البوت الموجودة",
        "botpasswords-label-delete": "احذف",
        "botpasswords-label-resetpassword": "أعد ضبط كلمة السر",
        "botpasswords-label-grants": "المنح التي يمكن تطبيقها:",
+       "botpasswords-help-grants": "كل منحة تعطي وصولا لصلاحيات المستخدم المعروضة التي يمتلكها حساب المستخدم بالفعل. انظر [[Special:ListGrants|جدول المنح]] للمزيد من المعلومات.",
        "botpasswords-label-restrictions": "قيود الاستخدام:",
        "botpasswords-label-grants-column": "الممنوح",
        "botpasswords-bad-appid": "اسم البوت \"$1\" غير صحيح.",
        "botpasswords-insert-failed": "فشل في اضافة  اسم البوت \"$1\".هل اضيف بالفعل؟",
        "botpasswords-update-failed": "فشل في تحديث اسم بوت \"$1\". هل تم حذفه؟",
-       "botpasswords-created-title": "صÙ\86اعة Ù\83Ù\84Ù\85Ø© Ø³Ø± Ø£Ù\84Ù\8aØ©",
-       "botpasswords-created-body": "تم إنشاء كلمة مرور بوت \"$1\".",
-       "botpasswords-updated-title": "تحديث كلمة السر الألية",
-       "botpasswords-updated-body": "كلمة سر البوت\"$1\" قد حذفت.",
+       "botpasswords-created-title": "تÙ\85 Ø¥Ù\86شاء Ù\83Ù\84Ù\85Ø© Ø³Ø± Ø¨Ù\88ت",
+       "botpasswords-created-body": "تم إنشاء كلمة سر بوت \"$1\" للمستخدم \"$2\".",
+       "botpasswords-updated-title": "تم تحديث كلمة سر البوت",
+       "botpasswords-updated-body": "كلمة سر البوت \"$1\" للمستخدم \"$2\" تم تحديثها.",
        "botpasswords-deleted-title": "كلمة سر البوت حذفت",
-       "botpasswords-deleted-body": "كلمة سر البوت\"$1\" قد حذفت.",
+       "botpasswords-deleted-body": "كلمة سر البوت \"$1\" لمستخدم \"$2\" قد حذفت.",
+       "botpasswords-newpassword": "كلمة السر الجديدة لتسجيل الدخول ب <strong>$1</strong> هي <strong>$2</strong>. <em>من فضلك سجل هذه كمرجع في المستقبل .</em>",
        "botpasswords-no-provider": "BotPasswordsSessionProvider غير متاح.",
        "botpasswords-restriction-failed": "قيود كلمة مرور البوت تمنع هذا الولوج.",
+       "botpasswords-invalid-name": "اسم المستخدم الموفر لا يحتوي على فاصل كلمة سر البوت (\"$1\").",
+       "botpasswords-not-exist": "المستخدم \"$1\" لا يمتلك كلمة سر بوت بالاسم \"$2\".",
        "resetpass_forbidden": "كلمات السر لا يمكن تغييرها",
        "resetpass_forbidden-reason": "لا يمكن تغيير كلمة المرور: $1",
        "resetpass-no-info": "يجب أن تكون مسجل الدخول للوصول إلى هذه الصفحة مباشرة.",
        "passwordreset-emailelement": "اسم {{GENDER:$1\n|المستخدم|المستخدمة}}: \n$1\n\nكلمة السر المؤقتة: \n$2",
        "passwordreset-emailsentemail": "إذا كان هذا العنوان البريد مرتبط بحسابك، من ثم سيتم إرسال بريد إلكتروني لإعادة تعيين كلمة السر.",
        "passwordreset-emailsentusername": "إذا كان هناك عنوان بريد إلكتروني مرتبط بهذا المستخدم، ثم سيتم إرسال بريد إلكتروني لإعادة تعيين كلمة السر.",
+       "passwordreset-emailsent-capture2": "{{PLURAL:$1|رسالة|رسائل}} البريد الإلكتروني لضبط كلمة السر تم إرسالها. {{PLURAL:$1|اسم المستخدم وكلمة السر معروضان|قائمة أسماء المستخدمين وكلمات السر معروضة}} بالأسفل.",
+       "passwordreset-emailerror-capture2": "إرسال بريد إلى {{GENDER:$2|المستخدم|المستخدمة}} فشل: $1 {{PLURAL:$3|اسم المستخدم وكلمة السر معروضان|lقائمة أسماء المستخدمين كلمات السر معروضة}} بالأسفل.",
+       "passwordreset-nocaller": "يجب أن يتم توفير مستدعي",
+       "passwordreset-nosuchcaller": "المستدعي غير موجود: $1",
+       "passwordreset-ignored": "إعادة ضبط كلمة السر لم تتم التعامل معها. ربما لا موفر تم ضبطه؟",
        "passwordreset-invalideamil": "عنوان بريد إلكتروني غير صالح",
+       "passwordreset-nodata": "لا اسم مستخدم ولا عنوان بريد الإلكتروي تم توفيره",
        "changeemail": "تغيير أو إزالة عنوان البريد الإلكتروني",
        "changeemail-header": "إكمال هذا النموذج لتغيير عنوان البريد الإلكتروني الخاص بك. إذا كنت ترغب في إزالة جمعية أي عنوان البريد الإلكتروني من حسابك، وترك الفراغ عنوان البريد الإلكتروني الجديد عند تقديم النموذج",
        "changeemail-no-info": "يجب تسجيل الدخول للوصول إلى هذه الصفحة مباشرة.",
        "changeemail-oldemail": "عنوان البريد الإلكتروني الحالي:",
        "changeemail-newemail": "عنوان البريد الإلكتروني الجديد:",
+       "changeemail-newemail-help": "هذا الحقل ينبغي أن يترك فارغا في حالة لو كنت تريد إزالة عنوان البريد الإلكتروني الخاص بك. أنت لن تكون قادرا على إعادة ضبط كلمة سر ضائعة ولن تتلقى رسئل بريد إلكتروني من هذه الويكي لو أزيل عنوان البريد الإلكتروني.",
        "changeemail-none": "(لا شيء)",
        "changeemail-password": "كلمة سر {{SITENAME}} الخاصة بك:",
        "changeemail-submit": "غيّر البريد الإلكتروني",
        "accmailtext": "أُرسِلت كلمة سر مولدة عشوائيا ل[[User talk:$1|$1]] إلى $2. يمكن تغييرها في صفحة ''[[Special:ChangePassword|تغيير كلمة السر]]'' بعد تسجيل الدخول.",
        "newarticle": "(جديد)",
        "newarticletext": "لقد تبعت وصلة لصفحة لم يتم إنشائها بعد.\nلإنشاء هذه الصفحة ابدأ الكتابة في الصندوق بالأسفل (انظر في [$1 صفحة المساعدة] للمزيد من المعلومات).\nإذا كانت زيارتك لهذه الصفحة بالخطأ، اضغط على زر ''رجوع'' في متصفح الإنترنت لديك.",
-       "anontalkpagetext": "----''هذه صفحة نقاش لمستخدم مجهول لم يقم بإنشاء حساب بعد أو لا يستعمل ذلك الحساب.\nلذا فيجب علينا استعمال رقم الأيبي للتعرف عليه/عليها.\nمثل هذا العنوان يمكن أن يشترك فيه عدة مستخدمين.\nلو كنت مستخدما مجهولا وتشعر بأن تعليقات لا تخصك تم توجيهها إليك، من فضلك [[Special:CreateAccount|أنشئ حسابا]] أو [[Special:UserLogin|سجل الدخول]] لتجنب الارتباك المستقبلي مع مستخدمين مجهولين آخرين.''",
+       "anontalkpagetext": "----\n<em>هذه صفحة نقاش لمستخدم مجهول لم يقم بإنشاء حساب بعد أو لا يستعمل ذلك الحساب.</em>\nلذا فيجب علينا استعمال رقم الأيبي للتعرف عليه/عليها.\nمثل هذا العنوان يمكن أن يشترك فيه عدة مستخدمين.\nلو كنت مستخدما مجهولا وتشعر بأن تعليقات لا تخصك تم توجيهها إليك، من فضلك [[Special:CreateAccount|أنشئ حسابا]] أو [[Special:UserLogin|سجل الدخول]] لتجنب الارتباك المستقبلي مع مستخدمين مجهولين آخرين.",
        "noarticletext": "الصفحة خالية. يمكنك [[Special:Search/{{PAGENAME}}|البحث عن عنوانها]] في الصفحات الأخرى أو\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} البحث في السجلات] (لتعرف إذا حذفت)،\nأو '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} إنشاؤها بنفسك]'''</span>.",
        "noarticletext-nopermission": "لا يوجد حاليا أي نص في هذه الصفحة.\nيمكنك [[Special:Search/{{PAGENAME}}|البحث عن عنوان هذه الصفحة]] في الصفحات الأخرى، أو <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} البحث في السجلات المتعلقة بها]</span>، لكنك لست مخولاً لإنشاء هذه الصفحة.",
        "missing-revision": "المراجعة #$1 من الصفحة المسماة \"{{FULLPAGENAME}}\" غير موجودة.\n\nهذا يحدث عادة عن طريق اتباع وصلة تاريخ قديمة لصفحة تم حذفها.\nالتفاصيل يمكن إيجادها في [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} سجل الحذف].",
        "userpage-userdoesnotexist": "حساب المستخدم \"<nowiki>$1</nowiki>\" غير مسجل.\nمن فضلك تأكد أنك تريد إنشاء/تعديل هذه الصفحة.",
        "userpage-userdoesnotexist-view": "حساب المستخدم \"$1\" غير مسجل.",
        "blocked-notice-logextract": "هذا المستخدم ممنوع حاليا.\nآخر مدخلة في سجل المنع موفرة بالأسفل كمرجع:",
-       "clearyourcache": "'''ملاحظة:''' بعد الحفظ، قد تحتاج إلى إفراغ كاش متصفحك لرؤية التغييرات.\n* '''فايرفوكس / سفاري:''' اضغط ''Shift'' أثناء ضغط ''Reload''، أو اضغط أيا من ''Ctrl-F5'' أو ''Ctrl-R'' (''⌘-R'' على ماك)\n* '''جوجل كروم:''' اضغط ''Ctrl-Shift-R'' (''⌘-Shift-R'' على ماك)\n* '''إنترنت إكسبلورر:''' اضغط ''Ctrl'' أثناء ضغط ''Refresh''، أو اضغط ''Ctrl-F5''\n* '''كنكرر:''' اضغط ''Reload'' أو اضغط ''F5''\n* '''أوبرا:''' أفرغ الكاش في ''Tools → Preferences''",
+       "clearyourcache": "<strong>ملاحظة:</strong> بعد الحفظ، أنت قد تحتاج إلى إفراغ الكاش الخاص بمتصفحك لرؤية التغييرات.\n* <strong>فايرفوكس / سافاري:</strong> أمسك <em>Shift</em> أثناء ضغط <em>Reload</em>، أو اضغط على إما <em>Ctrl-F5</em> أو <em>Ctrl-R</em> (<em>⌘-R</em> على ماك)\n* <strong>جوجل كروم:</strong> اضغط <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> على ماك)\n* <strong>إنترنت إكسبلورر:</strong> أمسك <em>Ctrl</em> أثناء ضغط <em>Refresh</em>، أو اضغط <em>Ctrl-F5</em>\n* <strong>أوبرا:</strong> اذهب إلى <em>Menu → Settings</em> (<em>Opera → Preferences</em> على ماك) ثم إلى <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "'''ملاحظة:''' استعمل زر \"{{int:showpreview}}\" لتجربة CSS الجديد قبل حفظ الصفحة.",
        "userjsyoucanpreview": "'''ملاحظة:''' استعمل زر \"{{int:showpreview}}\" لتجربة جافاسكربت الجديدة قبل حفظ الصفحة.",
        "usercsspreview": "'''تذكر أنك تقوم بعرض الأنماط المتراصة (CSS) الخاصة بك فقط\nلم يتم حفظها بعد!'''",
        "permissionserrors": "خطأ في السماح",
        "permissionserrorstext": "لا تمتلك الصلاحية لفعل هذا، {{PLURAL:$1||للسبب التالي|للسببين التاليين|للأسباب التالية}}:",
        "permissionserrorstext-withaction": "لا تملك الصلاحيات ل$2، لل{{PLURAL:$1||سبب التالي|سببين التاليين|أسباب التالية}}:",
+       "contentmodelediterror": "أنت لا يمكنك تعديل هذه المراجعة لأن موديل محتواها هو  <code>$1</code>، والذي يختلف عن موديل المحتوى الحالي للصفحة  <code>$2</code>.",
        "recreate-moveddeleted-warn": "'''تحذير: أنت تعيد إنشاء صفحة سبق حذفها.'''\n\nيجب عليك التيقن من أن الاستمرار بتحرير هذه الصفحة ملائم.\nسجلا الحذف والنقل لهذه الصفحة معروضان هنا للتيسير:",
        "moveddeleted-notice": "هذه الصفحة تم حذفها.\nسجلا الحذف والنقل للصفحة معروضان بالأسفل كمرجع.",
+       "moveddeleted-notice-recent": "عذرا، هذه الصفحة تم حذفها مؤخرا (في آخر 24 ساعة).\nسجلا الحذف والنقل للصفحة معروضان بالأسفل كمرجع.",
        "log-fulllog": "أظهر السجل الكامل",
        "edit-hook-aborted": "التعديل تم تركه بواسطة الخطاف.\nلم يعط تفسيرا.",
        "edit-gone-missing": "لم يمكن تحديث الصفحة.\nيبدو أنه تم حذفها.",
        "content-model-text": "نص عادي",
        "content-model-javascript": "جافاسكربت",
        "content-model-css": "CSS",
-       "content-json-empty-object": "غرض فارغ",
+       "content-json-empty-object": "كائن فارغ",
        "content-json-empty-array": "مصفوفة فارغة",
        "deprecated-self-close-category": "صفحات تستخدم وسوم أتش تي أم أل غير صالحة",
+       "deprecated-self-close-category-desc": "هذه الصفحة تحتوي على وسوم HTML مغلقة ذاتيا، مثل  <code>&lt;b/></code> أو <code>&lt;span/></code>. سلوك هذه سيتغير سريعا ليكون متوافقا مع معيار HTML5، لذا فاستخدامهم في نص الويكي ينبغي أن يتم الاستغناء عنه.",
        "duplicate-args-warning": "<strong>تنبيه:</strong> المدخل \"$3\" ل[[:$1]] المستعمل في [[:$2]] مكرر. آخر قيمة مكرر منه هي المعتمدة.",
        "duplicate-args-category": "صفحات تستعمل قالبا ببيانات مكررة",
        "duplicate-args-category-desc": "تحوي هذه الصفحة استدعاءات قالب تستخدم متغيرات مزدوجة مثل <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> أو <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "revdel-restore": "تغيير الرؤية",
        "pagehist": "تاريخ الصفحة",
        "deletedhist": "التاريخ المحذوف",
-       "revdelete-hide-current": "خطأ Ø¹Ù\86د Ø¥Ø­فاء العنصر المؤرخ في $2 $1: هذه هي المراجعة الحالية.\nلا يمكن إخفاؤها.",
+       "revdelete-hide-current": "خطأ Ø¹Ù\86د Ø¥Ø®فاء العنصر المؤرخ في $2 $1: هذه هي المراجعة الحالية.\nلا يمكن إخفاؤها.",
        "revdelete-show-no-access": "خطأ في إظهار العنصر ذا التاريخ $2 $1: هذا العنصر معلم ك\"مقيد\".\nليس لك صلاحية الوصول إليه.",
        "revdelete-modify-no-access": "خطأ في تعديل العنصر ذا التاريخ $2 $1: هذا العنصر معلم ك\"مقيد\".\nليس لك صلاحية الوصول إليه.",
        "revdelete-modify-missing": "خطأ في تعديل العنصر ذا الهوية $1: العنصر مفقود من قاعدة البيانات!",
        "mergehistory-go": "عرض التعديلات القابلة للدمج",
        "mergehistory-submit": "دمج المراجعات",
        "mergehistory-empty": "لا مراجعات يمكن دمجها.",
-       "mergehistory-done": "$3 {{PLURAL:$3|مراجعة|مراجعة}} من $1{{PLURAL:$3|كان|اين}} تم دمجها بنجاح في [[:$2]].",
+       "mergehistory-done": "$3 {{PLURAL:$3|مراجعة}} من $1{{PLURAL:$3|كان|اين}} تم دمجها بنجاح في [[:$2]].",
        "mergehistory-fail": "غير قادر على عمل دمج التاريخ، من فضلك أعد التحقق من محددات الصفحة والزمن.",
        "mergehistory-fail-bad-timestamp": "الختم الزمني غير صالح.",
        "mergehistory-fail-invalid-source": "الصفحة المصدر غير صالحة.",
        "localtime": "الوقت المحلي:",
        "timezoneuseserverdefault": "استخدام الويكي الافتراضي ($1)",
        "timezoneuseoffset": "آخر (حدد الفرق)",
-       "servertime": "Ù\88Ù\82ت Ø§Ù\84خادÙ\88Ù\85:",
+       "servertime": "وقت الخادم:",
        "guesstimezone": "أدخل التوقيت من المتصفح",
        "timezoneregion-africa": "أفريقيا",
        "timezoneregion-america": "أمريكا",
        "prefs-files": "ملفات",
        "prefs-custom-css": "CSS مخصص",
        "prefs-custom-js": "جافاسكربت مخصص",
-       "prefs-common-css-js": "سي إس إس وجافاسكربت مشترك لجميع المظاهر:",
+       "prefs-common-css-js": "CSS وجافاسكربت مشترك لجميع الواجهات:",
        "prefs-reset-intro": "يمكنك استخدام هذه الصفحة لإعادة تفضيلاتك للحالة الافتراضية للموقع.\nلن تستطيع استرجاع الحالة السابقة.",
        "prefs-emailconfirm-label": "تأكيد البريد الإلكتروني:",
        "youremail": "البريد:",
        "userrights-removed-self": "أزلت بنجاح صلاحياتك، ولن تتمكن من الوصول لهذه الصفحة مجددا.",
        "group": "المجموعة:",
        "group-user": "مستخدمون",
-       "group-autoconfirmed": "مستخدمون مؤكدون تلقائياً",
+       "group-autoconfirmed": "مستخدمون مؤكدون تلقائيا",
        "group-bot": "بوتات",
-       "group-sysop": "مديرو نظام",
+       "group-sysop": "إداريون",
        "group-bureaucrat": "بيروقراطيون",
        "group-suppress": "مزيلون",
        "group-all": "(الكل)",
        "group-bureaucrat-member": "{{GENDER:$1|بيروقراط}}",
        "group-suppress-member": "{{GENDER:$1|مزيل|مزيلة}}",
        "grouppage-user": "{{ns:project}}:مستخدمون",
-       "grouppage-autoconfirmed": "{{ns:project}}:مستخدمون مؤكدون تلقائياً",
+       "grouppage-autoconfirmed": "{{ns:project}}:مستخدمون مؤكدون تلقائيا",
        "grouppage-bot": "{{ns:project}}:بوتات",
        "grouppage-sysop": "{{ns:project}}:إداريون",
        "grouppage-bureaucrat": "{{ns:project}}:بيروقراطيون",
        "right-move": "نقل الصفحات",
        "right-move-subpages": "نقل الصفحات مع صفحاتها الفرعية",
        "right-move-rootuserpages": "نقل صفحات المستخدمين الأساسية",
-       "right-move-categorypages": "انقل صفحات التصنيف",
+       "right-move-categorypages": "نقل صفحات التصنيف",
        "right-movefile": "نقل الملفات",
        "right-suppressredirect": "عدم إنشاء تحويلة من الاسم القديم عند نقل صفحة",
        "right-upload": "رفع الملفات",
        "right-writeapi": "استخدام API للكتابة",
        "right-delete": "حذف الصفحات",
        "right-bigdelete": "حذف الصفحات ذات التواريخ الكبيرة",
-       "right-deletelogentry": "حذÙ\81 Ù\88اÙ\84غاء Ø­Ø°Ù\81 Ø¥Ø¯Ø®Ø§Ù\84ات Ø³Ø¬Ù\84 Ù\85عÙ\8aÙ\86",
+       "right-deletelogentry": "حذÙ\81 Ù\88Ø¥Ù\84غاء Ø­Ø°Ù\81 Ù\85دخÙ\84ات Ø³Ø¬Ù\84 Ù\85عÙ\8aÙ\86Ø©",
        "right-deleterevision": "حذف واسترجاع مراجعات معينة من الصفحات",
        "right-deletedhistory": "رؤية مدخلات التاريخ المحذوفة، بدون نصوصها المصاحبة",
        "right-deletedtext": "عرض النص المحذوف والتغييرات بين المراجعات المحذوفة",
        "right-browsearchive": "البحث في الصفحات المحذوفة",
        "right-undelete": "استرجاع صفحة",
        "right-suppressrevision": "مراجعة واسترجاع المراجعات المخفية عن مديري النظام",
-       "right-viewsuppressed": "أعرض Ø§Ù\84Ù\85راجعات Ø§Ù\84Ù\85Ø®Ù\81Ù\8aØ© Ø¨Ù\88اسطة Ø£Ù\8a Ù\85ستخدÙ\85",
+       "right-viewsuppressed": "عرض المراجعات المخفية بواسطة أي مستخدم",
        "right-suppressionlog": "رؤية السجلات السرية",
        "right-block": "منع المستخدمين الآخرين من التعديل",
        "right-blockemail": "منع مستخدم من إرسال بريد إلكتروني",
        "right-editinterface": "تعديل واجهة المستخدم",
        "right-editusercssjs": "تعديل ملفات CSS و JS للمستخدمين الآخرين",
        "right-editusercss": "تعديل ملفات CSS للمستخدمين الآخرين",
-       "right-edituserjs": "تعديل ملفات JS للمستخدمين الآخرين",
+       "right-edituserjs": "تعديل ملفات جافاسكريبت للمستخدمين الآخرين",
        "right-editmyusercss": "تعديل ملفات CSS للمستخدم نفسه",
        "right-editmyuserjs": "تعديل ملفات جافاسكربت للمستخدم نفسه",
        "right-viewmywatchlist": "عرض قائمة مراقبتك",
        "right-editmywatchlist": "حرر قائمة مراقبتك. لاحظ أن بعض الإجراءات لا تزال تضيف الصفحات حتى بدون هذا الحق.",
-       "right-viewmyprivateinfo": "إستعرض Ø¨Ù\8aاÙ\86اتÙ\83 Ø§Ù\84شخصÙ\8aØ© (Ù\85Ø«Ù\84 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\88اÙ\84Ø¥سم الحقيقي)",
-       "right-editmyprivateinfo": "حرر Ø¨Ù\8aاÙ\86اتÙ\83 Ø§Ù\84شخصÙ\8aØ© (Ù\85Ø«Ù\84 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\88اÙ\84Ø¥سم الحقيقي)",
+       "right-viewmyprivateinfo": "استعراض Ø¨Ù\8aاÙ\86اتÙ\83 Ø§Ù\84شخصÙ\8aØ© (Ù\85Ø«Ù\84 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\88اÙ\84اسم الحقيقي)",
+       "right-editmyprivateinfo": "تعدÙ\8aÙ\84 Ø¨Ù\8aاÙ\86اتÙ\83 Ø§Ù\84شخصÙ\8aØ© (Ù\85Ø«Ù\84 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\88اÙ\84اسم الحقيقي)",
        "right-editmyoptions": "تعديل تفضيلاتك",
        "right-rollback": "استرجاع تعديلات آخر مستخدم عدل صفحة معينة سريعا",
        "right-markbotedits": "التعليم على تعديلات الاسترجاع كتعديلات بوت",
        "right-import": "استيراد الصفحات من ويكيات أخرى",
        "right-importupload": "استيراد الصفحات من ملف مرفوع",
        "right-patrol": "تعليم تعديلات الآخرين بعلامة المراجعة",
-       "right-autopatrol": "عÙ\84Ù\85 ØªØ¹Ø¯Ù\8aÙ\84ات Ø§Ù\84Ù\85ستخدÙ\85 مراجعة تلقائيا",
+       "right-autopatrol": "اÙ\84تعÙ\84Ù\8aÙ\85 Ø¹Ù\84Ù\89 ØªØ¹Ø¯Ù\8aÙ\84ات Ø§Ù\84Ù\85ستخدÙ\85 Ù\83مراجعة تلقائيا",
        "right-patrolmarks": "رؤية علامات المراجعة في أحدث التغييرات",
        "right-unwatchedpages": "رؤية قائمة بالصفحات غير المراقبة",
        "right-mergehistory": "دمج تاريخ الصفحات",
        "right-override-export-depth": "تصدير الصفحات متضمنة الصفحات الموصولة حتى عمق 5",
        "right-sendemail": "إرسال رسائل بريد إلكتروني إلى مستخدمين آخرين",
        "right-passwordreset": "عرض رسائل إعادة ضبط كلمات السر",
-       "right-managechangetags": "Ø¥Ù\86شاء Ù\88حذÙ\81 [[Special:Tags|اÙ\84Ù\88سÙ\88Ù\85]] Ù\85Ù\86 Ù\82اعدة Ø§Ù\84بÙ\8aاÙ\86ات",
+       "right-managechangetags": "Ø¥Ù\86شاء Ù\88تعطÙ\8aÙ\84 [[Special:Tags|اÙ\84Ù\88سÙ\88Ù\85]]",
        "right-applychangetags": "تطبيق [[Special:Tags|الوسوم]]  مع التغييرات التي أجريتها.",
+       "right-changetags": "إضافة وإزالة [[Special:Tags|وسوم]] في مراجعات ومدخلات سجل فردية",
+       "right-deletechangetags": "حذف [[Special:Tags|الوسوم]] من قاعدة البيانات",
        "grant-generic": "\"$1\" حزمة الصلاحيات",
        "grant-group-page-interaction": "التفاعل مع الصفحات",
        "grant-group-file-interaction": "التفاعل مع الوسائط",
        "grant-group-high-volume": "أداء نشاط كبير الحجم",
        "grant-group-customization": "التخصيص والتفضيلات",
        "grant-group-administration": "أداء عمليات إدارية",
+       "grant-group-private-information": "الوصول للبيانات السرية المتعلقة بك",
        "grant-group-other": "نشاطات متفرقة",
        "grant-blockusers": "منع ورفع المنع عن المستخدمين",
        "grant-createaccount": "إنشاء حسابات",
        "grant-createeditmovepage": "إنشاء وتعديل ونقل الصفحات",
        "grant-delete": "حذف الصفحات والمراجعات ومدخلات السجلات",
+       "grant-editinterface": "تعديل نطاق ميدياويكي والCSS/JavaScript الخاصة بالمستخدم",
+       "grant-editmycssjs": "تعديل الCSS/JavaScript الخاصة بحسابك",
        "grant-editmyoptions": "تعديل تفضيلاتك",
        "grant-editmywatchlist": "تعديل قائمة مراقبتك",
        "grant-editpage": "تعديل صفحات موجودة",
        "grant-editprotected": "تعديل صفحات محمية",
        "grant-highvolume": "تعديل كبير الحجم",
+       "grant-oversight": "إخفاء المستخدمين وإخفاء المراجعات",
        "grant-patrol": "تغييرات دورية للصفحات",
+       "grant-privateinfo": "الوصول للمعلومات السرية",
        "grant-protect": "حماية وإزالة حماية الصفحات",
        "grant-rollback": "استرجاع التغييرات في الصفحات",
        "grant-sendemail": "إرسال بريد إلكتروني للمستخدمين الآخرين",
        "action-read": "قراءة هذه الصفحة",
        "action-edit": "تعديل هذه الصفحة",
        "action-createpage": "إنشاء هذه الصفحة",
-       "action-createtalk": "Ø¥Ù\86شاء ØµÙ\81حات Ø§Ù\84Ù\86Ù\82اش",
+       "action-createtalk": "Ø¥Ù\86شاء ØµÙ\81حة Ø§Ù\84Ù\86Ù\82اش Ù\87Ø°Ù\87",
        "action-createaccount": "إنشاء حساب المستخدم هذا",
-       "action-autocreateaccount": "تلقائيا إنشاء هذا الحساب مستخدم خارجي",
+       "action-autocreateaccount": "تلقائيا إنشاء هذا الحساب الخارجي للمستخدم",
        "action-history": "اعرض تاريخ هذه الصفحة",
        "action-minoredit": "التعليم على هذا التعديل كطفيف",
        "action-move": "نقل هذه الصفحة",
        "action-viewmyprivateinfo": "مشاهدة معلوماتك الخاصة",
        "action-editmyprivateinfo": "تعديل معلوماتك الخاصة",
        "action-editcontentmodel": "عدل عدل طريقة محتوى صفحة",
-       "action-managechangetags": "Ø¥Ù\86شاء Ù\88حذÙ\81 Ø§Ù\84Ù\88سÙ\88Ù\85 Ù\85Ù\86 Ù\82اعدة Ø§Ù\84بÙ\8aاÙ\86ات",
+       "action-managechangetags": "Ø¥Ù\86شاء Ù\88تعطÙ\8aÙ\84 Ø§Ù\84Ù\88سÙ\88Ù\85",
        "action-applychangetags": "تطبيق الوسوم مع تغييراتك",
+       "action-changetags": "أضف وأزل وسوما في مراجعات ومدخلات سجل فردية",
+       "action-deletechangetags": "حذف الوسوم من قاعدة البيانات",
+       "action-purge": "إفراغ كاش هذه الصفحة",
        "nchanges": "{{PLURAL:$1|لا تغييرات|تغيير واحد|تغييران|$1 تغييرات|$1 تغييرا|$1 تغيير}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|منذ الزيارة الأخيرة}}",
        "enhancedrc-history": "تاريخ",
        "recentchangeslinked-page": "اسم الصفحة:",
        "recentchangeslinked-to": "أظهر التغييرات للصفحات الموصولة للصفحة المعطاة عوضاً عن ذلك",
        "recentchanges-page-added-to-category": "[[:$1]] أضيفت إلى التصنيف",
-       "recentchanges-page-added-to-category-bundled": "أضيفت [[:$1]] و{{PLURAL:$2|صفحة واحدة|صفحتان|$2 صفحات}} إلى التصنيف",
+       "recentchanges-page-added-to-category-bundled": "أضيفت [[:$1]] إلى التصنيف، [[Special:WhatLinksHere/$1|هذه الصفحة مضمنة في صفحات اخرى]]",
        "recentchanges-page-removed-from-category": "أزيلت [[:$1]] من التصنيف",
-       "recentchanges-page-removed-from-category-bundled": "أزÙ\8aÙ\84ت [[:$1]] Ù\88{{PLURAL:$2|صÙ\81حة Ù\88احدة|صÙ\81حتاÙ\86|$2 ØµÙ\81حات}} Ù\85Ù\86 Ø§Ù\84تصÙ\86Ù\8aÙ\81",
+       "recentchanges-page-removed-from-category-bundled": "أزÙ\8aÙ\84ت [[:$1]] Ù\85Ù\86 Ø§Ù\84تصÙ\86Ù\8aÙ\81Ø\8c [[Special:WhatLinksHere/$1|Ù\87Ø°Ù\87 Ø§Ù\84صÙ\81حة Ù\85ضÙ\85Ù\86Ø© Ù\81Ù\8a ØµÙ\81حات Ø£Ø®Ø±Ù\89]]",
        "autochange-username": "تغيير آلي لميدياويكي",
        "upload": "ارفع ملفا",
        "uploadbtn": "ارفع الملف",
        "uploaddisabledtext": "رفع الملفات معطل.",
        "php-uploaddisabledtext": "رفع ملفات PHP معطل. من فضلك تحقق من إعدادات رفع الملفات.",
        "uploadscripted": "هذا الملف يضم كود HTML أو كود آخر يمكن أن يفسره متصفح الوب بطريقة خاطئة.",
+       "upload-scripted-pi-callback": "لا يمكن رفع ملف يحتوي على تعليمة معالجة XML-stylesheet",
+       "uploaded-script-svg": "تم العثور على عنصر سكريبت \"$1\" في ملف الSVG المرفوع.",
+       "uploaded-hostile-svg": "تم العثور على CSS غير آمن في عنصر الشكل في ملف الSVG المرفوع.",
+       "uploaded-event-handler-on-svg": "ضبط سمات معالج الأحداث <code>$1=\"$2\"</code> غير مسموح به في ملفات SVG.",
+       "uploaded-href-attribute-svg": "سمات href في ملفات SVG مسموح بوصلها فقط بأهداف http:// أو https:// ، تم العثور على <code>&lt;$1 $2=\"$3\"&gt;</code>.",
+       "uploaded-href-unsafe-target-svg": "تم العثور على href لبيانات غير آمنة: هدف URI <code>&lt;$1 $2=\"$3\"&gt;</code> في ملف SVG المرفوع.",
+       "uploaded-animate-svg": "تم العثور على وسم \"animate\" الذي ربما يكون يغير href, باستخدام سمة \"from\" <code>&lt;$1 $2=\"$3\"&gt;</code> في ملف SVG المرفوع.",
+       "uploaded-setting-event-handler-svg": "ضبط سمات معالج الأحداث ممنوع، تم العثور على <code>&lt;$1 $2=\"$3\"&gt;</code> في ملف SVG المرفوع.",
+       "uploaded-setting-href-svg": "استخدام وسم \"set\" لإضافة سمة \"href\" للعنصر الأب ممنوع.",
+       "uploaded-wrong-setting-svg": "استخدام وسم \"set\" لإضافة هدف خارجي/بيانات/سكريبت لأي سمة ممنوع. تم العثور على <code>&lt;set to=\"$1\"&gt;</code> في ملف SVG المرفوع.",
+       "uploaded-setting-handler-svg": "SVG الذي يضبط سمة \"handler\" مع خارجي/بيانات/سكريبت ممنوع. تم العثور على <code>$1=\"$2\"</code> في ملف SVG المرفوع.",
+       "uploaded-remote-url-svg": "SVG الذي يضبط أي سمة شكل مع URL خارجي ممنوع. تم العثور على <code>$1=\"$2\"</code> في ملف SVG المرفوع.",
+       "uploaded-image-filter-svg": "تم العثور على فلتر صورة مع URL: <code>&lt;$1 $2=\"$3\"&gt;</code> في ملف SVG المرفوع.",
        "uploadscriptednamespace": "يحتوي ملف SVG هذا على اسم نطاق غير مشروع \" $1 \"",
        "uploadinvalidxml": "تعذر تحليل XML في الملف المرفوع.",
        "uploadvirus": "الملف يحتوي على فيروس! التفاصيل: $1",
        "upload-options": "خيارات الرفع",
        "watchthisupload": "راقب هذا الملف",
        "filewasdeleted": "تم رفع ثم حذف ملف بهذا الاسم من قبل.\nمن الأفضل مراجعة $1 قبل رفعه مرة أخرى.",
+       "filename-thumb-name": "هذا يبدو وكأنه عنوان صورة مصغرة. من فضلك لا ترفع صورة مصغرة لنفس الويكي مرة ثانية. أو، من فضلك أصلح اسم الملف بحيث يكون معبرا أكثر، ولا يحتوي على بادئة الصورة المصغرة.",
        "filename-bad-prefix": "اسم الملف الذي ترفعه يبدأ ب'''\"$1\"'''، وهو اسم غير وصفي غالباً ما تخصصه الكاميرات الرقمية تلقائياً.\nمن فضلك اختر اسماً يصف ملفك بوضوح أكثر.",
        "filename-prefix-blacklist": " #<!-- اترك هذا السطر تماما كما هو --> <pre>\n# الصيغة كالتالي:\n#   * كل شيء من علامة \"#\" إلى آخر السطر هو تعليق\n#   * كل سطر غير فارغ هو بادئة لأسماء الملفات النمطية التي توضع تلقائيا بواسطة الكاميرات الرقمية\nCIMG # كاسيو\nDSC_ # نيكون\nDSCF # فوجي\nDSCN # نيكون\nDUW # بعض الهواتف المحمولة\nIMG # عام\nJD # جينوبتيك\nMGP # بينتاكس\nPICT # متنوع\n #</pre> <!-- اترك هذا السطر تماما كما هو -->",
        "upload-proto-error": "بروتوكول غير صحيح",
        "upload-too-many-redirects": "احتوى المسار تحويلات كثيرة جدا",
        "upload-http-error": "صودف خطأ HTTP: $1",
        "upload-copy-upload-invalid-domain": "رفع النسخ غير متاح من هذا الموقع",
+       "upload-foreign-cant-upload": "هذه الويكي ليست مضبوطة لرفع الملفات لمستودع الملفات الخارجي المطلوب.",
+       "upload-foreign-cant-load-config": "فشل تحميل الإعدادات للملفات المرفوعة لمستودع الملفات الخارجي.",
+       "upload-dialog-disabled": "رفع الملفات باستخدام هذا الحوار معطلة على هذه الويكي.",
        "upload-dialog-title": "رفع الملف",
        "upload-dialog-button-cancel": "إلغاء",
        "upload-dialog-button-done": "تم",
        "upload-dialog-button-upload": "رفع",
        "upload-form-label-infoform-title": "التفاصيل",
        "upload-form-label-infoform-name": "الاسم",
+       "upload-form-label-infoform-name-tooltip": "عنوان وصفي فريد للملف، والذي سيكون اسم الملف. يمكنك أن تستخدم لغة عادية مع مسافات. لا تضمن امتداد الملف.",
        "upload-form-label-infoform-description": "الوصف",
+       "upload-form-label-infoform-description-tooltip": "باختصار صف كل شيء ملحوظ حول العمل.\nلصورة، اذكر الأشياء الأساسية المصورة، المناسبة أو المكان.",
        "upload-form-label-usage-title": "الاستخدام",
        "upload-form-label-usage-filename": "اسم الملف",
        "upload-form-label-own-work": "هذا عملي الخاص",
        "upload-form-label-infoform-categories": "تصنيفات",
        "upload-form-label-infoform-date": "التاريخ",
+       "upload-form-label-own-work-message-generic-local": "أنا أؤكد أنني أقوم برفع هذا الملف مع مراعاة شروط الخدمة وسياسات الترخيص في {{SITENAME}}.",
+       "upload-form-label-not-own-work-message-generic-local": "لو أنك غير قادر على رفع هذا الملف تحت سياسات {{SITENAME}}، من فضلك أغلق هذا الحوار وجرب طريقة أخرى.",
+       "upload-form-label-not-own-work-local-generic-local": "أنت ربما تريد تجربة [[Special:Upload|صفحة الرفع الافتراضية]].",
+       "upload-form-label-own-work-message-generic-foreign": "أنا أفهم أنني أقوم برفع هذا الملف إلى مستودع مشترك. أنا أؤكد أنني أقوم بهذا بالتوافق مع شروط الخدمة وسياسات الترخيص هناك.",
+       "upload-form-label-not-own-work-message-generic-foreign": "لو أنك غير قادر على رفع هذا الملف تحت سياسات المستودع المشترك، من فضلك أغلق هذا الحوار وجرب طريقة أخرى.",
+       "upload-form-label-not-own-work-local-generic-foreign": "أنت ربما تريد أيضا تجربة [[Special:Upload|صفحة الرفع على {{SITENAME}}]]، لو أن هذا الملف يمكن رفعه هناك تحت سياساتهم.",
        "backend-fail-stream": "لا يمكن عرض الملف $1.",
        "backend-fail-backup": "لا يمكن صنع نسخة أحتياطية للملف $1.",
        "backend-fail-notexists": "الملف $1 غير موجود.",
-       "backend-fail-hashes": "لم يمكن الحصول على هاش الملف من أجل المقارنة",
-       "backend-fail-notsame": "يوجد بالفعل ملف غير متطابق في $1.",
-       "backend-fail-invalidpath": "$1 ليس مساراً صالحاً للتخزين.",
-       "backend-fail-delete": "لم يمكن حذف الملف $1.",
-       "backend-fail-describe": "Ù\84ا Ù\8aÙ\85Ù\83Ù\86 ØªØºÙ\8aÙ\8aر Ø§Ù\84بÙ\8aاÙ\86ات Ø§Ù\84تعرÙ\8aÙ\81 (metadata) Ù\84Ù\84Ù\85Ù\84Ù\81 \" $1 \".",
-       "backend-fail-alreadyexists": "الملف $1 موجود بالفعل.",
-       "backend-fail-store": "لا يمكن تخزين الملف $1 في $2 .",
-       "backend-fail-copy": "لا يمكن نسخ الملف  $1  إلى  $2 .",
-       "backend-fail-move": "تعذر نقل ملف $1 إلى $2 .",
+       "backend-fail-hashes": "لم يمكن الحصول على hashes الملفات من أجل المقارنة",
+       "backend-fail-notsame": "يوجد بالفعل ملف غير متطابق في \"$1\".",
+       "backend-fail-invalidpath": "\"$1\" ليس مساراً صالحاً للتخزين.",
+       "backend-fail-delete": "لم يمكن حذف الملف \"$1\".",
+       "backend-fail-describe": "Ù\84ا Ù\8aÙ\85Ù\83Ù\86 ØªØºÙ\8aÙ\8aر Ø¨Ù\8aاÙ\86ات Ø§Ù\84تعرÙ\8aÙ\81 metadata Ù\84Ù\84Ù\85Ù\84Ù\81 \"$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 لأنه أكبر من  {{PLURAL:$2|بايت واحد|$2 بايت}}.",
-       "backend-fail-readonly": "خلفية التخزين \"$1\" في وضعية القراءة فقط حاليا. السبب في ذلك هو: \"$2\"",
+       "backend-fail-readonly": "خلفية التخزين \"$1\" في وضعية القراءة فقط حاليا. السبب في ذلك هو:\n<em>$2</em>",
        "backend-fail-synced": "الملف \"$1\" في حالة غير متناسقة ضمن خلفية التخزين الداخلية",
        "backend-fail-connect": "تعذر ربط الإتصال بخلفية التخزين \"$1\".",
        "backend-fail-internal": "وقع خطأ غير معروف في خلفية التخزين \"$1\".",
        "uploadstash-summary": " توفر هذه الصفحة الوصول إلى الملفات التي يتم تحميلها (أو في أثناء عملية التحميل) ولكنها لم تنشر بعد. هذه الملفات هي غير مرئية لأحد إلا للمستخدم الذين تم الرفع لهم.",
        "uploadstash-clear": "مسح الملفات المخبأة",
        "uploadstash-nofiles": "ليس لديك أي ملفات مخبأة.",
-       "uploadstash-badtoken": "Ù\84Ù\85 Ù\8aÙ\86جح Ø£Ø¯Ø§Ø¡ Ø°Ù\84Ù\83 Ø§Ù\84عÙ\85Ù\84Ø\8c Ø±Ø¨Ù\85ا Ù\84Ø£Ù\86 Ù\88ثائÙ\82 ØªÙ\81Ù\88Ù\8aض Ø§Ù\84تحرÙ\8aر Ø§Ù\84خاصة Ø¨Ù\83 Ù\85Ù\86تÙ\87Ù\8aØ© Ø§Ù\84صÙ\84احÙ\8aØ©. حاول مرة أخرى.",
+       "uploadstash-badtoken": "Ù\81Ø´Ù\84 Ø£Ø¯Ø§Ø¡ Ø°Ù\84Ù\83 Ø§Ù\84عÙ\85Ù\84Ø\8c Ø±Ø¨Ù\85ا Ù\84Ø£Ù\86 Ù\88ثائÙ\82 ØªÙ\81Ù\88Ù\8aض Ø§Ù\84تحرÙ\8aر Ø§Ù\84خاصة Ø¨Ù\83 Ù\85Ù\86تÙ\87Ù\8aØ© Ø§Ù\84صÙ\84احÙ\8aØ©. Ù\85Ù\86 Ù\81ضÙ\84Ù\83 حاول مرة أخرى.",
        "uploadstash-errclear": "فشلت عملية مسح الملفات.",
        "uploadstash-refresh": "تحديث قائمة الملفات",
        "uploadstash-thumbnail": "اعرض صورة مصغرة",
+       "uploadstash-exception": "لم يمكن تخزين الرفع في الstash ($1): \"$2\".",
        "invalid-chunk-offset": "قطعة أوفست غير صالحة",
        "img-auth-accessdenied": "رفض الوصول",
        "img-auth-nopathinfo": "PATH_INFO مفقود.\nخادومك ليس مضبوطاً لتمرير هذه المعلومة.\nقد يكون مبنياً على نظام CGI ولا يمكنه دعم img_auth.\nراجع https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "apisandbox": "ملعب API",
        "apisandbox-jsonly": "الجافا سكريبت مطلوبة لاستخدام ملعب API",
        "apisandbox-api-disabled": "واجهة برمجة التطبيق API معطلة في هذا الموقع.",
+       "apisandbox-intro": "استخدم هذه الصفحة للتجربة ب<strong>MediaWiki web service API</strong>.\nارجع إلى [[mw:API:Main page|توثيق الAPI]] للمزيد من التفاصيل حول استخدام الAPI. مثال: [https://www.mediawiki.org/wiki/API#A_simple_example احصل على محتوى صفحة رئيسية]. اختر فعلا لترى المزيد من الأمثلة.\n\nلاحظ أنه، على الرغم من أن هذا ملعب، فالأفعال التي تقوم بها على هذه الصفحة ربما تعدل الويكي.",
        "apisandbox-fullscreen": "وسع اللوحة",
+       "apisandbox-fullscreen-tooltip": "وسع صفحة الملعب لتملأ نافذة المتصفح.",
        "apisandbox-unfullscreen": "أظهر الصفحة",
+       "apisandbox-unfullscreen-tooltip": "قلل صفحة الملعب، حتى تكون وصلات التصفح لميدياويكي متوفرة.",
        "apisandbox-submit": "عمل الطلب",
        "apisandbox-reset": "إفراغ",
        "apisandbox-retry": "أعد المحاولة",
+       "apisandbox-loading": "تحميل المعلومات لAPI module \"$1\"...",
+       "apisandbox-load-error": "حدث خطأ أثناء تحميل المعلومات لAPI module \"$1\": $2",
        "apisandbox-no-parameters": "وحدة API هذه ليس بها معاملات.",
        "apisandbox-helpurls": "وصلات المساعدة",
        "apisandbox-examples": "أمثلة",
        "apisandbox-dynamic-parameters-add-placeholder": "اسم المعامل",
        "apisandbox-dynamic-error-exists": "يوجد بالفعل معامل باسم \"$1\".",
        "apisandbox-deprecated-parameters": "معاملات مهملة",
+       "apisandbox-fetch-token": "املأ التوكين تلقائيا",
        "apisandbox-submit-invalid-fields-title": "بعض الحقول غير صالحة",
        "apisandbox-submit-invalid-fields-message": "برجاء تصحيح الحقل المعلم والمحاولة مرة أخرى.",
        "apisandbox-results": "النتائج",
        "apisandbox-sending-request": "إرسال طلب API ...",
        "apisandbox-loading-results": "استقبال طلبات API ...",
+       "apisandbox-results-error": "حدث خطأ أثناء تحميل رد استعدلام الAPI: $1.",
        "apisandbox-request-url-label": "مسار الطلب:",
        "apisandbox-request-time": "وقت الطلب: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "رمز الصحيح وإعادة الموافقة",
+       "apisandbox-results-fixtoken-fail": "فشل جلب توكين \"$1\"",
        "apisandbox-alert-page": "هناك حقول غير صالحة في هذه الصفحة.",
        "apisandbox-alert-field": "قيمة هذا الحقل غير صالحة.",
        "booksources": "مصادر كتاب",
        "booksources-text": "توجد أدناه قائمة بوصلات لمواقع أخرى تبيع الكتب الجديدة والمستعملة، أيضا يمكنك أن تحصل على معلومات إضافية عن الكتب التي تبحث عنها من هناك:",
        "booksources-invalid-isbn": "رقم ISBN المعطى لا يبدو صحيحا؛ تحقق من أخطاء النسخ من المصدر الأصلي.",
        "specialloguserlabel": "المؤدي:",
-       "speciallogtitlelabel": "اÙ\84Ù\87دÙ\81 (عÙ\86Ù\88اÙ\86 Ø£Ù\88 مستخدم):",
+       "speciallogtitlelabel": "اÙ\84Ù\87دÙ\81 (عÙ\86Ù\88اÙ\86 Ø§Ù\88 {{ns:user}}:username Ù\84Ù\84مستخدم):",
        "log": "سجلات",
        "logeventslist-submit": "أظهر",
        "all-logs-page": "كل السجلات العامة",
        "listgrouprights-namespaceprotection-namespace": "النطاق",
        "listgrouprights-namespaceprotection-restrictedto": "الصلاحيات التي تسمح للمستخدم بالتعديل",
        "listgrants": "المنح",
+       "listgrants-summary": "التالي هو قائمة بالمنح بعمليات الوصول لصلاحيات المستخدم المصاحبة لها. المستخدمون يمكنهم إعطاء صلاحية للتطبيقات لاستخدام حساباتهم، ولكن بسماحات محدودة بناء على المنح التي أعطاها المستخدم للتطبيق. تطبيق يعمل بالنيابة عن مستخدم لا يمكنه استخدام الصلاحيات التي لا يمتلكها المستخدم بالفعل.\nربما تكون هناك [[{{MediaWiki:Listgrouprights-helppage}}|معلومات إضافية]] حول الصلاحيات الفردية.",
        "listgrants-grant": "المنحة",
        "listgrants-rights": "الصلاحيات",
        "trackingcategories": "تصانيف التتبع",
        "trackingcategories-msg": "تصانيف التتبع",
        "trackingcategories-name": "اسم الرسالة",
        "trackingcategories-desc": "معايير إدراج تصنيف",
+       "restricted-displaytitle-ignored": "الصفحات بعناوين عرض تم تجاهلها",
+       "restricted-displaytitle-ignored-desc": "هذه الصفحة تحتوي على <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> تم تجاهله لأنه لا يساوي عنوان الصفحة الفعلي.",
        "noindex-category-desc": "هذه الصفحة لا تفهرسها الروبوتات لأن فيها الكلمة السحرية <code><nowiki>__NOINDEX__</nowiki></code> ولأنها في نطاق يسمح بهذا العلم.",
        "index-category-desc": "الصفحة فيها <code><nowiki>__INDEX__</nowiki></code> (وهي في نطاق يسمح بهذا العلم) ولذا فالروبوتات تفهرسها بينما الأصل ألا تفعل.",
        "post-expand-template-inclusion-category-desc": "بعد توسيع جميع القوالب حجم الصفحة أكبر من <code><nowiki>__INDEX__</nowiki></code> ولذا فبعض القوالب لا تُوسّع.",
        "emailccsubject": "نسخة من رسالتك إلى $1: $2",
        "emailsent": "أُرسل البريد الإلكتروني",
        "emailsenttext": "أُرسلت رسالتك الإلكترونية.",
-       "emailuserfooter": "هذا البريد الإلكتروني تم إرساله بواسطة $1 إلى $2 بواسطة وظيفة \"{{int:emailuser}}\" في {{SITENAME}}.",
+       "emailuserfooter": "هذا البريد الإلكتروني {{GENDER:$1|تم إرساله}} بواسطة $1 إلى {{GENDER:$2|$2}} بواسطة وظيفة \"{{int:emailuser}}\" في {{SITENAME}}.",
        "usermessage-summary": "ترك رسالة نظام.",
        "usermessage-editor": "مراسل النظام",
        "watchlist": "قائمة مراقبتي",
        "watchnologin": "غير مسجل الدخول",
        "addwatch": "إضافة إلى قائمة المراقبة",
        "addedwatchtext": "\"[[:$1]]\" وصفحة نقاشها أضيفتا إلى [[Special:Watchlist|قائمة مراقبتك]].",
+       "addedwatchtext-talk": "\"[[:$1]]\" وصفحتها المرافقة تمت إضافتها إلى [[Special:Watchlist|قائمة مراقبتك]].",
        "addedwatchtext-short": "أضيفت صفحة \"$1\" إلى قائمة مراقبتك.",
        "removewatch": "إزالة من قائمة المراقبة",
        "removedwatchtext": "\"[[:$1]]\" وصفحة نقاشها أزيلتا من [[Special:Watchlist|قائمة مراقبتك]].",
+       "removedwatchtext-talk": "\"[[:$1]]\" وصفحتها المرافقة تمت إزالتها من [[Special:Watchlist|قائمة مراقبتك]].",
        "removedwatchtext-short": "أزيلت صفحة \"$1\" من قائمة مراقبتك.",
        "watch": "راقب",
        "watchthispage": "راقب هذه الصفحة",
        "deletepage": "حذف الصفحة",
        "confirm": "أكد",
        "excontent": "المحتوى كان: '$1'",
-       "excontentauthor": "المحتوى كان: '$1' (والمساهم الوحيد كان '[[Special:Contributions/$2|$2]]')",
+       "excontentauthor": "المحتوى كان: \"$1\" والمساهم الوحيد كان \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|talk]])",
        "exbeforeblank": "المحتوى قبل الإفراغ كان: '$1'",
        "delete-confirm": "حذف \"$1\"",
        "delete-legend": "حذف",
        "delete-toobig": "لهذه الصفحة تاريخ تعديل طويل، أكثر من {{PLURAL:$1||مراجعة واحدة|مراجعتين|$1 مراجعات|$1 مراجعة}}.\nقُيّد محذف مثل هذه الصفحات لمنع الاضطراب المفاجئة في {{SITENAME}}.",
        "delete-warning-toobig": "لهذه الصفحة تاريخ تعديل طويل، أكثر من {{PLURAL:$1||مراجعة واحدة|مراجعتين|$1 مراجعات|$1 مراجعة}}.\nقد يؤدي حذفها إلى اضطراب عمليات قاعدة البيانات في {{SITENAME}}؛\nاستمر مع الحذر.",
        "deleteprotected": "لا يمكنك حذف هذه الصفحة لأنها محمية.",
-       "deleting-backlinks-warning": "[[Special:WhatLinksHere/{{FULLPAGENAME}}|تتصل صفحات أخرى]] بالصفحة التي تريد حذفها.",
+       "deleting-backlinks-warning": "<strong>تحذير:</strong> [[Special:WhatLinksHere/{{FULLPAGENAME}}|صفحات أخرى]] تصل إلى أو تضمن الصفحة التي أنت على وشك حذفها.",
        "rollback": "التراجع عن التعديلات",
        "rollbacklink": "استرجع",
        "rollbacklinkcount": "استرجع {{PLURAL:$1|لا تعديلات|تعديلا واحدا|تعديلين|$1 تعديلات|$1 تعديلاً|تعديل}}",
        "rollbacklinkcount-morethan": "استرجاع أكثر من {{PLURAL:$1|تعديل|تعديل|تعديلين|$1 تعديلات|$1 تعديلاً|$1 تعديل}}",
        "rollbackfailed": "لم ينجح الاسترجاع",
+       "rollback-missingparam": "محددات مطلوبة مفقودة عند الطلب.",
+       "rollback-missingrevision": "غير قادر على تحميل بيانات المراجعة.",
        "cantrollback": "لم يمكن استرجاع التعديل؛\nآخر مساهم هو المؤلف الوحيد لهذه الصفحة.",
        "alreadyrolled": "لم يمكن استرجاع آخر تعديل ل[[$1]] بواسطة [[User:$2|$2]] ([[User talk:$2|نقاش]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])؛\nشخص آخر عدل أو استرجع الصفحة بالفعل.\n\nآخر تعديل كان بواسطة [[User:$3|$3]] ([[User talk:$3|نقاش]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "ملخص التعديل كان:<em>$1</em>.",
        "revertpage": "استرجع تعديلات [[Special:Contributions/$2|$2]] ([[User talk:$2|نقاش]]) حتى آخر مراجعة ل[[User:$1|$1]]",
        "revertpage-nouser": "استرجع تعديلات مستخدم مخفي حتى آخر مراجعة ل{{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "استرجع تعديلات $1؛\nاسترجع حتى آخر نسخة بواسطة $2.",
+       "rollback-success-notify": "تم استرجاع التعديلات بواسطة $1;\nتم التغيير إلى آخر مراجعة بواسطة $2. [$3 عرض التغييرات]",
        "sessionfailure-title": "فشل في الجلسة",
        "sessionfailure": "يبدو أنه هناك مشكلة في جلسة الدخول الخاصة بك؛\nلذلك فقد ألغيت هذه العملية كإجراء احترازي ضد الاختراق.\nمن فضلك اضغط على مفتاح \"رجوع\" لتحميل الصفحة التي جئت منها، ثم حاول مرة أخرى.",
        "changecontentmodel": "غير نموذج المحتوى لصفحة",
        "changecontentmodel-success-text": "نوع المحتوى ل[[:$1]] تم تغييره.",
        "changecontentmodel-cannot-convert": "المحتوى على [[:$1]] لا يمكن تحويله لنوع من $2.",
        "changecontentmodel-nodirectediting": "نموذج المحتوى $1 لا يدعم التعديل المباشر",
+       "changecontentmodel-emptymodels-title": "لا موديلات محتوى متوفرة",
+       "changecontentmodel-emptymodels-text": "المحتوى على[[:$1]] لا يمكن تغييره لأي نوع.",
        "log-name-contentmodel": "سجل تغيير نموذج المحتوى",
        "log-description-contentmodel": "الأحداث المرتبطة بنماذج المحتوى لصفحة",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|أنشأ|أنشأت}} الصفحة $3 باستخدام موديل محتوى غير قياسي \"$5\"",
+       "logentry-contentmodel-change": "$1 {{GENDER:$2|غير|غيرت}} موديل المحتوى للصفحة $3 من \"$4\" إلى \"$5\"",
        "logentry-contentmodel-change-revertlink": "استرجع",
        "logentry-contentmodel-change-revert": "استرجع",
        "protectlogpage": "سجل الحماية",
        "undeletehistorynoadmin": "هذه الصفحة تم حذفها.\nالسبب للحذف معروض في الملخص بالأسفل، إلى جانب تفاصيل المستخدمين الذين قاموا بالتعديل على هذه الصفحة قبل حذفها.\nنص المراجعات المحذوفة هذه متوفر فقط للإداريين.",
        "undelete-revision": "المراجعة المحذوفة ل$1 (بتاريخ $4، الساعة $5) بواسطة $3:",
        "undeleterevision-missing": "مراجعة غير صحيحة أو مفقودة.\nربما لديك وصلة سيئة، أو ربما المراجعة تم استرجاعها أو إزالتها من الأرشيف.",
+       "undeleterevision-duplicate-revid": "{{PLURAL:$1|مراجعة واحدة|$1 مراجعة}} لم يمكن استعادتها, لأن ال<code>rev_id</code> {{PLURAL:$1|الخاص بها}}  كان مستخدما بالفعل.",
        "undelete-nodiff": "لم يتم العثور على مراجعة سابقة.",
        "undeletebtn": "استرجاع",
        "undeletelink": "اعرض/استعد",
        "undeletedrevisions": "تم استرجاع {{PLURAL:$1||تعديل واحد|تعديلين|$1 تعديلات|$1 تعديلا|$1 تعديل}}",
        "undeletedrevisions-files": "أسترجعت {{PLURAL:$1||مراجعة واحدة|مراجعتان|$1 مراجعات|$1 مراجعة}}  و{{PLURAL:$2||ملف واحد|ملفان|$2 ملفات|$2 ملفًا|$2 ملف}}",
        "undeletedfiles": "أسترجع {{PLURAL:$1||ملف واحد|ملفان|$1 ملفات|$1 ملفًا|$1 ملف}}",
-       "cannotundelete": "فشل الاسترجاع؛\n$1",
+       "cannotundelete": "بعض أو كل عملية الاسترجاع فشلت:\n$1",
        "undeletedpage": "'''تم استرجاع $1'''\n\nراجع [[Special:Log/delete|سجل الحذف]] لمعاينة عمليات الحذف والاسترجاعات الحديثة.",
        "undelete-header": "انظر الصفحات المحذوفة حديثا في [[Special:Log/delete|سجل الحذف]].",
        "undelete-search-title": "البحث في الصفحات المحذوفة",
        "sp-contributions-newbies-sub": "للحسابات الجديدة",
        "sp-contributions-newbies-title": "مساهمات المستخدم للحسابات الجديدة",
        "sp-contributions-blocklog": "سجل المنع",
-       "sp-contributions-suppresslog": "مساهمات المستخدم المحذوفة",
-       "sp-contributions-deleted": "مساهمات المستخدم المحذوفة",
+       "sp-contributions-suppresslog": "مساهمات {{GENDER:$1|المستخدم|المستخدمة}} المخفية",
+       "sp-contributions-deleted": "مساهمات {{GENDER:$1|المستخدم|المستخدمة}} المحذوفة",
        "sp-contributions-uploads": "مرفوعات",
        "sp-contributions-logs": "سجلات",
        "sp-contributions-talk": "نقاش",
        "ipbexpiry": "مدة المنع:",
        "ipbreason": "السبب:",
        "ipbreason-dropdown": "*أسباب المنع الشائعة\n** كتابة معلومات زائفة\n** إزالة المحتوى من الصفحات\n** سبام وصلات لمواقع خارجية\n** كتابة كلام لا معنى له في الصفحات\n** سلوك عدواني\n** إساءة استخدام حسابات متعددة\n** اسم مستخدم غير مقبول",
-       "ipb-hardblock": "اÙ\85Ù\86ع Ø§Ù\84Ù\85ستخدÙ\85Ù\8aÙ\86 Ø§Ù\84Ù\88اÙ\84جÙ\8aÙ\86 Ù\85Ù\86 Ø§Ù\84تعدÙ\8aÙ\84 Ø¨Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84Ø¢يبي هذا",
+       "ipb-hardblock": "اÙ\85Ù\86ع Ø§Ù\84Ù\85ستخدÙ\85Ù\8aÙ\86 Ø§Ù\84Ù\88اÙ\84جÙ\8aÙ\86 Ù\85Ù\86 Ø§Ù\84تعدÙ\8aÙ\84 Ø¨Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84Ø£يبي هذا",
        "ipbcreateaccount": "امنع إنشاء الحسابات",
        "ipbemailban": "امنع المستخدم من إرسال بريد إلكتروني",
        "ipbenableautoblock": "تلقائيا امنع آخر عنوان أيبي تم استعماله بواسطة هذا المستخدم، وأي عناوين أيبي أخرى يحاول التحرير من خلالها",
        "move-page-legend": "نقل صفحة",
        "movepagetext": "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.\nالعنوان القديم سيصبح تحويلة للعنوان الجديد.\nيمكنك أن تترك التحويلات التي تشير إلى العنوان الأصلي كما هي لتقوم البوتات بتحديثها تلقائياً.\nإذا اخترت أن تقوم بالتحديث يدوياً، فتأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]] وقم بتصحيحها.\nأنت المسؤول عن التأكد من أن الوصلات تصل إلى الصفحات التي يفترض أن تصل إليها.\n\nلاحظ أنه <strong>لن يتم</strong> نقل الصفحة إذا وجدت صفحة في العنوان الجديد، إلا إذا كانت صفحة تحويل، ولا تاريخ لها.\nهذا يعني أنك تستطيع استرجاع الصفحة إلى مكانها لو قمت بخطأ، ولا يمكنك نسخ هذه الصفحة فوق صفحة موجودة.\n\n<strong>ملاحظة:</strong>\n\nهذا قد يكون تغييراً كارثياً وغير متوقع لصفحة مشهورة؛\nمن فضلك تأكد أنك تفهم عواقب هذا الفعل قبل أن تستمر.",
        "movepagetext-noredirectfixer": "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.\nالعنوان القديم سيصبح تحويلة للعنوان الجديد.\nيمكنك تحديث التحويلات التي تشير إلى العنوان الأصلي تلقائياً.\nلو اخترت ألا تفعل، تأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]].\nأنت المسؤول عن التأكد من أن الوصلات تصل إلى الصفحات التي يفترض أن تصل إليها.\n\nلاحظ أنه <strong>لن يتم</strong>  نقل الصفحة إذا كان هناك صفحة بنفس العنوان الجديد، إلا إذا كانت فارغة، أو تحويلة لا تاريخ لها.\nهذا يعني أنك تستطيع استرجاع الصفحة إلى مكانها لو قمت بخطأ، وأنك لا يمكنك الكتابة على صفحة موجودة.\n\n<strong>ملاحظة</strong> \n\nهذا قد يكون تغييراً كارثياً وغير متوقع لصفحة مشهورة؛\nمن فضلك تأكد أنك تفهم عواقب هذا الفعل قبل أن تستمر.",
-       "movepagetalktext": "صفحة النقاش المرفقة سيتم نقلها كذلك، '''إلا في حالة''':\n* توجد صفحة نقاش غير فارغة تحت العنوان الجديد، أو\n* قمت بإزالة اختيار الصندوق بالأسفل.\n\nوفي هذه الحالات، يجب عليك نقل أو دمج محتويات الصفحة يدويا، إذا رغب في ذلك.",
+       "movepagetalktext": "لو علمت على هذا الصندوق، فصفحة النقاش المرفقة يتم نقلها أوتوماتيكيا للعنوان الجديد، إلا لو كانت صفحة نقاش غير فارغة هناك بالفعل.\n\nفي هذه الحالة، فسيتعين عليك نقل أو دمج الصفحة يدويا لو رغبت في ذلك.",
        "moveuserpage-warning": "'''تحذير: أنت على وشك نقل صفحة مستخدم. من فضلك لاحظ أن الصفحة وحدها سوف تنقل وأن المستخدم لن يعاد تسميته.'''",
        "movecategorypage-warning": "<strong>تحذير:</strong> أنت على وشك نقل صفحة التصنيف إلى عنوان جديد؛ <em>لن</em> تنقل الصفحات المندرجة تحت التصنيف إلى العنوان الجديد.",
        "movenologintext": "يجب أن تكون مستخدماً مسجلاً وأن  [[Special:UserLogin|تسجل دخولك]] لكي تنقل صفحة.",
        "movenosubpage": "ليس لهذه الصفحة صفحات فرعية.",
        "movereason": "السبب:",
        "revertmove": "استرجع",
-       "delete_and_move_text": "==الحذف مطلوب==\nالصفحة الهدف \"[[:$1]]\" موجودة بالفعل.\nهل تريد حذفها لإفساح المجال للنقل؟",
+       "delete_and_move_text": "الصفحة الهدف \"[[:$1]]\" موجودة بالفعل.\nهل تريد حذفها لإفساح المجال للنقل؟",
        "delete_and_move_confirm": "نعم، احذف الصفحة",
        "delete_and_move_reason": "حُذِفت لإفساح مجال لنقل \"[[$1]]\"",
        "selfmove": "لا يوجد اختلاف في عنوان المصدر والهدف؛\nلا يمكن نقل الصفحة على نفسها.",
        "move-leave-redirect": "اترك تحويلة خلفك",
        "protectedpagemovewarning": "'''تحذير:''' هذه الصفحة قد تم حمايتها، فقط المستخدمون الذين يمتلكون امتيازات الإدارة يمكنهم نقلها.\nآخر مدخلة سجل موفرة بالأسفل كمرجع:",
        "semiprotectedpagemovewarning": "'''ملاحظة:''' هذه الصفحة تمت حمايتها ليتمكن المستخدمون المسجلون وحدهم من نقلها.\nآخر مدخلة سجل موفرة بالأسفل كمرجع:",
-       "move-over-sharedrepo": "== الملف موجود ==\n[[:$1]] موجود في مستودع مشترك. نقل الملف إلى هذا العنوان سوف يلغي الملف المشترك.",
+       "move-over-sharedrepo": "[[:$1]] موجود في مستودع مشترك. نقل الملف إلى هذا العنوان سوف يلغي الملف المشترك.",
        "file-exists-sharedrepo": "اسم الملف الذي اخترته مستخدم من قبل في مستودع مشترك.\nمن فضلك اختر اسماً آخر.",
        "export": "تصدير صفحات",
        "exporttext": "يمكنك تصدير النص وتاريخ تعديلات صفحة أو مجموعة صفحات في صيغة XML.\nهذا يمكن استيراده إلى ويكي آخر يستعمل ميدياويكي بواسطة [[Special:Import|صفحة الاستيراد]].\n\nلتصدير الصفحات، أدخل عناوينها في الصندوق أسفله، عنواناً واحداً في كل سطر، مع اختيار ما إذا كنت ترغب بتصدير النسخة الحالية مع جميع النسخ القديمة، أي مع كامل معلومات تاريخ الصفحة، أو فقط النسخة الحالية مع معلومات عن التعديل الأخير.\n\nفي الحالة الأخيرة يمكنك أيضاً استخدام وصلة، على سبيل المثال [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] للصفحة «[[{{MediaWiki:Mainpage}}]]».",
        "import-nonewrevisions": "لا مراجعات تم استيرادها (كل المراجعات إما أنها كانت موجودة بالفعل، وأو تم تجاوزها نتيجة أخطاء).",
        "xml-error-string": "$1 عند السطر $2، العمود $3 (بايت $4): $5",
        "import-upload": "رفع بيانات XML",
-       "import-token-mismatch": "فقد لبيانات الجلسة. من فضلك حاول مرة أخرى.",
+       "import-token-mismatch": "فقد لبيانات الجلسة.\n\nأنت لابد من أنه قد تم تسجيل خروجك. <strong>من فضلك تأكد من أنك مازلت مسجل الدخول وحاول مرة أخرى</strong>.\nلو كان مازال لا يعمل، فحاول [[Special:UserLogout|تسجيل الخروج]] وتسجيل الدخول مرة أخرى، وتحقق من أن متصفحك يسمح بالكوكيز من هذا الموقع.",
        "import-invalid-interwiki": "لم يمكن الاستيراد من الويكي المحدد.",
        "import-error-edit": "الصفحة \"$1\" لم يتم استيرادها لأنه لا يمكن لك تحريرها.",
        "import-error-create": "الصفحة \"$1\" لم يتم استيرادها لأنه لا يمكن لك استحداثها أصلا.",
        "tooltip-ca-nstab-category": "رؤية صفحة التصنيف",
        "tooltip-minoredit": "علم على هذا كتعديل طفيف",
        "tooltip-save": "احفظ تغييراتك",
+       "tooltip-publish": "انشر تغييراتك",
        "tooltip-preview": "اعرض تغييراتك، من فضلك استخدم هذا قبل الحفظ!",
        "tooltip-diff": "اعرض التغييرات التي قمت بها للنص.",
        "tooltip-compareselectedversions": "شاهد الفروق بين النسختين المختارتين من هذه الصفحة.",
        "hours-ago": "منذ {{PLURAL:$1|ساعة|$1 ساعات}}",
        "minutes-ago": "منذ {{PLURAL:$1|دقيقة|$1 دقائق}}",
        "seconds-ago": "منذ {{PLURAL:$1|ثانية|$1 ثوان}}",
-       "monday-at": "Ù\8aÙ\88Ù\85 Ø§Ù\84اثنين الساعة $1",
+       "monday-at": "Ù\8aÙ\88Ù\85 Ø§Ù\84Ø¥ثنين الساعة $1",
        "tuesday-at": "يوم الثلاثاء الساعة $1",
        "wednesday-at": "يوم الأربعاء الساعة $1",
        "thursday-at": "يوم الخميس الساعة $1",
        "exif-artist": "المؤلف",
        "exif-copyright": "مالك الحقوق",
        "exif-exifversion": "نسخة Exif",
-       "exif-flashpixversion": "نسخة فلاش بكس المدعومة",
+       "exif-flashpixversion": "نسخة Flashpix المدعومة",
        "exif-colorspace": "فضاء الألوان",
        "exif-componentsconfiguration": "معنى كل مكونة",
        "exif-compressedbitsperpixel": "طور ضغط الصورة",
        "exif-iimcategory-edu": "تعليم",
        "exif-iimcategory-evn": "بيئة",
        "exif-iimcategory-hth": "صحة",
-       "exif-iimcategory-hum": "اهتمام البشرية",
+       "exif-iimcategory-hum": "اهتمام البشرية",
        "exif-iimcategory-lab": "عمل",
        "exif-iimcategory-lif": "أسلوب الحياة وأوقات الفراغ",
        "exif-iimcategory-pol": "سياسة",
        "confirmemail_body_set": "شخص ما -من المحتمل أن يكون أنت- من عنوان الأيبي $1 غيّر عنوان البريد\nالإلكتروني للحساب \"$2\" إلى عنوان البريد الإلكتروني هذا في\n{{SITENAME}}.\n\nلتأكيد أن هذا الحساب لك فعلا ولتنشيط خواص البريد الإلكتروني في\n{{SITENAME}}، افتح هذه الوصلة في متصفحك:\n\n$3\n\nإذا كان هذا الحساب *ليس* لك، اتبع هذه الوصلة لإلغاء تأكيد عنوان البريد\nالإلكتروني:\n\n$5\n\nسينتهي رمز التفعيل هذا في $4.",
        "confirmemail_invalidated": "تأكيد عنوان البريد الإلكتروني تم إلغاؤه",
        "invalidateemail": "إلغاء تأكيد البريد الإلكتروني",
+       "notificationemail_subject_changed": "عنوان البريد الإلكتروني المسجل ل{{SITENAME}} تم تغييره",
+       "notificationemail_subject_removed": "عنوان البريد الإلكتروني المسجل ل{{SITENAME}} تمت إزالته",
+       "notificationemail_body_changed": "شخص ما، غالبا أنت،  من عنوان الأيبي $1،\nقام بتغيير عنوان البريد الإلكتروني للحساب \"$2\" إلى \"$3\" في {{SITENAME}}.\n\nلو أن هذا لم يكن أنت، فاتصل بإداري للموقع حالا.",
+       "notificationemail_body_removed": "شخص ما، غالبا أنت،  من عنوان الأيبي $1،\nقام بإزالة عنوان البريد الإلكتروني للحساب \"$2\" في {{SITENAME}}.\n\nلو أن هذا لم يكن أنت، فاتصل بإداري للموقع حالا.",
        "scarytranscludedisabled": "[التضمين بالإنترويكي معطل]",
        "scarytranscludefailed": "[البحث عن القالب فشل ل$1]",
        "scarytranscludefailed-httpstatus": "[فشل جلب القالب لـ $1: HTTP $2]",
        "scarytranscludetoolong": "[المسار طويل للغاية]",
        "deletedwhileediting": "'''تحذير''': هذه الصفحة تم حذفها بعد أن بدأت أنت بتعديلها!",
-       "confirmrecreate": "حذف المستخدم [[User:$1|$1]] ([[User talk:$1|نقاش]]) هذه الصفحة بعد أن بدأت أنت بتحريرها للسبب التالي:\n:''$2''\nالرجاء التأكد من أنك تريد إعادة إنشاء هذه الصفحة.",
-       "confirmrecreate-noreason": "حذف المستخدم [[User:$1|$1]] ([[User talk:$1|نقاش]]) هذه الصفحة بعد أن بدأت أنت بتحريرها. الرجاء التأكد من أنك تريد إعادة إنشاء هذه الصفحة.",
+       "confirmrecreate": "{{GENDER:$1|حذف المستخدم|حذفت المستخدمة}} [[User:$1|$1]] ([[User talk:$1|نقاش]]) هذه الصفحة بعد أن بدأت أنت بتحريرها للسبب التالي:\n: <em>$2</em>\nالرجاء التأكد من أنك تريد إعادة إنشاء هذه الصفحة.",
+       "confirmrecreate-noreason": "{{GENDER:$1|حذف المستخدم|حذفت المستخدمة}} [[User:$1|$1]] ([[User talk:$1|نقاش]]) هذه الصفحة بعد أن بدأت أنت بتحريرها. الرجاء التأكد من أنك تريد إعادة إنشاء هذه الصفحة.",
        "recreate": "إعادة إنشاء",
        "unit-pixel": "بك",
        "confirm_purge_button": "موافق",
        "confirm-unwatch-button": "موافق",
        "confirm-unwatch-top": "إزالة هذه الصفحة من قائمة مراقبتك؟",
        "confirm-rollback-button": "موافق",
+       "confirm-rollback-top": "استرجاع التعديلات لهذه الصفحة؟",
        "semicolon-separator": "؛&#32;",
        "comma-separator": "،&#32;",
        "quotation-marks": "«$1»",
        "timezone-local": "محلي",
        "duplicate-defaultsort": "'''تحذير:''' مفتاح الترتيب الافتراضي \"$2\" يتجاوز مفتاح الترتيب الافتراضي السابق \"$1\".",
        "duplicate-displaytitle": "<strong>تحذير:</strong> أعرض عنوان \"$2\" تجاهل العنوان المعروض سابقا \"$1\".",
+       "restricted-displaytitle": "<strong>تحذير:</strong> عنوان العرض \"$1\" تم تجاهله بما أنه لا يساوي عنوان الصفحة الفعلي.",
        "invalid-indicator-name": "<strong>خطأ:</strong> لا يجوز أن تبقى خاصية <code>name</code> لمؤشرات وضع الصفحة فارغةً.",
        "version": "نسخة",
        "version-extensions": "الامتدادات المثبتة",
        "version-libraries-description": "الوصف",
        "version-libraries-authors": "المؤلفون",
        "redirect": "تحويل حسب الملف أو المستخدم أو الصفحة أو معرف الدخول",
-       "redirect-summary": "هذه الصفحة الخاصة تحوّل إلى ملف (باسمه) أو صفحة (برقم إحدى مراجعاتها) أو إلى صفحة مستخدم (برقمه التعريفي). الاستخدام [[{{#Special:Redirect}}/file/Example.jpg]] أو [[{{#Special:Redirect}}/revision/328429]] أو [[{{#Special:Redirect}}/user/101]].",
-       "redirect-submit": "Ø­Ù\88Ù\91Ù\84",
+       "redirect-summary": "هذه الصفحة الخاصة تحوّل إلى ملف (باسمه) أو صفحة (برقم إحدى مراجعاتها) أو إلى صفحة مستخدم (برقمه التعريفي) أو إلى مدخلة سجل (برقم السجل). الاستخدام [[{{#Special:Redirect}}/file/Example.jpg]] أو [[{{#Special:Redirect}}/revision/328429]] أو [[{{#Special:Redirect}}/user/101]] أو [[{{#Special:Redirect}}/logid/186]].",
+       "redirect-submit": "اذÙ\87ب",
        "redirect-lookup": "ابحث في:",
        "redirect-value": "الوجهة",
        "redirect-user": "رقم مستخدم",
        "tags-create-reason": "السبب:",
        "tags-create-submit": "أنشئ",
        "tags-create-no-name": "عليك أن تحدد اسم الوسم.",
+       "tags-create-invalid-chars": "أسماء الوسوم ينبغي ألا تحتوي على فواصل (<code>,</code>) أو forward slashes (<code>/</code>).",
        "tags-create-invalid-title-chars": "يجب أن لا تحتوي أسماء العلامات الأحرف التي لا يمكن استخدامها في عناوين الصفحات.",
        "tags-create-already-exists": "الوسم \"$1\" موجود بالفعل.",
+       "tags-create-warnings-above": "{{PLURAL:$2|التحذير التالي حدث|التحذيرات التالية حدثت}} عند محاولة إنشاء الوسم \"$1\":",
        "tags-create-warnings-below": "هل تود متابعة إنشاء الوسم؟",
        "tags-delete-title": "احذف الوسم",
        "tags-delete-explanation-initial": "أنت على وشك حذف الوسم \"$1\" من قاعدة البيانات.",
+       "tags-delete-explanation-in-use": "ستتم إزالته من {{PLURAL:$2|$2 مراجعة او مدخلة سجل|كل $2 مراجعات و/أو مدخلات سجل}} الذي هو مطبق عليهم حاليا.",
+       "tags-delete-explanation-warning": "هذا الفعل <strong>غير رجعي</strong> و <strong>لا يمكن التراجع عنه</strong>، ولا حتى بواسطة إداريي قاعدة البيانات. كن متاكدا من أن هذا هو الوسم الذي تريد حذفه.",
+       "tags-delete-explanation-active": "<strong>الوسم \"$1\" مازال نشطا، وسيتم الاستمرار في تطبيقه في المستقبل.</strong> لمنع هذا من الحدوث، اذهب إلى المكان(الأمكنة) حيث الوسم مضبوط ليتم تطبيقه، وعطله هناك.",
        "tags-delete-reason": "سبب:",
-       "tags-delete-submit": "إزاÙ\84Ø© هذا الوسم دون رجعة (ستدمر بعض البيانات)",
+       "tags-delete-submit": "حذÙ\81 هذا الوسم دون رجعة (ستدمر بعض البيانات)",
        "tags-delete-not-allowed": "الوسوم التي يعرفها امتداد لا يمكن حذفها إلا إذا أتاح الامتداد ذلك.",
        "tags-delete-not-found": "الوسم \"$1\" غير موجود.",
+       "tags-delete-too-many-uses": "الوسم \"$1\" مطبق في أكثر من $2 {{PLURAL:$2|مراجعة|مراجعات}}، مما يعني أنه لا يمكن حذفه.",
+       "tags-delete-warnings-after-delete": "الوسم \"$1\" تم حذفه، لكن {{PLURAL:$2|التحذير التالي حدث|التحذيرات التالية حدثت}}:",
+       "tags-delete-no-permission": "أنت لا تمتلك الصلاحية لحذف وسوم التغيير.",
        "tags-activate-title": "نشط الوسم",
        "tags-activate-question": "أنت على وشك تنشيط الوسم \"$1\".",
        "tags-activate-reason": "السبب:",
        "tags-deactivate-submit": "عطل",
        "tags-apply-no-permission": "ليس لديك إذن لتطبيق علامات التغيير جنبا إلى جنب مع التغييرات.",
        "tags-apply-blocked": "لا يمكنك تطبيق علامات التغيير جنبا إلى جنب مع التغييرات في حين منعت.",
-       "tags-apply-not-allowed-one": "السوم \"$1\" غير مسموح أن يتم تطبيقه يدويا.",
+       "tags-apply-not-allowed-one": "الوسم \"$1\" غير مسموح أن يتم تطبيقه يدويا.",
        "tags-apply-not-allowed-multi": "{{PLURAL:$2|الوسم|الوسوم}} التالية غير مسموح أن يتم تطبيقها يدويا: $1",
        "tags-update-no-permission": "أنت لا تمتلك السماح لإضافة أو إزالة وسوم التغيير من المراجعات أو مدخلات السجل الفردية.",
        "tags-update-blocked": "لا يمكنك إضافة أو إزالة العلامات التغيير بينماهي محظورة.",
        "tags-edit-revision-selected": "{{PLURAL:$1|مراجعة مختارة|مراجعات مختارة}} من [[:$2]]:",
        "tags-edit-logentry-selected": "{{PLURAL:$1|حدث سجل مختار|أحداث سجل مختارة}}:",
        "tags-edit-revision-legend": "أضف أو أزل الوسوم من {{PLURAL:$1|هذه المراجعة|كل $1 المراجعات}}",
+       "tags-edit-logentry-legend": "أضف أو أزل الوسوم من {{PLURAL:$1|مدخلة السجل هذه|كل مدخلات السجل ال$1}}",
        "tags-edit-existing-tags": "الوسوم الموجودة:",
        "tags-edit-existing-tags-none": "</em>لا وسوم</em>",
        "tags-edit-new-tags": "وسوم جديدة:",
        "logentry-block-unblock": "$1 {{GENDER:$2|رفع منع}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": " {{GENDER:$2|غير|غيرت}} $1 إعدادات المنع ل{{GENDER:$4|$3}} بتاريخ انتهاء $5 $6",
        "logentry-suppress-block": "{{GENDER:$2|منع|منعت}} $1 {{GENDER:$4|$3}} لفترة زمنية مدتها $5 $6",
+       "logentry-suppress-reblock": "$1 {{GENDER:$2|غير|غيرت}} إعدادات المنع ل{{GENDER:$4|$3}} بتاريخ انتهاء $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|استورد}} $3 بواسطة رفع ملف",
+       "logentry-import-upload-details": "$1 {{GENDER:$2|استورد|استوردت}} $3 بواسطة رفع الملف ($4 {{PLURAL:$4|مراجعة|مراجعات}})",
        "logentry-import-interwiki": "$1 {{GENDER:$2|استورد|استوردت}} $3 من ويكي أخرى",
+       "logentry-import-interwiki-details": "$1 {{GENDER:$2|استورد|استوردت}} $3 من $5 ($4 {{PLURAL:$4|مراجعة|مراجعات}})",
        "logentry-merge-merge": "{{GENDER:$2|دمج|دمجت}} $1 $3 إلى $4 (المراجعات حتى $5).",
        "logentry-move-move": "{{GENDER:$2|نقل|نقلت}} $1 صفحة $3 إلى $4",
        "logentry-move-move-noredirect": "{{GENDER:$2|نقل|نقلت}} $1 صفحة $3 إلى $4 دون ترك تحويلة",
        "logentry-protect-protect": "$1 {{GENDER:$2|حمى|حمت}} $3 $4",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|حمى|حمت}} $3 $4 [مضمنة]",
        "logentry-protect-modify": "{{GENDER:$2|غير|غيرت}} $1 مستوى حماية $3 $4",
-       "logentry-rights-rights": "{{GENDER:$2|غيّر|غيّرت}} $1 عضوية $3 من $4 إلى $5",
+       "logentry-protect-modify-cascade": "$1 {{GENDER:$2|غير|غيرت}} مستوى الحماية ل$3 $4 [مضمن]",
+       "logentry-rights-rights": "{{GENDER:$2|غيّر|غيّرت}} $1 عضوية {{GENDER:$6|$3}} من $4 إلى $5",
        "logentry-rights-rights-legacy": "{{GENDER:$2|غيّر|غيّرت}} $1 عضوية $3",
        "logentry-rights-autopromote": "تمت تلقائيا ترقية {{GENDER:$2|المستخدم|المستخدمة}} $1 من  $4 إلى $5",
        "logentry-upload-upload": " {{GENDER:$2|رفع|رفعت}} $1 $3",
        "logentry-upload-overwrite": "{{GENDER:$2|رفع|رفعت}} $1 نسخة جديدة من  $3",
        "logentry-upload-revert": "{{GENDER:$2|رفع|رفعت}} $1 $3",
        "log-name-managetags": "سجل إدارة الوسوم",
+       "log-description-managetags": "هذه الصفحة تعرض مهام الإدارة المرتعلقة ب[[Special:Tags|الوسوم]]. السجل يحتوي فقط على الافعال التي تم عملها يدويا بواسطة إداري؛ الوسوم ربما يتم إنشاؤها او حذفها بواسطة برنامج الويكي بدون تسجيل مدخلة في هذا السجل.",
        "logentry-managetags-create": "$1 {{GENDER:$2|أنشأ|أنشأت}} الوسم \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|حذف|حذفت}} الوسم \"$4\" (أزيل من $5 {{PLURAL:$5|مراجعة أو مدخلة سجل|مراجعات و/أو مدخلات سجل}})",
        "logentry-managetags-activate": "$1 {{GENDER:$2|فعل|فعلت}} الوسم \"$4\" للاستخدام بواسطة البوتات والمستخدمين",
        "logentry-managetags-deactivate": "$1 {{GENDER:$2|ألغى تفعيل|ألغت تفعيل}} الوسم \"$4\" للاستخدام بواسطة البوتات والمستخدمين",
        "log-name-tag": "سجل الوسوم",
+       "log-description-tag": "هذه الصفحة تعرض متى قام المستخدمون بإضافة أو إزالة [[Special:Tags|الوسوم]] من المراجعات أو مدخلات السجل الفردية. السجل لا يعرض أفعال الوسم عندما يحدثوا كجزء من تعديل، حذف، أو فعل مماثل.",
+       "logentry-tag-update-add-revision": "$1 {{GENDER:$2|أضاف|أضافت}} {{PLURAL:$7|الوسم|الوسوم}} $6 للمراجعة $4 للصفحة $3",
+       "logentry-tag-update-add-logentry": "$1 {{GENDER:$2|أضاف|أضافت}} {{PLURAL:$7|الوسم|الوسوم}} $6 لمدخلة السجل $5 للصفحة $3",
+       "logentry-tag-update-remove-revision": "$1 {{GENDER:$2|أزال|أزالت}} {{PLURAL:$9|الوسم|الوسوم}} $8 من المراجعة $4 للصفحة $3",
+       "logentry-tag-update-remove-logentry": "$1 {{GENDER:$2|أزال|أزالت}} {{PLURAL:$9|الوسم|الوسوم}} $8 من مدخلة السجل $5 للصفحة $3",
+       "logentry-tag-update-revision": "$1 {{GENDER:$2|حدث|حدثت}} الوسوم للمراجعة $4 للصفحة $3 ({{PLURAL:$7|أضاف}} $6; {{PLURAL:$9|أزال}} $8)",
+       "logentry-tag-update-logentry": "$1 {{GENDER:$2|حدث|حدثت}} الوسوم على مدخلة السجل $5 للصفحة $3 ({{PLURAL:$7|أضاف}} $6; {{PLURAL:$9|أزال}} $8)",
        "rightsnone": "(لا شيء)",
        "revdelete-summary": "ملخص التعديل",
        "feedback-adding": "إضافة تعليقات إلى الصفحة...",
        "feedback-close": "تم",
        "feedback-external-bug-report-button": "أرسل تقرير علة تقنية",
        "feedback-dialog-title": "أرسل تغذية راجعة",
+       "feedback-dialog-intro": "أنت يمكنك استخدام الاستمارة السهلة بالأسفل لإرسال تعليقك. تعليقك ستتم إضافته للصفحة \"$1\"، مع اسم المستخدم الخاص بك.",
        "feedback-error-title": "خطأ",
        "feedback-error1": "خطأ: لا يمكن التعرف عليها من API",
        "feedback-error2": "خطأ: فشل في تحرير",
        "feedback-message": "الرسالة:",
        "feedback-subject": "الموضوع:",
        "feedback-submit": "إرسال",
+       "feedback-terms": "أنا أفهم أن معلومات وكيل المستخدم الخاص بي تشمل معلومات حول نسخة متصفحي ونظام التشغيل الخاص بي بالضبط وستتم مشاركتها علنيا بجانب تعليقي.",
+       "feedback-termsofuse": "أنا أوافق على توفير تعليقات بالتوافق مع شروط الاستخدام.",
        "feedback-thanks": "شكرا! أُرسلت ملاحظاتك لصفحة \"[$2 $1]\".",
        "feedback-thanks-title": "شكرا لك!",
        "feedback-useragent": "وكيل المستخدم:",
        "searchsuggest-search": "بحث",
        "searchsuggest-containing": "يحتوي...",
+       "api-error-autoblocked": "عنوان الأيبي الخاص بك تم منعه تلقائيا، لأنه تم استخدامه بواسطة مستخدم ممنوع",
        "api-error-badaccess-groups": "لا يسمح لك بتحميل الملفات إلى هذه الويكي.",
        "api-error-badtoken": "خطأ داخلي: رمز مميز غير صحيح.",
        "api-error-blocked": "لقد منعت من التحرير.",
        "api-error-copyuploaddisabled": "تم تعطيل تحميل من رابط على هذا الخادم.",
-       "api-error-duplicate": "Ù\87Ù\86اÙ\83 {{PLURAL:$1|Ù\87Ù\88 Ù\85Ù\84Ù\81 Ø¢Ø®Ø±|Ù\83Ø°Ù\84Ù\83$2 Ø¨Ø¹Ø¶ Ø§Ù\84Ù\85Ù\84Ù\81ات Ø§Ù\84أخرÙ\89}} Ù\85سبÙ\82اÙ\8b Ø¹Ù\84Ù\89 Ø§Ù\84Ù\85Ù\88Ù\82ع Ø¨Ù\86Ù\81س Ø§Ù\84Ù\85ضÙ\85Ù\88Ù\86.",
+       "api-error-duplicate": "Ù\87Ù\86اÙ\83 {{PLURAL:$1|Ù\85Ù\84Ù\81 Ø¢Ø®Ø±|بعض Ø§Ù\84Ù\85Ù\84Ù\81ات Ø§Ù\84أخرÙ\89}} Ù\85سبÙ\82ا Ø¹Ù\84Ù\89 Ø§Ù\84Ù\85Ù\88Ù\82ع Ø¨Ù\86Ù\81س Ø§Ù\84Ù\85حتÙ\88Ù\89.",
        "api-error-duplicate-archive": "هناك {{PLURAL:$1|كان ملف آخر |كذلك بعض الملفات الأخرى}} مسبقاً على الموقع بنفس المضمون، ولكن {{PLURAL:$1|أنه تم | إجراء}} الحذف لها.",
        "api-error-empty-file": "كان ملف الذي قمت بإرسال فارغة.",
        "api-error-emptypage": "إنشاء صفحات فارغة جديدة، غير مسموح به.",
        "api-error-filetype-banned-type": "$1 {{PLURAL:$4|ليس نوع ملف مسموح به|ليست أنواع ملفات مسموح بها}}. {{PLURAL:$3|نوع الملف المسموح به هو|أنواع الملفات المسموح بها هي}} $2.",
        "api-error-filetype-missing": "يفتقد الملفّ ملحق نوعيّته.",
        "api-error-hookaborted": "التعديل الذي تحاول أن تقوم به تم إحباطه",
-       "api-error-http": "خطأ Ø¯Ø§Ø®Ù\84Ù\8a: ØªØ¹Ø°Ø± Ø§Ù\84اتصاÙ\84 Ø¨Ø§Ù\84خادÙ\88Ù\85.",
+       "api-error-http": "خطأ داخلي: تعذر الاتصال بالخادم.",
        "api-error-illegal-filename": "اسم الملف غير مسموح به.",
        "api-error-internal-error": "خطأ داخلي: حدث خطأ عند معالجة التحميل الخاص بك على الويكي.",
        "api-error-invalid-file-key": "خطأ داخلي: لم يتم العثور على الملف في التخزين المؤقت.",
        "api-error-nomodule": "خطأ داخلي: لم يتم تعيين تحميل الوحدة النمطية.",
        "api-error-ok-but-empty": "خطأ داخلي : لم يكن هناك استجابة من الملقم.",
        "api-error-overwrite": "لا يسمح بالكتابة فوق ملف موجود.",
+       "api-error-ratelimited": "أنت تحاول رفع الكثير من الملفات في فترة زمنية قصيرة أقصر مما تسمح به هذه الويكي.\nمن فضلك حاول مرة ثانية خلال عدة دقائق.",
        "api-error-stashfailed": "خطأ داخلي: فشل الملقم في تخزين الملفات المؤقتة.",
        "api-error-publishfailed": "خطأ داخلي: لم ينجح الخادوم في نشر ملف مؤقت",
        "api-error-stasherror": "حدث خطأ أثناء رفع الملف لتخزينه.",
        "api-error-stashnosuchfilekey": "الملف الذي كنت تحاول الوصول اليه في مخبوائتك غير موجود.",
        "api-error-timeout": "لم يستجب الملقم في الوقت المتوقع.",
        "api-error-unclassified": "حدث خطأ غير معروف",
-       "api-error-unknown-code": "خطأ غير معروف : \" $1 \"",
+       "api-error-unknown-code": "خطأ غير معروف: \"$1\"",
        "api-error-unknown-error": "خطأ داخلي: قد حدث خطأ عند محاولة تحميل الملف الخاص بك.",
-       "api-error-unknown-warning": "تحذير غير معروف:$1",
-       "api-error-unknownerror": "خطأ غير معروف : \" $1 \"",
-       "api-error-uploaddisabled": "تم تعطيل تحميل على هذا الويكي.",
-       "api-error-verification-error": "هذا الملف قد يكون معطوباً أو يحتوي على ملحق غير صحيح.",
+       "api-error-unknown-warning": "تحذير غير معروف: \"$1\"",
+       "api-error-unknownerror": "خطأ غير معروف: \"$1\"",
+       "api-error-uploaddisabled": "تم تعطيل الرفع على هذه الويكي.",
+       "api-error-verification-error": "هذا الملف قد يكون معطوباً أو يحتوي على امتداد غير صحيح.",
+       "api-error-was-deleted": "تم رفع ملف بهذا الاسم سابقا ثم تم حذفه بعد هذا.",
        "duration-seconds": "{{PLURAL:$1|أقل من ثانية|ثانية واحدة|ثانيتان|$1 ثوانٍ|$1 ثانية}}",
        "duration-minutes": "{{PLURAL:$1|أقل من دقيقة|دقيقة واحدة|دقيقتان|$1 دقائق|$1 دقيقة}}",
        "duration-hours": "({{PLURAL:$1||ساعة واحدة|ساعتان|$1 ساعات|$1 ساعة}})",
        "expand_templates_generate_rawhtml": "أظهر خام HTML",
        "expand_templates_preview": "عرض مسبق",
        "expand_templates_preview_fail_html": "<em>عذرا! لم نستطع معالجة تعديلك بسبب فقدان بيانات الجلسة.\n\nلأن {{SITENAME}} بها HTML الخام مفعلة، العرض المسبق مخفي كاحتياط ضد هجمات الجافا سكريبت.</em>\n\n<strong>إذا كانت هذه محاولة تعديل صادقة، من فضلك حاول مرة أخرى.</strong>\nإذا كانت مازالت لا تعمل، حاول [[Special:UserLogout|تسجيل الخروج]] ثم تسجيل الدخول مجددا.و تاكد في  متصفحك من الكوكيز  الخاصة  بهذا الموقع.",
+       "expand_templates_preview_fail_html_anon": "<em>لأن {{SITENAME}} لديه الHTML الخام مفعل وأنت غير مسجل الدخول، فعملية المعاينة مخفية كاحتياط ضد عمليات هجوم الجافاسكريبت.</em>\n\n<strong>لو أن هذه عملية معاينة صحيحة، فمن فضلك  [[Special:UserLogin|سجل الدخول]] وحاول مرة أخرى.</strong>",
        "expand_templates_input_missing": "يجب تقديم بعض المدخلات النصية على الأقل.",
        "pagelanguage": "تغيير لغة الصفحة",
        "pagelang-name": "صفحة",
        "log-name-pagelang": "سجل تغيير اللغة",
        "log-description-pagelang": "هذا سجل تغيرات في صفحة اللغات.",
        "logentry-pagelang-pagelang": " {{GENDER:$2|غيَّر|غيَّرت}} $1 لغة الصفحة «$3» من $4 إلى $5.",
+       "default-skin-not-found": "أخ! الواجهة الافتراضية للويكي الخاصة بك، والمعرفة في <code dir=\"ltr\">$wgDefaultSkin</code> ك<code>$1</code>، غير متوفرة.\n\nعملية تنصيبك يبدو أنها تحتوي على {{PLURAL:$4|الواجهة|الواجهات}} التالية. انظر [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] للمعلومات حول كيف تفعل  {{PLURAL:$4|ها|هم وتختار الافتراضي}}.\n\n$2\n\n; لو أنك قمت بتنصيب ميدياويكي حالا:\n: أنت ربما قمت بالتنصيب من git, أو مباشرة من الكود المصدري باستخدام طريقة أخرى. هذا متوقع. حاول تنصيب بعض الواجهات من [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory]، عن طريق تحميل:\n:* تحميل [https://www.mediawiki.org/wiki/Download tarball installer]، والذي يأتي مع واجهات وامتدادات عديدة. أنت يمكنك نسخ مجلد ال<code>skins/</code> مباشرة منه.\n:* تحميل ال  واجهات الtarballs الفردية من [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins استخدام Git لتحميل الواجهات].\n: فعل هذا ينبغي ألا يتعارض مع مستودع git الخاص بك لو أنك مطور ميدياويكي.\n\n; لو أنك قمت بترقية ميدياويكي حالا:\n: MediaWiki 1.24 وأحدث لم يعد يقوم بتفعيل الواجهات المنصبة تلقائيا (انظر [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). أنت يمكنك نسخ {{PLURAL:$5|السطر التالي|السطور التالية}} إلى <code>LocalSettings.php</code> لتفعيل {{PLURAL:$5||كل}}  {{PLURAL:$5|الواجهة|الواجهات}} المنصبة:\n\n<pre dir=\"ltr\">$3</pre>\n\n; لو أنك قمت بتعديل <code>LocalSettings.php</code> حالا:\n: فتحقق مجددا من أسماء الواجهات للأخطاء الإملائية.",
+       "default-skin-not-found-no-skins": "أخ! الواجهة الافتراضية للويكي الخاصة بك، والمعرفة في <code>$wgDefaultSkin</code> ك<code>$1</code>، غير متوفرة.\n\nأنت ليس لديك أي واجهات منصبة.\n\n; لو أنك قد قمت بتنصيب أو ترقية ميدياويكي حالا:\n: أنت على الأرجح قد قمت بالتنصيب من git، أو مباشرة من الكود المصدري باستخدام طريقة أخرى. هذا متوقع. MediaWiki 1.24 وأحدث لا يحتوي على أي واجهات في المستودع الرئيسي. حاول تنصيب بعض الواجهات من  [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory]، عن طريق تحميل [https://www.mediawiki.org/wiki/Download tarball installer], والذي يأتي مع واجهات وامتداات عديدة. أنت يمكنك نسخ مجلد ال<code>skins/</code> منه.\n:* تحميل tarballs الواجهات الفردية من [https://www.mediawiki.org/wiki/Special:SkinDistributor mediawiki.org].\n:* [https://www.mediawiki.org/wiki/Download_from_Git#Using_Git_to_download_MediaWiki_skins استخدام Git لتحميل الواجهات].\n: فعل هذا ينبغي ألا يتداخل مع مستودع git الخاص بك لو أنك مطور ميدياويكي. انظر [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] للمعلومات حول كيفية تفعيل الواجهات واختيار الافتراضي.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (مفعل)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 (<strong>ملغاة</strong>)",
        "mediastatistics": "إحصاءات الميديا",
        "sessionprovider-nocookies": "قد يتم تعطيل الكوكيز. تأكد من تمكين ملفات تعريف الأرتباط وأبد مرةأخرى.",
        "randomrootpage": "صفحة جذر عشوائية",
        "log-action-filter-block": "نوع المنع:",
+       "log-action-filter-contentmodel": "نوع تغيير موديل المحتوى:",
        "log-action-filter-delete": "نوع الحذف:",
        "log-action-filter-import": "نوع الاستيراد:",
        "log-action-filter-managetags": "نوع فعل إدارة الوسوم:",
        "log-action-filter-move": "نوع النقل:",
        "log-action-filter-newusers": "نوع إنشاء الحساب:",
+       "log-action-filter-patrol": "نوع الخفر:",
        "log-action-filter-protect": "نوع الحماية:",
        "log-action-filter-rights": "نوع تغيير الصلاحية",
+       "log-action-filter-suppress": "نوع الإخفاء:",
        "log-action-filter-upload": "نوع الرفع:",
        "log-action-filter-all": "الكل",
        "log-action-filter-block-block": "منع",
        "log-action-filter-block-reblock": "منع التعديل",
        "log-action-filter-block-unblock": "رفع المنع",
+       "log-action-filter-contentmodel-change": "تغيير موديل المحتوى",
+       "log-action-filter-contentmodel-new": "إنشاء صفحة بموديل محتوى غير قياسي",
        "log-action-filter-delete-delete": "حذف الصفحات",
        "log-action-filter-delete-restore": "استرجاع الصفحات",
        "log-action-filter-delete-event": "حذف السجلات",
        "log-action-filter-delete-revision": "حذف المراجعات",
        "log-action-filter-import-interwiki": "استيراد عابر للويكي",
+       "log-action-filter-import-upload": "استيراد بواسطة رفع XML",
        "log-action-filter-managetags-create": "إنشاء الوسوم",
        "log-action-filter-managetags-delete": "حذف الوسوم",
+       "log-action-filter-managetags-activate": "تفعيل الوسم",
+       "log-action-filter-managetags-deactivate": "تعطيل الوسم",
+       "log-action-filter-move-move": "نقل بدون الكتابة على التحويلات",
+       "log-action-filter-move-move_redir": "نقل مع الكتابة على التحويلات",
+       "log-action-filter-newusers-create": "إنشاء بواسطة مستخدم مجهول",
+       "log-action-filter-newusers-create2": "إنشاء بواسطة مستخدم مسجل",
        "log-action-filter-newusers-autocreate": "إنشاء آلي",
        "log-action-filter-newusers-byemail": "الإنشاء بكلمة مرور مرسلة عبر البريد الإلكتروني",
+       "log-action-filter-patrol-patrol": "خفر يدوي",
+       "log-action-filter-patrol-autopatrol": "خفر أوتوماتيكي",
        "log-action-filter-protect-protect": "حماية",
        "log-action-filter-protect-modify": "تعديل الحماية",
        "log-action-filter-protect-unprotect": "رفع الحماية",
+       "log-action-filter-protect-move_prot": "نقل الحماية",
        "log-action-filter-rights-rights": "تغيير يدوي",
+       "log-action-filter-rights-autopromote": "تغيير أوتوماتيكي",
+       "log-action-filter-suppress-event": "إخفاء السجل",
+       "log-action-filter-suppress-revision": "إخفاء المراجعة",
+       "log-action-filter-suppress-delete": "إخفاء الصفحة",
+       "log-action-filter-suppress-block": "إخفاء المستخدم بواسطة المنع",
+       "log-action-filter-suppress-reblock": "إخفاء المستخدم بواسطة إعادة المنع",
        "log-action-filter-upload-upload": "رفع جديد",
        "log-action-filter-upload-overwrite": "إعادة الرفع",
+       "authmanager-authn-not-in-progress": "عملية التحقق ليست جارية أو بينات الجلسة تم فقدها. من فضلك ابدأ مرة ثانية من البداية.",
+       "authmanager-authn-no-primary": "الاعتماد الموفر لم يمكن التحقق منه.",
+       "authmanager-authn-no-local-user": "الاعتماد الموفر غير مرتبط بأي مستخدم على هذه الويكي.",
+       "authmanager-authn-no-local-user-link": "الاعتمادات الموفرة صحيحة لكن غير مرتبطة بأي مستخدم على هذه الويكي. سجل الدخول باستخدام طريقة أخرى، أو أنشيء مستخدما جديدا، وستمتلك الاختيار لوصل اعتماداتك السابقة لذلك الحساب.",
+       "authmanager-authn-autocreate-failed": "الإنشاء التلقائي لحساب محلي فشل: $1",
+       "authmanager-change-not-supported": "الاعتمادات الموفرة لم يمكن تغييرها، حيث أن لا شيء سيستخدمها.",
        "authmanager-create-disabled": "إنشاء الحسابات معطل.",
        "authmanager-create-from-login": "لإنشاء حساب، برجاء ملء الحقول أدناه.",
+       "authmanager-create-not-in-progress": "إنشاء الحساب ليس جاريا أو بيانات الجلسة تم فقدها. من فضلك ابدأ ثانية من البداية.",
+       "authmanager-create-no-primary": "الاعتمادات الموفرة لم يمكن استخدامها لإنشاء الحساب.",
+       "authmanager-link-no-primary": "الاعتماد الموفر لم يمكن استخدامه لوصل الحسابات.",
+       "authmanager-link-not-in-progress": "وصل الحساب ليس جاريا أو بيانات الجلسة تم فقدها. من فضلك ابدأ ثانية منذ البداية.",
+       "authmanager-authplugin-setpass-failed-title": "تغيير كلمة السر فشل",
+       "authmanager-authplugin-setpass-failed-message": "إضافة التحقق رفضت تغيير كلمة السر.",
+       "authmanager-authplugin-create-fail": "إضافة التحقق رفضت إنشاء الحساب.",
+       "authmanager-authplugin-setpass-denied": "إضافة التحقق لا تسمح بتغيير كلمات السر.",
+       "authmanager-authplugin-setpass-bad-domain": "نطاق غير صحيح.",
+       "authmanager-autocreate-noperm": "إنشاء الحساب التلقائي غير مسموح به.",
+       "authmanager-autocreate-exception": "إنشاء الحسابات التلقائي تم تعطيله مؤقتا نظرا للأخطاء السابقة.",
+       "authmanager-userdoesnotexist": "حساب المستخدم \"$1\" غير مسجل.",
+       "authmanager-userlogin-remembermypassword-help": "ما إذا كانت كلمة السر ينبغي أن يتم تذكرها لأطول من مدة الجلسة.",
+       "authmanager-username-help": "اسم المستخدم للتوثيق.",
+       "authmanager-password-help": "كلمة السر للتوثيق",
+       "authmanager-domain-help": "النطاق للتوثيق الخارجي.",
        "authmanager-retype-help": "كلمة المرور مرة أخرى للتأكيد.",
        "authmanager-email-label": "البريد الإلكتروني",
        "authmanager-email-help": "عنوان البريد الإلكتروني",
        "authmanager-provider-password": "توثيق مبني على كلمة المرور",
        "authmanager-provider-password-domain": "توثيق مبني على كلمة المرور والنطاق",
        "authmanager-provider-temporarypassword": "كلمة مرور مؤقتة",
+       "authprovider-confirmlink-message": "بناء على محاولات تسجيل الدخول الحديثة الخاصة بك، فالحسابات التالية يمكن وصلها بحساب الويكي الخاص بك. وصلهم يفعل تسجيل الدخول عبر هذه الحسابات. من فضلك اختر أيهم ينبغي أن يتم وصلها.",
+       "authprovider-confirmlink-request-label": "الحسابات التي ينبغي أن يتم وصلها",
+       "authprovider-confirmlink-success-line": "$1: تم الوصل بشكل صحيح.",
+       "authprovider-confirmlink-failed": "وصل الحساب لم ينجح بشكل كامل: $1",
+       "authprovider-confirmlink-ok-help": "الاستمرار بعد عرض رسائل فشل الوصل.",
        "authprovider-resetpass-skip-label": "تخطى",
        "authprovider-resetpass-skip-help": "تخطي إعادة تعيين كلمة المرور",
+       "authform-nosession-login": "عملية التحقق كانت ناجحة، لكن متصفحك لا يمكنه \"تذكر\" أنك مسجل الدخول.\n\n$1",
+       "authform-nosession-signup": "الحساب تم إنشاؤه، لكن متصفحك لا يمكنه cannot \"تذكر\" أنك مسجل الدخول.\n\n$1",
+       "authform-newtoken": "توكين مفقود. $1",
+       "authform-notoken": "توكين مفقود",
+       "authform-wrongtoken": "توكين خاطئ",
+       "specialpage-securitylevel-not-allowed-title": "غير مسموح به",
+       "specialpage-securitylevel-not-allowed": "عذرا، أنت غير مسموح لك باستخدام هذه الصفة لأن هويتك لا يمكن التحقق منها.",
+       "authpage-cannot-login": "غير قادر على بدء عملية تسجيل الدخول.",
+       "authpage-cannot-login-continue": "غير قادر على الاستمرار في تسجيل الدخول. جلستك على الأرجح انتهت صلاحيتها.",
+       "authpage-cannot-create": "غير قادر على بدء عملية إنشاء الحساب.",
+       "authpage-cannot-create-continue": "غير قادر على الاستمرار في إنشاء الحساب. جلستك على الأرجح انتهت صلاحيتها.",
+       "authpage-cannot-link": "غير قادر على بدء عملية وصل الحسابات.",
+       "authpage-cannot-link-continue": "غير قادر على الاستمرار في وصل الحساب. جلستك على الأرجح انتهت صلاحيتها.",
        "cannotauth-not-allowed-title": "الإذن مرفوض",
+       "cannotauth-not-allowed": "أنت غير مسموح لك باستخدام هذه الصفحة",
        "changecredentials": "تغيير الاعتماد",
        "changecredentials-submit": "تغيير الاعتماد",
+       "changecredentials-invalidsubpage": "$1 ليس نوع اعتماد صحيح.",
+       "changecredentials-success": "اعتماداتك تم تغييرها.",
        "removecredentials": "إزالة الاعتماد",
        "removecredentials-submit": "إزالة الاعتماد",
+       "removecredentials-invalidsubpage": "$1 ليس نوع اعتمادات صحيح.",
+       "removecredentials-success": "اعتماداتك تمت إزالتها.",
+       "credentialsform-provider": "نوع الاعتمادات:",
        "credentialsform-account": "اسم الحساب:",
        "cannotlink-no-provider-title": "لا توجد حسابات قابلة للربط",
        "cannotlink-no-provider": "لا توجد حسابات قابلة للربط",
        "linkaccounts": "ربط الحسابات",
+       "linkaccounts-success-text": "الحساب تم وصله.",
        "linkaccounts-submit": "اربط الحسابات",
-       "unlinkaccounts": "إزالة ربط الحسابات"
+       "unlinkaccounts": "إزالة ربط الحسابات",
+       "unlinkaccounts-success": "الحساب تم فك وصله.",
+       "authenticationdatachange-ignored": "تغيير بيانات التحقق لم يتم التعامل معه. ربما لم يتم ضبط موفر؟",
+       "userjsispublic": "من فضلك لاحظ: صفحات الجافاسكريبت الفرعية لا ينبغي أن تحتوي غلى بيانات سرية بما أنها يمكن رؤيتها بواسطة المستخدمين الآخرين.",
+       "usercssispublic": "من فضل لاحظ: صفحات الCSS الفرعية لا ينبغي أن تحتوي على بيانات سرية بما أنها يمكن رؤيتها بواسطة المستخدمين الآخرين."
 }
index 1a537ce..76c2859 100644 (file)
        "userlogin-loggedin": "سیر حال حاضیردا {{GENDER:$1|$1}} عونوانیندا گیریش ائدیب سیز.\nآشاغیداکی فورمودان بیر آیری ایشلدن عونوانیندا گیریش اوچون ایشلدین.",
        "userlogin-reauth": "{{GENDER:$1|$1}} اوْلدوغونوزو تأیید ائتمک اۆچون یئنه گیرمه‌لیسینیز.",
        "userlogin-createanother": "بیر باشقا حساب یارات",
-       "createacct-emailrequired": "ایمیل آدرسی",
+       "createacct-emailrequired": "ایمئیل آدرسی",
        "createacct-emailoptional": "ایمیل آدرسی (ایستگه باغلی)",
        "createacct-email-ph": "ایمیل آدرسینیزی یازین",
        "createacct-another-email-ph": "ایمیل آدرسینیزی یازین",
index 403fb6c..1dfc717 100644 (file)
        "passwordreset-username": "Імя ўдзельніка:",
        "passwordreset-domain": "Дамэн:",
        "passwordreset-capture": "Паказаць выніковы электронны ліст?",
-       "passwordreset-capture-help": "Калі Вы пазначыце гэтае поле, электронны ліст (з часовым паролем), будзе паказаны Вам як толькі ён будзе дасланы ўдзельніку.",
+       "passwordreset-capture-help": "Калі Вы пазначыце гэтае поле, электронны ліст (з часовым паролем) будзе паказаны Вам, як толькі ён будзе дасланы ўдзельніку.",
        "passwordreset-email": "Адрас электроннай пошты:",
        "passwordreset-emailtitle": "Падрабязнасьці рахунку ў {{GRAMMAR:месны|{{SITENAME}}}}",
        "passwordreset-emailtext-ip": "Нехта (магчыма Вы, з IP-адрасу $1) зрабіў запыт на скіданьне вашага паролю ў {{GRAMMAR:месны|{{SITENAME}}}} ($4). {{PLURAL:$3|1=Наступны рахунак удзельніка зьвязаны|Наступныя рахункі ўдзельнікаў зьвязаныя}} з гэтым адрасам электроннай пошты:\n\n$2\n\n{{PLURAL:$3|1=Гэты часовы пароль будзе|Гэтыя часовыя паролі будуць}} дзейнічаць $5 {{PLURAL:$5|дзень|дні|дзён}}.\nЦяпер Вам неабходна ўвайсьці і выбраць новы пароль. Калі нехта іншы зрабіў гэты запыт, ці Вы ўспомнілі Ваш пачатковы пароль, які ня хочаце мяняць, Вы можаце праігнараваць гэтае паведамленьне, і працягваць выкарыстоўваць стары пароль.",
        "rollbacklinkcount-morethan": "адкаціць больш за $1 {{PLURAL:$1|рэдагаваньне|рэдагаваньні|рэдагаваньняў}}",
        "rollbackfailed": "Памылка адкату",
        "rollback-missingparam": "У запыце адсутнічаюць абавязковыя парамэтры.",
+       "rollback-missingrevision": "Не атрымалася загрузіць зьвесткі вэрсіі.",
        "cantrollback": "Немагчыма адкаціць зьмену; апошні рэдактар — адзіны аўтар гэтай старонкі.",
        "alreadyrolled": "Немагчыма адкаціць апошнюю зьмену [[:$1]], якую {{GENDER:$2|зрабіў|зрабіла}} [[User:$2|$2]] ([[User talk:$2|гутаркі]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); нехта іншы ўжо зьмяніў старонку альбо адкаціў зьмены.\n\nАпошнія зьмены зробленыя [[User:$3|$3]] ([[User talk:$3|гутаркі]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Кароткае апісаньне зьменаў было: <em>$1</em>.",
        "undeletehistorynoadmin": "Гэтая старонка была выдаленая.\nПрычына выдаленьня пададзена ніжэй, разам са зьвесткамі ўдзельніка, які рэдагаваў старонку перад выдаленьнем.\nТэкст выдаленай старонкі могуць глядзець толькі адміністратары.",
        "undelete-revision": "Выдаленая вэрсія $1 (ад $5 $4) ўдзельніка $3:",
        "undeleterevision-missing": "Некарэктная ці неіснуючая вэрсія.\nВерагодна Вы карысталіся няслушнай спасылкай, альбо, магчыма, вэрсія была выдаленая з архіву.",
+       "undeleterevision-duplicate-revid": "$1 {{PLURAL:$1|вэрсія ня можа быць адноўленая|вэрсіі ня могуць быць адноўленыя|вэрсіяў ня могуць быць адноўленыя}}, бо {{PLURAL:$1|1=яе|іх}} <code>rev_id</code> ужо выкарыстоўваецца.",
        "undelete-nodiff": "Папярэдняя вэрсія ня знойдзеная.",
        "undeletebtn": "Аднавіць",
        "undeletelink": "паглядзець/аднавіць",
index c0f4249..c8eb76b 100644 (file)
@@ -54,6 +54,7 @@
        "tog-watchdefault": "Добавяне на страниците, които редактирам, в списъка ми за наблюдение",
        "tog-watchmoves": "Добавяне на преместените от мен страници и файлове към списъка ми за наблюдение",
        "tog-watchdeletion": "Добавяне на изтритите от мен страници и файлове към списъка ми за наблюдение",
+       "tog-watchuploads": "Добавяне на новите качени от мен файлове към списъка ми за наблюдение",
        "tog-watchrollback": "Добавяне на страници, в които съм {{GENDER:$1|извършвал|извършвала}} отмяна на редакции в списъка ми за наблюдениe",
        "tog-minordefault": "Отбелязване на всички промени като малки по подразбиране",
        "tog-previewontop": "Показване на предварителния преглед преди текстовата кутия",
        "history-feed-description": "Редакционна история на страницата в {{SITENAME}}",
        "history-feed-item-nocomment": "$1 в $2",
        "history-feed-empty": "Исканата страница не съществува — може да е била изтрита или преименувана. Опитайте да [[Special:Search|потърсите]] нови страници, които биха могли да са ви полезни.",
+       "history-edit-tags": "Редактиране етикетите на избраните редакции",
        "rev-deleted-comment": "(резюмето е премахнато)",
        "rev-deleted-user": "(името на автора е изтрито)",
        "rev-deleted-event": "(записът е изтрит)",
index 8c3c3d8..e631f1c 100644 (file)
        "october-date": "$1 a viz Here",
        "november-date": "$1 a viz Du",
        "december-date": "$1 a viz Kerzu",
+       "period-am": "mintin",
+       "period-pm": "goude-merenn",
        "pagecategories": "{{PLURAL:$1|Rummad |Rummad }}",
        "category_header": "Niver a bennadoù er rummad \"$1\"",
        "subcategories": "Isrummadoù",
        "passwordreset-emailtext-user": "Goulennet en deus an implijer $1 war  {{SITENAME}} e vefe degaset soñj dezhañ eus titouroù e gont evit {{SITENAME}} ($4). Emañ liammet {{PLURAL:$3|ar gont implijer|ar c'hontoù implijer}} da-heul gant ar chomlec'h postel-mañ :\n\n$2\n\nMont a raio da get {{PLURAL:$3|ar ger-tremen da c'hortoz|ar gerioù-tremen da c'hortoz}} a-benn {{PLURAL:$5|un devezh|$5 deiz}}.\nMat e vefe deoc'h kevreañ ha dibab ur ger-tremen nevez bremañ. Mard eo bet goulennet kement-se gant unan bennak all pe m'hoc'h eus soñj eus ho ker-tremen orin ha mar ne fell ket deoc'h e cheñch ken, na daolit ket evezh ouzh ar gemennadenn-mañ ha dalc'hit d'ober gant ho ker-tremen kozh.",
        "passwordreset-emailelement": "Anv implijer :           \n$1\n\nGer-tremen da c'hortoz : \n$2",
        "passwordreset-emailsentemail": "Kaset ez eus bet ur postel deoc'h da adderaouekaat ho ker-tremen.",
-       "passwordreset-emailsent-capture": "Ur postel evit aderaouekaat ho ker-tremen, evel diskouezet amañ dindan, zo bet kaset.",
-       "passwordreset-emailerror-capture": "Kaset ez eus bet ur postel degas da soñj evel m'emañ diskouezet amañ dindan met c'hwitet eo bet ar gasadenn d'an {{GENDER:$2|implijer|implijerez}} : $1",
        "changeemail": "Kemmañ ar chomlec'h postel",
        "changeemail-header": "Kemmañ chomlec'h postel ar gont",
        "changeemail-no-info": "Ret eo deoc'h bezañ kevreet a-benn mont d'ar bajenn-se war-eeun.",
        "undo-nochange": "War a seblant eo bet nullet ar c'hemm dija.",
        "undo-summary": "Dizober kemmoù $1 a-berzh [[Special:Contributions/$2|$2]] ([[User talk:$2|kaozeal]])",
        "undo-summary-username-hidden": "Dizober ar reizhadenn $1 gant un implijer kuzhet",
-       "cantcreateaccounttitle": "Dibosupl krouiñ ar gont",
        "cantcreateaccount-text": "Stanket eo bet ar c'hrouiñ kontoù adal ar chomlec'h IP ('''$1''') gant [[User:$3|$3]].\n\nAn abeg roet gant $3 zo ''$2''",
        "viewpagelogs": "Gwelet ar marilhoù evit ar bajenn-mañ",
        "nohistory": "Ar bajenn-mañ n'he deus tamm istor ebet.",
        "mostrevisions": "Pennadoù bet kemmet ar muiañ",
        "prefixindex": "An holl bajennoù a grog gant...",
        "prefixindex-namespace": "An holl bajennoù enno ur rakger (esaouenn anv $1)",
+       "prefixindex-submit": "Diskouez",
        "prefixindex-strip": "Lemel ar rakger er roll",
        "shortpages": "Pennadoù berr",
        "longpages": "Pennadoù hir",
        "usereditcount": "$1 {{PLURAL:$1|kemm|kemm}}",
        "usercreated": "{{GENDER:$3|Krouet}} d'an $1 da $2",
        "newpages": "Pajennoù nevez",
+       "newpages-submit": "Diskouez",
        "newpages-username": "Anv implijer :",
        "ancientpages": "Pennadoù koshañ",
        "move": "adenvel",
        "apisandbox": "Poull-traezh API",
        "apisandbox-api-disabled": "Diweredekaet eo API war al lec'hienn-mañ.",
        "apisandbox-intro": "Grit gant ar bajenn-mañ evit amprouiñ '''servij Web API MediaWiki'''.\nKit da deuler ur sell war [https://www.mediawiki.org/wiki/API:Main_page titouroù an API] evit gouzout hiroc'h war an doare da embreger API. Da skouer :\n[https://www.mediawiki.org/wiki/API#A_simple_example gwelet danvez ur bennbajenn]. Dibabit un oberiadenn bennak evit gwelet skouerioù all",
+       "apisandbox-unfullscreen": "Diskouez ar bajenn",
        "apisandbox-submit": "Sevel ar goulenn",
        "apisandbox-reset": "Riñsañ",
-       "apisandbox-examples": "Skouer",
-       "apisandbox-results": "Disoc'h",
+       "apisandbox-retry": "Klask en-dro",
+       "apisandbox-examples": "Skouerioù",
+       "apisandbox-dynamic-parameters": "Arventenn ouzhpenn",
+       "apisandbox-dynamic-parameters-add-label": "Ouzhpennañ un arventenn:",
+       "apisandbox-dynamic-parameters-add-placeholder": "Anv an arventenn",
+       "apisandbox-results": "Disoc'hoù",
        "apisandbox-request-url-label": "Goulenn URL :",
        "apisandbox-request-time": "Pad ar goulenn: $1",
        "booksources": "Oberennoù dave",
        "specialloguserlabel": "Implijer :",
        "speciallogtitlelabel": "Bukadenn (titl pe implijer) :",
        "log": "Marilhoù",
+       "logeventslist-submit": "Diskouez",
        "all-logs-page": "An holl varilhoù foran",
        "alllogstext": "Diskwel a-gevret an holl varilhoù hegerz war {{SITENAME}}.\nGallout a rit strishaat ar mod diskwel en ur zibab ar marilh, an anv implijer (diwallit ouzh ar pennlizherennoù) pe ar bajenn a fell deoc'h (memes tra).",
        "logempty": "Goullo eo istor ar bajenn-mañ.",
        "log-title-wildcard": "Klask an titloù a grog gant an destenn-mañ",
        "showhideselectedlogentries": "Diskouez/kuzhat penngerioù ar marilh bet diuzet",
+       "checkbox-select": "Diuzañ : $1",
+       "checkbox-all": "An holl",
+       "checkbox-none": "Hini ebet",
+       "checkbox-invert": "Eilpennañ",
        "allpages": "An holl bajennoù",
        "nextpage": "Pajenn war-lerc'h ($1)",
        "prevpage": "Pajenn gent ($1)",
        "cachedspecial-viewing-cached-ts": "Emaoc'h o sellet ouzh ur stumm krubuilhet eus ar bajenn-mañ a c'hall bezañ dispredet un disterañ.",
        "cachedspecial-refresh-now": "Gwelet an hini nevesañ.",
        "categories": "Roll ar rummadoù",
+       "categories-submit": "Diskouez",
        "categoriespagetext": "Er {{PLURAL:$1|rummad|rummadoù}} da-heul ez eus pajennoù pe restroù media.\nNe ziskouezer ket amañ ar [[Special:UnusedCategories|Rummadoù dizimplij]].\nGwelet ivez ar [[Special:WantedCategories|rummadoù goulennet a vank]].",
        "categoriesfrom": "Diskouez ar rummadoù en ur gregiñ gant :",
        "deletedcontributions": "Degasadennoù diverket un implijer",
        "wlheader-showupdated": "E '''tev''' emañ merket ar pajennoù bet kemmet abaoe ar wezh ziwezhañ hoc'h eus sellet outo",
        "wlnote": "Setu aze {{PLURAL:$1|ar c'hemm diwezhañ|ar '''$1''' kemm diwezhañ}} c'hoarvezet e-kerzh an {{PLURAL:$2|eurvezh|'''$2''' eurvezh}} diwezhañ, d'an $3 da $4.",
        "wlshowlast": "Diskouez an $1 eurvezh $2 devezh diwezhañ",
+       "watchlist-hide": "Kuzhat",
+       "watchlist-submit": "Diskouez",
+       "wlshowhideminor": "kemmoù dister",
+       "wlshowhidebots": "robotoù",
+       "wlshowhideliu": "implijerien enrollet",
+       "wlshowhideanons": "implijerien dizanv",
        "wlshowhidemine": "ma c'hemmoù",
        "watchlist-options": "Dibarzhioù ar roll evezhiañ",
        "watching": "Heuliet...",
        "whatlinkshere-hidelinks": "$1 liamm",
        "whatlinkshere-hideimages": "$1 ar restroù liammet",
        "whatlinkshere-filters": "Siloù",
+       "whatlinkshere-submit": "Mont",
        "autoblockid": "Emstankañ #$1",
        "block": "Stankañ an implijer",
        "unblock": "Distankañ an implijer",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|adweladenn}} enporzhiet eus $2",
        "javascripttest": "Amprouadenn JavaScript",
        "javascripttest-qunit-intro": "Sellet ouzh [$1 an teulioù amprouiñ] e mediawiki.org.",
-       "tooltip-pt-userpage": "Ho pajenn implijer",
+       "tooltip-pt-userpage": "{{GENDER:|Ho pajenn}} implijer",
        "tooltip-pt-anonuserpage": "Ar bajenn implijer evit ar c'homlec'h IP implijet ganeoc'h",
-       "tooltip-pt-mytalk": "Ho pajenn gaozeal",
+       "tooltip-pt-mytalk": "{{GENDER:|Ho}} pajenn gaozeal",
        "tooltip-pt-anontalk": "Kaozeadennoù diwar-benn ar c'hemmoù graet adal ar chomlec'h-mañ",
-       "tooltip-pt-preferences": "Ma fenndibaboù",
+       "tooltip-pt-preferences": "{{GENDER:|Ma}} fenndibaboù",
        "tooltip-pt-watchlist": "Roll ar pajennoù evezhiet ganeoc'h.",
-       "tooltip-pt-mycontris": "Roll ho tegasadennoù",
+       "tooltip-pt-mycontris": "Roll ho tegasadennoù{{GENDER:|your}}",
        "tooltip-pt-login": "Daoust ma n'eo ket ret, ec'h aliomp deoc'h kevreañ",
        "tooltip-pt-logout": "Digevreañ",
        "tooltip-pt-createaccount": "Erbedet eo deoc'h krouiñ ur gont ha kevreañ ; n'eo ket ret koulskoude.",
        "tooltip-t-recentchangeslinked": "Roll ar c'hemmoù diwezhañ war ar pajennoù liammet ouzh ar bajenn-mañ",
        "tooltip-feed-rss": "Magañ ar red RSS evit ar bajenn-mañ",
        "tooltip-feed-atom": "Magañ ar red Atom evit ar bajenn-mañ",
-       "tooltip-t-contributions": "Gwelet roll degasadennoù an implijer-mañ",
+       "tooltip-t-contributions": "Gwelet roll degasadennoù {{GENDER:$1|this user}} an implijer-mañ",
        "tooltip-t-emailuser": "Kas ur postel d'an implijer-mañ",
        "tooltip-t-upload": "Enporzhiañ ur skeudenn pe ur restr media war ar servijer",
        "tooltip-t-specialpages": "Roll an holl bajennoù dibar",
        "tooltip-ca-nstab-category": "Gwelet pajenn ar rummad",
        "tooltip-minoredit": "Merkañ ar c'hemm-mañ evel dister",
        "tooltip-save": "Enrollañ ho kemmoù",
+       "tooltip-publish": "Embann ho kemmoù",
        "tooltip-preview": "Rakwelet ar c'hemmoù; trugarez d'ober gantañ a-raok enrollañ!",
        "tooltip-diff": "Diskouez ar c'hemmoù degaset ganeoc'h en destenn.",
        "tooltip-compareselectedversions": "Sellet ouzh an diforc'hioù zo etre daou stumm diuzet ar bajenn-mañ.",
        "confirm-watch-top": "Ouzhpennañ ar bajenn-mañ d'ho roll evezhiañ",
        "confirm-unwatch-button": "Mat eo",
        "confirm-unwatch-top": "Lemel ar bajenn-mañ a-ziwar ho roll evezhiañ",
+       "confirm-rollback-button": "Mat eo",
        "quotation-marks": "« $1 »",
        "imgmultipageprev": "&larr; pajenn gent",
        "imgmultipagenext": "pajenn war-lerc'h &rarr;",
        "iranian-calendar-m11": "11vet miz Jalāli",
        "iranian-calendar-m12": "12vet miz Jalāli",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|kaozeal]])",
+       "timezone-local": "Lec'hel",
        "duplicate-defaultsort": "Diwallit : Frikañ a ra an alc'hwez dre ziouer \"$2\" an hini a oa a-raok \"$1\".",
        "version": "Stumm",
        "version-extensions": "Astennoù staliet",
        "tags-source-header": "Mammenn",
        "tags-active-header": "Oberiant ?",
        "tags-hitcount-header": "Kemmoù balizennet",
+       "tags-actions-header": "Oberoù",
        "tags-active-yes": "Ya",
        "tags-active-no": "Ket",
        "tags-edit": "aozañ",
        "special-characters-group-thai": "Thai",
        "special-characters-group-lao": "Laoseg",
        "special-characters-group-khmer": "Khmer",
-       "api-error-blacklisted": "Dibabit un titl deskrivañ all",
        "randomrootpage": "Pajenn wrizienn dargouezhek"
 }
index 8e71647..9cafa75 100644 (file)
        "trackingcategories-msg": "Categoria de seguiment",
        "trackingcategories-name": "Nom del missatge",
        "trackingcategories-desc": "Criteris d'inclusió de categoria",
+       "restricted-displaytitle-ignored": "Pàgines amb títols a mostrar ignorats",
        "noindex-category-desc": "La pàgina conté una paraula màgica <code><nowiki>__NOINDEX__</nowiki></code> (i és en un espai de noms on està permesa) i per tant no està indexada per robots.",
        "index-category-desc": "La pàgina conté un <code><nowiki>__INDEX__</nowiki></code> (i és en un espai de noms on està permès) i per tant està indexat per robots quan normalment no ho seria.",
        "post-expand-template-inclusion-category-desc": "La mida de la pàgina és més gran que <code>$wgMaxArticleSize</code> un cop expandides totes les plantilles, per tant algunes plantilles no s'han expandit.",
        "rollbacklinkcount": "reverteix $1 {{PLURAL:$1|edició|edicions}}",
        "rollbacklinkcount-morethan": "reverteix més de $1 {{PLURAL:$1|edició|edicions}}",
        "rollbackfailed": "No s'ha pogut revocar",
+       "rollback-missingrevision": "No es poden carregar les dades de revisió.",
        "cantrollback": "No s'han pogut revertir les edicions; el darrer col·laborador és l'únic autor de la pàgina.",
        "alreadyrolled": "No es pot revertir la darrera modificació de [[:$1]]\nde l'usuari [[User:$2|$2]] ([[User talk:$2|Discussió]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]). Algú altre ja ha modificat o revertit la pàgina.\n\nLa darrera modificació l'ha fet l'usuari [[User:$3|$3]] ([[User talk:$3|Discussió]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "El resum d'edició és: <em>$1</em>.",
        "changecontentmodel-success-text": "S'ha canviat el tipus de contingut de [[:$1]].",
        "changecontentmodel-cannot-convert": "El contingut a [[:$1]] no es pot convertir a un tipus de $2.",
        "changecontentmodel-nodirectediting": "El model de contingut $1 no permet l'edició directa",
+       "changecontentmodel-emptymodels-title": "No hi ha models de contingut",
+       "changecontentmodel-emptymodels-text": "El contingut a [[:$1]] no pot convertir-se a cap tipus.",
        "log-name-contentmodel": "Registre de canvis del model de contingut",
        "log-description-contentmodel": "Esdeveniments relacionats amb els models de contingut d'una pàgina",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|ha canviat}} el model de contingut de la pàgina $3 de «$4» a «$5»",
        "lockdbsuccesstext": "S'ha bloquejat la base de dades.<br />\nRecordeu-vos de [[Special:UnlockDB|treure el bloqueig]] quan hàgiu acabat el manteniment.",
        "unlockdbsuccesstext": "S'ha desbloquejat la base de dades del projecte {{SITENAME}}.",
        "lockfilenotwritable": "No es pot modificar el fitxer de la base de dades de bloquejos. Per a blocar o desblocar la base de dades, heu de donar-ne permís de modificació al servidor web.",
+       "databaselocked": "La bases de dades ja està bloquejada.",
        "databasenotlocked": "La base de dades no està bloquejada.",
        "lockedbyandtime": "(per $1 el $2 a les $3)",
        "move-page": "Reanomena $1",
        "redirect-page": "ID de pàgina",
        "redirect-revision": "Revisió de la pàgina",
        "redirect-file": "Nom del fitxer",
+       "redirect-logid": "ID de registre",
        "redirect-not-exists": "No s'ha trobat el valor",
        "fileduplicatesearch": "Cerca fitxers duplicats",
        "fileduplicatesearch-summary": "Cerca fitxers duplicats d'acord amb el seu valor de resum.",
        "tags-edit-title": "Modifica les etiquetes",
        "tags-edit-manage-link": "Gestiona les etiquetes",
        "tags-edit-revision-selected": "{{PLURAL:$1|Revisió seleccionada|Revisions seleccionades}} de [[:$2]]:",
+       "tags-edit-revision-legend": "Afegeix o suprimeix etiquetes {{PLURAL:$1|d'aquesta revisió|de totes les $1 revisions}}",
        "tags-edit-logentry-legend": "Afegeix o suprimeix etiquetes {{PLURAL:$1|d'aquesta entrada del registre|de totes les entrades del registre}}",
        "tags-edit-existing-tags": "Etiquetes existents:",
        "tags-edit-existing-tags-none": "<em>Cap</em>",
index dcc4c5c..ee26071 100644 (file)
        "page_last": "тlаьххьара",
        "histlegend": "Кхетор: (хӀинцалера.) — йолучу башхон къастам; (хьалх.) — хьалхалерчу башхон къастам; '''ж''' — жимо бозалца болу хийцам.",
        "history-fieldset-title": "АгӀона хийцамаш",
-       "history-show-deleted": "Ð\94Ó\80аÑ\8fÑ\85инарш",
+       "history-show-deleted": "Ð\94Ó\80аÑ\8fÑ\8cÑ\85нарш",
        "histfirst": "ширниш",
        "histlast": "хьалхарниш",
        "historysize": "($1 {{PLURAL:$1|байт}})",
index d95f26e..a2a081a 100644 (file)
        "rollbacklinkcount-morethan": "vrácení více než $1 {{PLURAL:$1|editace|editací}} zpět",
        "rollbackfailed": "Nešlo vrátit zpět",
        "rollback-missingparam": "V požadavku chybí povinné parametry.",
+       "rollback-missingrevision": "Nepodařilo se načíst data revize.",
        "cantrollback": "Nelze vrátit zpět poslední editaci, neboť poslední přispěvatel je jediným autorem této stránky.",
        "alreadyrolled": "Nelze vrátit zpět poslední editaci [[:$1]] od uživatele [[User:$2|$2]] ([[User talk:$2|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), protože někdo jiný již stránku editoval nebo vrátil tuto změnu zpět.\n\nPoslední editaci této stránky {{GENDER:$3|provedl|provedla|provedl uživatel}} [[User:$3|$3]] ([[User talk:$3|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Shrnutí editace bylo: <em>$1</em>.",
index 7956f83..13b9137 100644 (file)
        "revertmove": "zurück verschieben",
        "delete_and_move_text": "Die Seite „[[:$1]]“ existiert bereits.\nMöchtest du diese löschen, um die Seite verschieben zu können?",
        "delete_and_move_confirm": "Ja, Seite löschen",
-       "delete_and_move_reason": "gelöscht, um Platz für die Verschiebung von „[[$1]]“ zu machen",
+       "delete_and_move_reason": "Gelöscht, um Platz für die Verschiebung von „[[$1]]“ zu machen",
        "selfmove": "Ursprungs- und Zielname sind gleich.\nEine Seite kann nicht auf sich selbst verschoben werden.",
        "immobile-source-namespace": "Seiten des „$1“-Namensraums können nicht verschoben werden",
        "immobile-target-namespace": "Seiten können nicht in den „$1“-Namensraum verschoben werden",
index 6445fad..388d6c2 100644 (file)
        "rcnotefrom": "Cêr de <strong>$2</strong> ra nata {{PLURAL:$5|vurnayışiyê}} asenê (tewr vêşi <strong>$1</strong> asenê) <strong>$3, $4</strong>",
        "rclistfrom": "$3 $2 ra tepiya vurnayışanê neweyan bımocne",
        "rcshowhideminor": "vurriyayışê werdi $1",
-       "rcshowhideminor-show": "Bımocne",
+       "rcshowhideminor-show": "Bıasne",
        "rcshowhideminor-hide": "Bınımne",
        "rcshowhidebots": "botan $1",
-       "rcshowhidebots-show": "Bımocne",
+       "rcshowhidebots-show": "Bıasne",
        "rcshowhidebots-hide": "Bınımne",
        "rcshowhideliu": "karberê qeydbiyayeyi $1",
        "rcshowhideliu-show": "Bıasne",
        "rcshowhideliu-hide": "Bınımne",
        "rcshowhideanons": "karberê bênameyi $1",
-       "rcshowhideanons-show": "Bımocne",
+       "rcshowhideanons-show": "Bıasne",
        "rcshowhideanons-hide": "Bınımne",
        "rcshowhidepatr": "$1 vurnayışê ke dewriya geyrayê",
        "rcshowhidepatr-show": "Bıasne",
        "rcshowhidepatr-hide": "Bınımne",
        "rcshowhidemine": "vurnayışanê mı $1",
-       "rcshowhidemine-show": "Bımocne",
+       "rcshowhidemine-show": "Bıasne",
        "rcshowhidemine-hide": "Bınımne",
        "rcshowhidecategorization": "kategorizasyonê pele $1",
        "rcshowhidecategorization-show": "Bıasne",
        "diff": "ferq",
        "hist": "verên",
        "hide": "Bınımne",
-       "show": "Bımocne",
+       "show": "Bıasne",
        "minoreditletter": "q",
        "newpageletter": "N",
        "boteditletter": "b",
index 61e06c0..67bedaa 100644 (file)
        "userrights-reason": "कारण:",
        "userrights-unchangeable-col": "तमीले परिवर्तन गद्द नसक्ने समूहहरू",
        "userrights-conflict": "प्रयोगकर्ताको अधिकार परिवर्तनमी मतभेद भयो ! कृपया तमरो परिवर्तन पुनरावलोकन तथा पुष्टि गर ।",
-       "userrights-removed-self": "तमà¥\80लà¥\87 à¤¸à¤«à¤²à¤¤à¤¾à¤ªà¥\82रà¥\8dवà¤\95 à¤\86फà¥\8dनà¥\8b à¤\85धिà¤\95ारहरà¥\82लाà¤\88 à¤®à¥\87à¤\9fायà¥\8c à¥¤ à¤¤à¥\8dयà¥\88 à¤\95ारण à¤¤à¤®à¥\80 à¤\85ब यो पानो हेद्द नाइसक्दा ।",
+       "userrights-removed-self": "तमलà¥\87 à¤¸à¤«à¤²à¤¤à¤¾à¤ªà¥\82रà¥\8dवà¤\95 à¤\86फनà¥\8b à¤\85धिà¤\95ारहरà¥\82लाà¤\88 à¤®à¥\87à¤\9fाया à¥¤ à¤¤à¥\8dयà¥\88 à¤\95ारण à¤¤à¤® à¤\86ब यो पानो हेद्द नाइसक्दा ।",
        "group": "समूह:",
        "group-user": "प्रयोगकर्ताहरू",
        "group-autoconfirmed": "स्वत स्थापित प्रयोगकर्ताहरू",
        "group-sysop-member": "{{GENDER:$1|प्रबन्धक}}",
        "group-bureaucrat-member": "{{GENDER:$1|प्रशासक}}",
        "group-suppress-member": "{{GENDER:$1|दबाउन्या}}",
-       "grouppage-user": "{{एनयस:आयोजना}}:प्रयोगकर्ताहरू",
+       "grouppage-user": "{{ns:project}}:प्रयोगकर्ताहरू",
        "grouppage-autoconfirmed": "{{एनयस:आयोजना}}:स्वनिर्धारित प्रयोगकर्ताहरू",
        "grouppage-bot": "{{एनयस:आयोजना}}:बोटहरु",
-       "grouppage-sysop": "{{एनयस:आयोजना}}:प्रबन्धकहरु",
+       "grouppage-sysop": "{{ns:project}}:प्रबन्धकहरू",
        "grouppage-bureaucrat": "{{एनयस:आयोजना}}:प्रशासकहरू",
        "grouppage-suppress": "{{एनयस:आयोजना}}:लुकौन्या",
        "right-read": "पृष्ठहरू पढ",
        "right-upload_by_url": "URL बठे फाइल उर्ध्वभरण गर्ने",
        "right-purge": "साइटको क्याश( cache) निश्चित नगरिकनै पर्ज(Purge) गर्ने",
        "right-writeapi": "लेखन API प्रयोग गद्य्या",
+       "right-delete": "पृष्ठहरू मेट्ने",
        "right-bigdelete": "लामो इतिहास भयाका पानाहरू मेट्ट्या",
        "right-deleterevision": "खुलाइयाको पानाहरू मेटाउन्या र मेटायाको रद्द गद्या",
        "right-deletedtext": "मेट्याका संशोधन बीचका मेट्याका पाठ र परिवर्तनहरू हेद्या",
+       "right-undelete": "मेट्याको पाना फर्काउने",
        "right-suppressionlog": "व्यक्तिगत लगहरू हेद्या",
        "right-block": "अरु प्रयोगकर्तानलाई सम्पादन गद्दाकी ब्लक गर",
        "right-unblockself": "आफुलाई खुल्ला गर ।",
index 0c6b8ef..7a99fe3 100644 (file)
        "morenotlisted": "Cl'elèinch ché an n'é mìa finî.",
        "mypage": "Pàgina",
        "mytalk": "Al mē discusiòun",
-       "anontalk": "Discusiòun per cl' IP ché",
+       "anontalk": "Discusiòun",
        "navigation": "Navigasiòun",
        "and": "&#32;e",
        "qbfind": "Câta",
        "laggedslavemode": "'''Atèinti:''' la pàgina la pré avèir mìa al revisiòun pió nōv.",
        "readonly": "'Database' bluchê",
        "enterlockreason": "Scréver al mutîv dal blôch, precişêr quând a 's pèinsa che 'l vègna tôt via.",
-       "readonlytext": "In cól mumèint ché al databêş l'é bluchê e an 's pōlen fêr né zûnti né mudéfichi. Al blôch ed sôlit l'é lighê a 'na revişiòun normêla e quând la srà finîda al gnirà sbluchê. \n\nL'aminitradōr dal sistēma ch' al l'à bluchê l'à dê cla spiegasiòun ché: $1",
+       "readonlytext": "In cól mumèint ché al databêş l'é bluchê e an 's pōlen fêr né zûnti né mudéfichi. Al blôch ed sôlit l'é lighê a 'na revişiòun normêla e quând la srà finîda al gnirà sbluchê. \n\nL'aminitradōr dal sistēma ch' l'à urdnê 'l blôch l'à dê cla spiegasiòun ché: $1",
        "missing-article": "Al datebêş an n'à mìa catê al tèst ed 'na pàgina ch' l' aré duvû catêres sòt' al nòm \"$1\" $2. Ed sôlit còst a sucēd quând a vîn arciamê, a partîr da la stòria dal mudéfichi o dal cunfrûnt tra versiòun, un colegamèint a 'na pàgina scanşlêda, a un cunfrûnt tra versiòun che gh'în mìa o a un cunfrûnt tra versiòun cun la stòria dal mudéfichi scanşlêda. In chês cuntrâri, a s'é pubabilmèint catê un erōr int al prugrâma ed Media Wiki. A se dmânda al piaşèir ed comunichêr còl ch'é sucès a un [[Special:ListUsers/sysop|amministadōr]] e comunichêregh l'indirés (URL) in quistiòun.",
        "missingarticle-rev": "(nómer ed la versiòun: $1)",
        "missingarticle-diff": "(Diff: $1, $2)",
        "viewsource": "Guêrda la surzéia",
        "viewsource-title": "Guêrda la surzéia 'd $1",
        "actionthrottled": "L'asiòun la vîn tardêda.",
-       "actionthrottledtext": "Cme mişûra 'd sicurèsa cûnt'r al spam soquânti operasiòun a vînen limitêdi a 'n nómer mâsim ed vôlti in un precîş peréiod ed tèimp, in cól chêş ché a s'é bèle andê d'ed là 'd cól lémit. A se dmânda ed turnêr a pruvêr tra soquânt minût.",
+       "actionthrottledtext": "Cme mişûra 'd sicurèsa cûntra l'abûş soquânti operasiòun a vînen limitêdi a 'n nómer mâsim ed vôlti in un precîş peréiod ed tèimp, in cól chêş ché a 's é bèle andê d'ed là 'd cól lémit. A 's e-dmânda 'd turnêr a pruvêr tra soquânt minût.",
        "protectedpagetext": "Cla pàgina ché l'é stêda prutèta per impidîr la mudéfica o êtri operasiòun.",
        "viewsourcetext": "L'é pusébil vèder e cupiêr al côdis surzéia ed cla pàgina ché.",
        "viewyourtext": "L'é pusébil vèder e cupiêr al côdis surzéia dal <strong>tō mudéfichi</strong> ed cla pàgina ché.",
        "protectedinterface": "Cla pàgina ché la gh'à 'n elemèint ch' al fa pêrt dal colegamèint tra utèint e al progrâma 'd cól sît ché e l'é prutèta per schivşêr pusébil abûş. Per zuntêr o mudufichêr tradusiòun per tót i sistēma wiki druvêr [https://translatewiki.net/ translatewiki.net], al prugèt 'd adatamèint a ògni léngva 'd MediaWiki.",
        "editinginterface": "<strong>Atèinti:</strong> Al tèst ed cla pàgina ché 'l fa pêrt dal colegamèint tra utèint e 'l prugrâma dal sît.  Tót' al modéfichi fâti a cla pàgina ché a se spècen in sém a i mesâg vést per tót j utèint ed cól wiki ché.",
        "translateinterface": "Per zuntêr o mudifichêr al tradusiòun vâlidi in sém a tót i wiki, drōva [https://translatewiki.net/ translatewiki.net], al prugèt Media Wiki p'r al léngui di divêrs pôst.",
-       "cascadeprotected": "Insém a cla pàgina ché an n'é mìa pusébil fêr dal mudéfichi perchè l'é dèinter {{PLURAL:$1|int la pàgina sgnêda ché  'd sègvit, ch' l'é stêda prutèta|int al pàgini sgnêdi ché  'd sègvit, ch' în stêdi prutèti}} cun la prutesiòun ch' la 's arfà in cuntinvasiòun:\n$2",
+       "cascadeprotected": "In sém a cla pàgina ché an n'é mìa pusébil fêr dal mudéfichi perchè l'é dèinter {{PLURAL:$1|int la pàgina sgnêda ché  'd sègvit, ch' l'é stêda prutèta|int al pàgini sgnêdi ché  'd sègvit, ch' în stêdi prutèti}} cun la prutesiòun ch' la 's arfà in cuntinvasiòun:\n$2",
        "namespaceprotected": "An 's gh'à mìa i permès necesâri per mudifichêr al pàgini dal spâsi di nòm <strong>$1</strong>.",
        "customcssprotected": "An 's gh'à mìa i permès necesâri per mudifichêr cla pàgina CSS ché, perchè la gh'à dèinter al j impustasiòun personêli 'd n' êter utèint.",
        "customjsprotected": "An 's gh'à mìa i permès necesâri per mudifichêr cla pàgina JavaScript ché, perchè la gh'à dèinter al j impustasiòun personêli 'd n' êter utèint.",
        "mypreferencesprotected": "An 's gh'à mìa i permès necesâri per cambiêr al preferèinsi personêli.",
        "ns-specialprotected": "An n'é mìa pusébil mudifichêr al pàgini specêli.",
        "titleprotected": "Al tétol ed cla pagina ché l'é stê bluchê da [[User:$1|$1]].\nCòst l'é al mutîv: <em>$2</em>.",
-       "filereadonlyerror": "An n'é mìa stê pusébil mudifichêr al file \"$1\" perchè al depôsit di file \"$2\" a 's pōl sōl lēzer.\n\nL'aministradōr ch' al l'à bluchê l'à dê cla spiegasiòun ché:\"$3\".",
+       "filereadonlyerror": "An n'é mìa stê pusébil mudifichêr al file \"$1\" perchè al depôsit di file \"$2\" a 's pōl sōl lēzer.\n\nL'aministradōr dal sistēma ch' al l'à bluchê l'à dê cla spiegasiòun ché:\"$3\".",
        "invalidtitle-knownnamespace": "Tétol mìa vâlid cme spâsi di nòm \"$2\" e tèst \"$3\"",
        "invalidtitle-unknownnamespace": "Tétol mìa vâlid cun spâsi di nòm mìa cgnusû \"$1\" e tèst \"$2\"",
        "exception-nologin": "An t'é mìa gnû dèinter",
        "createacct-reason": "Mutîv",
        "createacct-reason-ph": "Perchè ét drē fêr 'n' êtra utèinsa",
        "createacct-submit": "Fà la tó utèinsa",
-       "createacct-another-submit": "Fà 'n' êtra utèinsa.",
+       "createacct-another-submit": "Fà l' utèinsa.",
        "createacct-benefit-heading": "{{SITENAME}} crès grâsia a persòuni cme té.",
        "createacct-benefit-body1": "{{PLURAL:$1|mudéfica|mudéfichi}}",
        "createacct-benefit-body2": "{{PLURAL:$1|pàgina|pàgini}}",
        "nocookieslogin": "Per fêr l'ingrès a {{SITENAME}} a 's dēv druvêr i cookie che rişûlten bluchê. Tōrna fêr l'ingrès dôp avèir şbluchê i cookie int al tó navigadōr.",
        "nocookiesfornew": "L'iscrisiòun utèint an n'é mìa stêda fâta, perchè òm mìa prû cunfermêr la só urégin. Veréfica 'd avèir şbluchê i cookie, tōrna carghêr cla pàgina ché e prōva incòra.",
        "noname": "Al nòm utèint scrét an n'é mìa vâlid.",
-       "loginsuccesstitle": "Ingrès fât.",
+       "loginsuccesstitle": "Fât l'ingrès.",
        "loginsuccess": "''' T'é stê coleghê al terminêl {{SITENAME}} cun al nòm utèint '''$1'''.",
-       "nosuchuser": "An n'é mìa registrê nisûn utèint cun al nòm \"$1\". I nòm utèin în sensébil al lètri grândi. Veréfica al nòm scrét o [[Special:CreateAccount|fà un nōv ingrès]].",
+       "nosuchuser": "An n'é mìa registrê nisûn utèint cun al nòm \"$1\". I nòm utèin în sensébil al lètri grândi. Veréfica al nòm scrét o [[Special:CreateAccount|fà 'na nōva utèinsa]].",
        "nosuchusershort": "An gh'é mìa registrê un utèint ciamê ''$1''. Veréfica al nòm scrét.",
        "nouserspecified": "L'é necesâri precişêr un nòm utèint.",
        "login-userblocked": "Cl'utèinsa ché l'é bluchêda. An n'é pusébil fêr l'ingrès.",
        "passwordreset-emailtext-user": "L'utèint $1 ed {{SITENAME}} l'à dmandê de spidîregh 'na nōva cêva 'd ingrès per andêr dèinter a {{SITENAME}} ($4). {{PLURAL:$3|L'utèint inscrét| J utèint inscrét}} a sté indirés ed pôsta eletrônica în:\n\n$2 \n\n{{PLURAL:$3|Cla cêva 'd ingrès pruvişôria ché la scadrà| St' al cêvi 'd ingrès pruvişôri ché scadrân}} dôp {{PLURAL:$5|ûn dé|$5 dé}}. Ét duvrés andêr dèinter e sernîr 'na cêva 'd ingrès nōva adès. \n\nSe t'é mìa stê té a fêr la dmânda, o s' ét t'é ricurdê la cêva 'd ingrès uriginêla e an 't vō mia pió cambiêrla, ét pō scanşlêr cól mesâg ché e cuntinvêr a druvêr la tó cêva 'd ingrès vècia",
        "passwordreset-emailelement": "Nòm utèint: \n$1\n.\nCêva 'd ingrès pruvişôria: \n$2",
        "passwordreset-emailsentemail": "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès.",
-       "passwordreset-emailsent-capture": "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, ché sòta a gh'é al tèst che gh'é scrét.",
-       "passwordreset-emailerror-capture": "É stê fât un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, scréta ché 'd sègvit. La spedisiòun {{GENDER:$2|a l'utèint}} an n'é mia 'riusîda:$1",
        "changeemail": "Câmbia l'indirés ed la pôsta eletrônica",
        "changeemail-header": "Câmbia l'indirés ed la pôsta eletrônica 'd la tó inscrisiòun.",
        "changeemail-no-info": "Per andêr dèinter diretamèint a cla pàgina ché 't gh'ê da fêr l'ingrès.",
        "undo-nochange": "A sèmbra che la mudéfica la sìa bèle stêda scanşlêda.",
        "undo-summary": "Scanşlê la mudéfica $1 ed [[Special:Contributions/$2|$2]]\n([[User talk:$2|discusiòun]])",
        "undo-summary-username-hidden": "Scanşlê la modéfica $1 ed 'n utèin lughê",
-       "cantcreateaccounttitle": "Impusébil registrêr un utèint",
        "cantcreateaccount-text": "La registrasiòun ed cl'indirés IP ché ('''$1''') l'é stêda bluchêda da [[User:$3|$3]]. \n\nAl mutîv dal blôch dê da $3 l'é còst: ''$2''.",
        "cantcreateaccount-range-text": "La registrasiòun da indirés IP int l'intervâl <strong>$1</strong>, in dó gh'é dèinter al tó  (<strong>$4</strong>), l'é stêda bluchêda da [[User:$3|$3]]. \n\nAl mutîv dê da $3 l'é <em>$2</em>",
        "viewpagelogs": "Guêrda la stòria 'd cla pàgina ché",
index 13eb863..6e92c24 100644 (file)
@@ -47,7 +47,8 @@
                        "Robin van der Vliet",
                        "Zciric",
                        "Psychoslave",
-                       "Orikrin1998"
+                       "Orikrin1998",
+                       "Gamliel Fishkin"
                ]
        },
        "tog-underline": "Substrekado de ligiloj:",
@@ -90,7 +91,7 @@
        "tog-ccmeonemails": "Sendi al mi kopiojn de retpoŝtaĵoj, kiujn mi sendis al aliaj uzantoj.",
        "tog-diffonly": "Ne montri paĝan enhavon sub la ŝanĝmontrilo",
        "tog-showhiddencats": "Montri kaŝitajn kategoriojn",
-       "tog-norollbackdiff": "Nemontri diferencon post plenumado de ŝanĝomalfaro",
+       "tog-norollbackdiff": "Ne montri diferencon post plenumado de ŝanĝomalfaro",
        "tog-useeditwarning": "Averti min kiam mi forlasas redaktan paĝon kun nekonservitaj ŝanĝoj",
        "tog-prefershttps": "Ĉiam uzu sekuran konekton ensalutite",
        "underline-always": "Ĉiam",
        "period-am": "atm.",
        "period-pm": "ptm.",
        "pagecategories": "{{PLURAL:$1|Kategorio|Kategorioj}}",
-       "category_header": "Artikoloj en kategorio “$1”",
+       "category_header": "Paĝoj en kategorio “$1”",
        "subcategories": "Subkategorioj",
        "category-media-header": "Dosieroj en kategorio “$1”",
-       "category-empty": "<em>Tiu ĉi kategorio nuntempe enhavas neniun artikolon aŭ plurmedian dosieron.</em>",
+       "category-empty": "<em>Tiu ĉi kategorio nuntempe enhavas neniun paĝon aŭ plurmedian dosieron.</em>",
        "hidden-categories": "{{PLURAL:$1|Kaŝita kategorio|Kaŝitaj kategorioj}}",
        "hidden-category-category": "Kaŝitaj kategorioj",
        "category-subcat-count": "{{PLURAL:$2|Ĉi tiu kategorio havas nur la jenan subkategorion.|Ĉi tiu kategorio havas la {{PLURAL:$1|jenan subkategorion|$1 jenajn subkategoriojn}}, el $2 entute.}}",
        "noindex-category": "Neindeksitaj paĝoj",
        "broken-file-category": "Paĝoj kun rompita ligilo al dosiero",
        "about": "Pri",
-       "article": "Artikolo",
+       "article": "Enhava paĝo",
        "newwindow": "(en nova fenestro)",
        "cancel": "Nuligi",
        "moredotdotdot": "Pli...",
        "tagline": "El {{SITENAME}}",
        "help": "Helpo",
        "search": "Serĉi",
+       "search-ignored-headings": " #<!-- lasu ĉi tiun linion ekzakte kiel ĝi estas --> <pre>\n# Titoloj kiuj estos ignoritaj en serĉado.\n# Ŝanĝoj al ĉi tio efikas tuj kiam la paĝo kun la titolo estas indeksita.\n# Vi povas igi reindeksadon de paĝo, farinte nulan redakton.\n# La sintakso estas jena:\n#   * Io ajn ekde signo \"#\" ĝis la fino de la linio estas komento.\n#   * Ĉiu nemalplena linio estas la ekzakta titolo por ignori usklecon kaj kion ajn.\nReferencoj\nEksteraj ligiloj\nVidu Ankaŭ\n #</pre> <!-- lasu ĉi tiun linion ekzakte kiel ĝi estas -->",
        "searchbutton": "Serĉi",
        "go": "Ek",
        "searcharticle": "Ek",
-       "history": "Historio de versioj",
+       "history": "Historio de paĝo",
        "history_short": "Historio",
        "updatedmarker": "ĝisdatigita de post mia lasta vizito",
        "printableversion": "Presebla versio",
        "protect": "Protekti",
        "protect_change": "ŝanĝi",
        "protectthispage": "Protekti la paĝon",
-       "unprotect": "Ŝanĝi protekadon",
-       "unprotectthispage": "Ŝanĝi protektadon de ĉi tiu paĝo",
+       "unprotect": "Ŝanĝi protekton",
+       "unprotectthispage": "Ŝanĝi protekton de ĉi tiu paĝo",
        "newpage": "Nova paĝo",
        "talkpage": "Diskuti la paĝon",
        "talkpagelinktext": "diskuto",
        "specialpage": "Speciala paĝo",
        "personaltools": "Personaj iloj",
-       "articlepage": "Vidi paĝenhavon",
+       "articlepage": "Vidi enhavan paĝon",
        "talk": "Diskuto",
        "views": "Vidoj",
        "toolbox": "Iloj",
-       "userpage": "Vidi uzulan paĝon",
+       "userpage": "Vidi uzantopaĝon",
        "projectpage": "Rigardi projektopaĝon",
        "imagepage": "Vidi dosieropaĝon",
        "mediawikipage": "Vidi mesaĝopaĝon",
        "jumpto": "Iri al:",
        "jumptonavigation": "navigado",
        "jumptosearch": "serĉi",
-       "view-pool-error": "Bedaŭrinde la serviloj estas tro uzataj ĉi-momente.\nTro da uzantoj provas vidi ĉi tiun paĝon.\nBonvolu atendi iom antaŭ ol provi atingi ĝin denove.\n\n$1",
-       "generic-pool-error": "Bedaŭrinde la serviloj estas tro uzataj ĉi-momente.\nTro da uzantoj provas vidi ĉi tiun risurcon.\nBonvolu iom atendi antaŭ vi provos atingi ĝin denove.",
+       "view-pool-error": "Pardonon, la serviloj estas tro uzataj ĉi-momente.\nTro da uzantoj provas vidi ĉi tiun paĝon.\nBonvolu atendi iom antaŭ ol provi atingi ĝin denove.\n\n$1",
+       "generic-pool-error": "Pardonon, la serviloj estas tro uzataj ĉi-momente.\nTro da uzantoj provas vidi ĉi tiun risurcon.\nBonvolu iom atendi antaŭ vi provos atingi ĝin denove.",
        "pool-timeout": "Tempolimo atingita dum atendo de ŝlosado",
        "pool-queuefull": "Atendovico de servilaro estas plena.",
        "pool-errorunknown": "Nekonata eraro",
        "ok": "Bone",
        "retrievedfrom": "Elŝutita el  \"$1\"",
        "youhavenewmessages": "{{PLURAL:$3|Vi havas}} $1 ($2).",
-       "youhavenewmessagesfromusers": "Riceviĝis $1 de {{PLURAL:$3|alia uzanto|$3 uzantoj}} ($2).",
+       "youhavenewmessagesfromusers": "Riceviĝis $1 de {{PLURAL:$3|alia uzanto|$3 uzantoj}} ($2).\n\nVi havas $1 de {{PLURAL:$3|alia uzanto|$3 uzantoj}} ($2).",
        "youhavenewmessagesmanyusers": "Riceviĝis $1 de multaj uzantoj ($2).",
        "newmessageslinkplural": "{{PLURAL:$1|nova mesaĝo|999=novaj mesaĝoj}}",
        "newmessagesdifflinkplural": "$1 {{PLURAL:$1|ŝanĝo|ŝanĝoj}}",
        "rollbacklinkcount-morethan": "nuligi pli ol $1 {{PLURAL:$1|redakton|redaktojn}}",
        "rollbackfailed": "Malfaro malsukcesis",
        "rollback-missingparam": "Mankas neprajn parametrojn de peto.",
+       "rollback-missingrevision": "Ne eblas ŝarĝi datumojn pri revizioj.",
        "cantrollback": "Ne povas restarigi antaŭan redakton; la redaktinto lasta estas la sola aŭtoro de la paĝo.",
        "alreadyrolled": "Ne povas restarigi la lastan redakton de [[:$1]] de la [[User:$2|$2]] ([[User talk:$2|diskuto]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\npro tio, ke oni intertempe redaktis aŭ restarigis la paĝon.\nLa lasta redaktinto estis [[User:$3|$3]] ([[User talk:$3|diskuto]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "La resumo de la redakto estis: <em>$1</em>.",
index 7099422..38de0a1 100644 (file)
        "rollbacklinkcount-morethan": "revertir más de $1 {{PLURAL:$1|edición|ediciones}}",
        "rollbackfailed": "No se pudo revertir",
        "rollback-missingparam": "Faltan parámetros requeridos en la solicitud.",
+       "rollback-missingrevision": "No se pueden cargar datos de la revisión.",
        "cantrollback": "No se puede revertir la edición;\nel último colaborador es el único autor de esta página.",
        "alreadyrolled": "No se puede revertir la última edición de [[:$1]] hecha por [[User:$2|$2]] ([[User talk:$2|discusión]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nalguien más ya ha editado o revertido esa página.\n\nLa última edición fue hecha por [[User:$3|$3]] ([[User talk:$3|discusión]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "El resumen de la edición fue: <em>$1</em>.",
        "sp-contributions-newbies-sub": "Para cuentas nuevas",
        "sp-contributions-newbies-title": "Contribuciones de usuarios nuevos",
        "sp-contributions-blocklog": "registro de bloqueos",
-       "sp-contributions-suppresslog": "contribuciones de {{GENDER:$1|usuario|usuaria}} suprimidas",
-       "sp-contributions-deleted": "contribuciones de {{GENDER:$1|usuario|usuaria}} borradas",
+       "sp-contributions-suppresslog": "contribuciones {{GENDER:$1|del usuario|de la usuaria}} suprimidas",
+       "sp-contributions-deleted": "contribuciones {{GENDER:$1|del usuario|de la usuaria}} borradas",
        "sp-contributions-uploads": "subidas",
        "sp-contributions-logs": "registros",
        "sp-contributions-talk": "discusión",
        "unlinkaccounts": "Desvincular cuentas",
        "unlinkaccounts-success": "Se ha desvinculado la cuenta.",
        "authenticationdatachange-ignored": "El cambio den los datos de autentificacion no fue realizado. ¿Tal vez, no se configuró un proveedor?",
-       "userjsispublic": "Recuerda: Las subpáginas JavaScript no deberían contener datos confidenciales, pues otros usuarios los pueden ver.",
-       "usercssispublic": "Recuerda: Las subpáginas CSS no deberían contener datos confidenciales, pues otros usuarios los pueden ver."
+       "userjsispublic": "Recuerda: las subpáginas JavaScript no deberían contener datos confidenciales, pues otros usuarios los pueden ver.",
+       "usercssispublic": "Recuerda: las subpáginas CSS no deberían contener datos confidenciales, pues otros usuarios los pueden ver."
 }
index 1e24c8f..e265a0e 100644 (file)
        "watchthis": "پی‌گیری این صفحه",
        "savearticle": "صفحه ذخیره شود",
        "savechanges": "ذخیرهٔ تغییرات",
-       "publishpage": "ذخÛ\8cرÙ\87 صفحه",
-       "publishchanges": "ذخÛ\8cرÙ\87 تغییرات",
+       "publishpage": "اÙ\86تشار صفحه",
+       "publishchanges": "اÙ\86تشار تغییرات",
        "preview": "پیش‌نمایش",
        "showpreview": "پیش‌نمایش",
        "showdiff": "نمایش تغییرات",
        "grant-group-high-volume": "انجام فعالیت‌های حجم بالا",
        "grant-group-customization": "سفارشی‌سازی و تنظیمات",
        "grant-group-administration": "انجام اقدامات مدیریتی",
+       "grant-group-private-information": "دسترسی به اطلاعات محرمانهٔ خودتان",
        "grant-group-other": "فعالیت‌های متفرقه",
        "grant-blockusers": "بستن و باز کردن کاربرها",
        "grant-createaccount": "ایجاد حساب‌های کاربری",
        "grant-highvolume": "ویرایش با حجم بالا",
        "grant-oversight": "پنهان کردن ویرایش‌ها",
        "grant-patrol": "تغییرات گشت صفحات",
+       "grant-privateinfo": "دسترسی به اطلاعات محرمانه",
        "grant-protect": "حفاظت و عدم حفاظت صفحات",
        "grant-rollback": "واگردانی  تغییرات صفحات",
        "grant-sendemail": "ارسال ایمیل به دیگر کاربران",
        "action-applychangetags": "اعمال برچسب بر روی تغییرات شما",
        "action-changetags": "افزودن یا حذف برچسب قراردادی بر روی نسخه یا سیاهه ورودی‌ها",
        "action-deletechangetags": "حذف برچسب‌ها از پایگاه داده",
+       "action-purge": "خالی‌کردن میانگیر این صفحه",
        "nchanges": "$1 تغییر",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|از آخرین بازدید}}",
        "enhancedrc-history": "تاریخچه",
        "uploadstash-errclear": "پاک‌کردن پرونده‌ها ناموفق بود.",
        "uploadstash-refresh": "تازه کردن فهرست پرونده‌ها",
        "uploadstash-thumbnail": "نمایش بندانگشتی",
+       "uploadstash-exception": "ناتوان از ذخیره کردن بارگذاری در نهانگاه ($1): ''$2''.",
        "invalid-chunk-offset": "جابجایی نامعتبر قطعه",
        "img-auth-accessdenied": "منع دسترسی",
        "img-auth-nopathinfo": "PATH_INFO موجود نیست.\nسرور شما برای ردکردن این مقدار تنظیم نشده‌است.\nممکن است مبتنی بر سی‌جی‌آی باشد و از img_auth پشتیبانی نکند.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization را ببینید.",
        "watchnologin": "به سامانه وارد نشده‌اید",
        "addwatch": "افزودن به فهرست پی‌گیری",
        "addedwatchtext": "«[[:$1]]» و صفحهٔ بحث آن به [[Special:Watchlist|فهرست پی‌گیری‌های]] شما اضافه شد.",
+       "addedwatchtext-talk": "''[[:$1]]'' و صفحهٔ مرتبط به آن به [[Special:Watchlist|فهرست پی‌گیری]] شما افزوده شدند.",
        "addedwatchtext-short": "صفحه \" $1 \" به فهرست پیگیریهای خود اضافه شده است.",
        "removewatch": "حذف از فهرست پی‌گیری",
        "removedwatchtext": "صفحهٔ «[[:$1]]» و صفحهٔ بحث آن از [[Special:Watchlist|فهرست پی‌گیری‌های شما]] برداشته شد.",
+       "removedwatchtext-talk": "''[[:$1]]'' و صفحهٔ مرتبط به آن از [[Special:Watchlist|فهرست پی‌گیری]] شما حذف شدند.",
        "removedwatchtext-short": "صفحهٔ \"$1\" از فهرست پیگیری‌های شما حذف شده‌است.",
        "watch": "پی‌گیری",
        "watchthispage": "پی‌گیری این صفحه",
        "rollbacklinkcount-morethan": "واگردانی بیش از $1 ویرایش",
        "rollbackfailed": "واگردانی نشد",
        "rollback-missingparam": "فقدان پارامترهای ضروری در درخواست",
+       "rollback-missingrevision": "ناتوان از بارگیری اطلاعات نسخه.",
        "cantrollback": "نمی‌توان ویرایش را واگرداند؛\nآخرین مشارکت‌کننده تنها مؤلف این مقاله است.",
        "alreadyrolled": "واگردانی آخرین ویرایش [[:$1]] توسط [[User:$2|$2]] ([[User talk:$2|بحث]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) ممکن نیست؛\nپیش از این شخص دیگری مقاله را ویرایش یا واگردانی کرده‌است.\n\nآخرین ویرایش توسط [[User:$3|$3]] ([[User talk:$3|بحث]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) انجام شده‌است.",
        "editcomment": "خلاصهٔ ویرایش این بود:  <em>«$1»</em>.",
        "undeletehistorynoadmin": "این مقاله حذف شده‌است.\nدلیل حذف این مقاله به همراه مشخصات کاربرانی که قبل از حذف این صفحه را ویرایش کرده‌اند، در خلاصهٔ زیر آمده‌است.\nمتن واقعی این ویرایش‌های حذف شده فقط در دسترس مدیران است.",
        "undelete-revision": "نسخهٔ حذف شدهٔ $1 (به تاریخ $4 ساعت $5) توسط $3:",
        "undeleterevision-missing": "نسخه نامعتبر یا مفقود است.\nممکن است پیوندتان نادرست باشد یا اینکه نسخه از بایگانی حذف یا بازیابی شده باشد .",
+       "undeleterevision-duplicate-revid": "{{PLURAL:$1|یک نسخه|$1 نسخه}} احیا نشد، چون <code>rev_id</code> آن {{PLURAL:$1|نسخه|نسخه‌ها}} از پیش مورد استفاده بود.",
        "undelete-nodiff": "نسخهٔ قدیمی‌تری یافت نشد.",
        "undeletebtn": "احیا",
        "undeletelink": "نمایش/احیا",
        "undeletedrevisions": "$1 نسخه احیا {{PLURAL:$1|شد}}",
        "undeletedrevisions-files": "$1 نسخه و $2 پرونده احیا {{PLURAL:$1|شد|شدند}}.",
        "undeletedfiles": "$1 پرونده احیا {{PLURAL:$1|شد|شدند}}.",
-       "cannotundelete": "احیا ناموفق بود:\n$1",
+       "cannotundelete": "تÙ\85اÙ\85 Û\8cا Ø¨Ø®Ø´Û\8c Ø§Ø² Ø§Ø­Û\8cا Ù\86اÙ\85Ù\88Ù\81Ù\82 Ø¨Ù\88د:\n$1",
        "undeletedpage": "'''$1 احیا شد'''\n\nبرای دیدن سیاههٔ حذف‌ها و احیاهای اخیر به  [[Special:Log/delete|سیاههٔ حذف]] رجوع کنید.",
        "undelete-header": "برای دیدن صفحه‌های حذف‌شدهٔ اخیر [[Special:Log/delete|سیاههٔ حذف]] را ببینید.",
        "undelete-search-title": "جستجوی صفحه‌های حذف‌شده",
        "sp-contributions-newbies-sub": "برای تازه‌کاران",
        "sp-contributions-newbies-title": "مشارکت‌های کاربری برای حساب‌های تازه‌کار",
        "sp-contributions-blocklog": "سیاههٔ بسته‌شدن‌ها",
-       "sp-contributions-suppresslog": "مشارکت‌های فرونشانی‌شده",
-       "sp-contributions-deleted": "مشارکت‌های حذف‌شدهٔ کاربر",
+       "sp-contributions-suppresslog": "مشارکت‌های فرونشانی‌شده {{GENDER:$1|کاربر}}",
+       "sp-contributions-deleted": "مشارکت‌های حذف‌شدهٔ {{GENDER:$1|کاربر}}",
        "sp-contributions-uploads": "بارگذاری‌ها",
        "sp-contributions-logs": "سیاهه‌ها",
        "sp-contributions-talk": "بحث",
        "linkaccounts-submit": "پیوند حساب کاربری",
        "unlinkaccounts": "حذف پیوند حساب کاربری",
        "unlinkaccounts-success": "پیوند کاربری بدون پیوند شد.",
-       "authenticationdatachange-ignored": "به تغيير اطلاعات احراز هويت پرداخته نشد. آیا ممکن است که هيچ مهيا کننده‌ای برای اين کار تنظيم نشده باشد؟"
+       "authenticationdatachange-ignored": "به تغيير اطلاعات احراز هويت پرداخته نشد. آیا ممکن است که هيچ مهيا کننده‌ای برای اين کار تنظيم نشده باشد؟",
+       "userjsispublic": "لطفاً توجه کنید: زیرصفحه‌های جاوااسکریپت نباید حاوی اطلاعات محرمانه باشند چون توسط دیگران قابل مشاهده هستند.",
+       "usercssispublic": "لطفاً توجه کنید: زیرصفحه‌های سی‌اس‌اس نباید حاوی اطلاعات محرمانه باشند چون توسط دیگران قابل مشاهده هستند."
 }
index b699b2f..6c2190a 100644 (file)
        "unlockdbsuccesssub": "Verrouillage de la base de données supprimé",
        "lockdbsuccesstext": "La base de données a été verrouillée.<br />\nN'oubliez pas de la [[Special:UnlockDB|déverrouiller]] lorsque vous aurez terminé votre opération de maintenance.",
        "unlockdbsuccesstext": "La base de données a été déverrouillée.",
-       "lockfilenotwritable": "Le fichier de verrouillage de la base de données n'est pas inscriptible.\nPour bloquer ou débloquer la base de données, il doit être accessible par le serveur web.",
+       "lockfilenotwritable": "Le fichier de verrouillage de la base de données n'est pas inscriptible.\nPour bloquer ou débloquer la base de données, il doit être accessible en écriture par le serveur web.",
        "databaselocked": "La base de données est déjà verrouillée.",
        "databasenotlocked": "La base de données n'est pas verrouillée.",
-       "lockedbyandtime": "(par $1 le $2 à $3)",
+       "lockedbyandtime": "(par {{GENDER:$1|$1}} le $2 à $3)",
        "move-page": "Renommer $1",
        "move-page-legend": "Renommer une page",
        "movepagetext": "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom. L’ancien titre deviendra une page de redirection vers le nouveau titre. \nVous pouvez mettre à jour automatiquement les redirections qui pointent vers le titre original. \nSi vous choisissez de ne pas le faire, assurez-vous de vérifier toute [[Special:DoubleRedirects|double redirection]] ou [[Special:BrokenRedirects|redirection cassée]]. Vous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <strong>pas</strong> renommée s’il existe déjà une page portant le nouveau titre, sauf si cette dernière est une simple redirection avec un historique de modifications vierge. \nCela signifie que vous pouvez de nouveau renommer une page vers sa position d’origine si vous avez fait une erreur et que vous ne pouvez pas écraser une page existante.\n\n<strong>Attention !</strong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’avoir compris les conséquences de votre démarche avant de continuer.",
        "movepagetext-noredirectfixer": "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom.\nL’ancien titre deviendra une page de redirection vers le nouveau titre.\nVérifiez bien les [[Special:DoubleRedirects|doubles redirections]] ou les [[Special:BrokenRedirects|redirections cassées]].\nVous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.\n\nNotez que la page ne sera <strong>pas</strong> déplacée s’il existe déjà une page avec le nouveau titre, sauf si cette dernière a un historique de modifications vierge et est soit vide, soit une simple redirection. Ceci permet de renommer une page vers sa position d’origine si le déplacement s’avère erroné, et il est impossible d’écraser une page existante.\n\n<strong>Attention !</strong>\nCeci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d’en avoir compris les conséquences avant de continuer.",
        "movepagetalktext": "Si vous cochez cette case, la page de discussion associée sera automatiquement renommée, à moins qu’une page de discussion non vide existe déjà sous ce nouveau nom.\n\nDans ce cas, vous devrez renommer ou fusionner cette page de discussion manuellement si vous le désirez.",
-       "moveuserpage-warning": "'''Attention :''' Vous êtes sur le point de renommer une page d’utilisateur. Veuillez noter que seule la page sera renommée et que l’utilisateur '''ne''' sera '''pas''' renommé.",
+       "moveuserpage-warning": "<strong>Attention :</strong> Vous êtes sur le point de renommer une page d’utilisateur. Veuillez noter que seule la page sera renommée et que l’utilisateur <em>ne</em> sera <em>pas</em> renommé.",
        "movecategorypage-warning": "<strong>Avertissement :</strong> Vous êtes sur le point de renommer une page de catégorie. Veuillez noter que seule la catégorie sera renommée et <em>qu’aucune</em> des pages de l’ancienne catégorie ne sera transférée dans la nouvelle.",
        "movenologintext": "Pour pouvoir renommer une page, vous devez être [[Special:UserLogin|identifié{{GENDER:||e}}]] avec un compte utilisateur enregistré et d'ancienneté suffisante.",
        "movenotallowed": "Vous n'avez pas la permission de renommer les pages.",
        "movenotallowedfile": "Vous n'avez pas la permission de renommer les fichiers.",
-       "cant-move-user-page": "Vous n’avez pas la permission de renommer les pages principales d’utilisateurs.",
-       "cant-move-to-user-page": "Vous n’avez pas la permission de renommer une page vers une page utilisateur (à l’exception d’une sous-page).",
+       "cant-move-user-page": "Vous n’avez pas la permission de renommer les pages principales des utilisateurs (sauf les sous-pages).",
+       "cant-move-to-user-page": "Vous n’avez pas la permission de renommer une page vers une page utilisateur (mais vous pouvez le faire vers une sous-page utilisateur).",
        "cant-move-category-page": "Vous n'avez pas la permis de renommer les pages de catégorie.",
        "cant-move-to-category-page": "Vous n'avez pas la permission de renommer une page vers une page de catégorie.",
        "newtitle": "Nouveau titre :",
index 7e69455..2765143 100644 (file)
        "minoredit": "Mionathrú é seo",
        "watchthis": "Déan faire ar an lch seo",
        "savearticle": "Sábháil an lch",
+       "publishpage": "Foilsigh leathanach",
        "preview": "Réamhamharc",
        "showpreview": "Taispeáin réamhamharc",
        "showdiff": "Taispeáin athruithe",
        "recreate-moveddeleted-warn": "'''Rabhadh: Tá tú ag athchruthú leathanaigh a scriosadh cheana.'''\n\nAn bhfuil tú cinnte go bhfuil sé oiriúnach an leathanach seo a cur in eagar?\nCuirtear an loga scriosta ar fáil anseo mar áis:",
        "log-fulllog": "Féach ar an logchomhad iomlán",
        "undo-summary": "Cealaíodh athrú $1 le [[Special:Contributions/$2|$2]] ([[User talk:$2|plé]])",
-       "cantcreateaccounttitle": "Ní féidir cuntas a chruthú",
        "viewpagelogs": "Féach ar logaí faoin leathanach seo",
        "nohistory": "Níl aon stáir athraithe ag an leathanach seo.",
        "currentrev": "Leagan reatha",
        "tooltip-ca-nstab-category": "Féach ar an leathanach catagóire",
        "tooltip-minoredit": "Déan mionathrú den athrú seo",
        "tooltip-save": "Sábháil do chuid athruithe",
+       "tooltip-publish": "Foilsigh do chuid athruithe",
        "tooltip-preview": "Réamhamharc ar do chuid athruithe; úsáid an gné seo roimh a shábhálaíonn tú!",
        "tooltip-diff": "Taispeáin na difríochtaí áirithe a rinne tú don téacs",
        "tooltip-compareselectedversions": "Féach na difríochtaí idir an dhá leagain roghnaithe den leathanach seo.",
        "exif-gpsspeed-n": "Muirmhílte",
        "exif-gpsdirection-t": "Fíorthreo",
        "exif-gpsdirection-m": "Treo maighnéadach",
+       "exif-dc-publisher": "Foilsitheoir",
        "namespacesall": "iad uile",
        "monthsall": "gach mí",
        "confirmemail": "Deimhnigh do ríomhsheoladh",
index 3a86779..e6907d2 100644 (file)
        "rollbacklinkcount-morethan": "reverter máis de $1 {{PLURAL:$1|edición|edicións}}",
        "rollbackfailed": "Houbo un erro ao reverter as edicións",
        "rollback-missingparam": "Faltan parámetros obrigatorios na solicitude.",
+       "rollback-missingrevision": "Non se poden cargar datos da revisión.",
        "cantrollback": "Non se pode desfacer a edición; o último colaborador é o único autor desta páxina.",
        "alreadyrolled": "Non se pode desfacer a edición en \"[[:$1]]\" feita por [[User:$2|$2]] ([[User talk:$2|conversa]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); alguén máis editou ou desfixo os cambios desta páxina.\n\nA última edición fíxoa [[User:$3|$3]] ([[User talk:$3|conversa]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "O resumo de edición foi: <em>$1</em>.",
index 80cf567..47d668d 100644 (file)
        "alllogstext": "{{SITENAME}} ના લોગનો સંયુક્ત વર્ણન.\nતમે લોગનો પ્રકાર,સભ્ય નામ અથવા અસરગ્રસ્ત પાના આદિ પસંદ કરી તમારી યાદિ ટૂંકાવી શકો.",
        "logempty": "લોગમાં આને મળતી કોઇ વસ્તુ નથી",
        "log-title-wildcard": "આ શબ્દો દ્વારા શરૂ થનાર શીર્ષકો શોધો",
-       "showhideselectedlogentries": "પસàª\82દàª\97à«\80નà«\80 àª²à«\8bàª\97 àª¨à«\8bàª\82ધણà«\80àª\93 àª¬àª¤àª¾àªµà«\8b/àª\9bà«\82પાવો",
+       "showhideselectedlogentries": "પસàª\82દàª\97à«\80નà«\80 àª²à«\8bàª\97 àª¨à«\8bàª\82ધણà«\80àª\93 àª¬àª¤àª¾àªµà«\8b/àª\9bà«\81પાવો",
        "allpages": "બધા પાના",
        "nextpage": "આગળનું પાનું ($1)",
        "prevpage": "પાછળનું પાનું ($1)",
index bdc8691..db69923 100644 (file)
        "authmanager-authplugin-create-fail": "A hitelesítés beépülője megtagadta a fiók létrehozását.",
        "authmanager-authplugin-setpass-denied": "A hitelesítés beépülője nem teszi lehetővé a jelszó megváltoztatását.",
        "authmanager-authplugin-setpass-bad-domain": "Érvénytelen domain.",
-       "authmanager-autocreate-noperm": "Automatikus fiók létrehozása nem engedélyezett.",
-       "authmanager-autocreate-exception": "Automatikus fiók létrehozása átmenetileg le van tiltva a korábbi hibák miatt.",
-       "authmanager-userdoesnotexist": "\"$1\" felhasználói fiók nincs regisztrálva.",
+       "authmanager-autocreate-noperm": "Az automatikus fióklétrehozás nem engedélyezett.",
+       "authmanager-autocreate-exception": "A fiókok automatikus létrehozását átmenetileg letiltottuk a korábbi hibák miatt.",
+       "authmanager-userdoesnotexist": "A(z) „$1” felhasználó nincs regisztrálva.",
        "authmanager-retype-help": "Jelszó még egyszer a megerősítéshez.",
        "authmanager-email-label": "E-mail",
-       "authmanager-email-help": "E-mail cím",
+       "authmanager-email-help": "E-mail-cím",
        "authmanager-realname-label": "Valódi név",
        "authmanager-realname-help": "A felhasználó valódi neve",
        "authmanager-provider-password": "Jelszó alapú hitelesítés",
index b807488..184f0cb 100644 (file)
        "rollbacklinkcount-morethan": "rollback di più di {{PLURAL:$1|una modifica|$1 modifiche}}",
        "rollbackfailed": "Rollback fallito",
        "rollback-missingparam": "Parametri obbligatori mancanti nella richiesta.",
+       "rollback-missingrevision": "Impossibile caricare i dati della versione.",
        "cantrollback": "Impossibile annullare le modifiche; l'utente che le ha effettuate è l'unico ad aver contribuito alla pagina.",
        "alreadyrolled": "Non è possibile annullare le modifiche apportate alla pagina [[:$1]] da parte di [[User:$2|$2]] ([[User talk:$2|discussione]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); un altro utente ha già modificato la pagina oppure ha effettuato il rollback.\n\nLa modifica più recente alla pagina è stata apportata da [[User:$3|$3]] ([[User talk:$3|discussione]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "L'oggetto della modifica era: <em>$1</em>.",
index 52b1e42..3aabbe6 100644 (file)
        "userjsyoucanpreview": "'''Tips:''' Gunakna tombol \"{{int:showpreview}}\" kanggo ngetès JavaScript anyar panjenengan sadurungé disimpen.",
        "usercsspreview": "'''Pèngeten yèn panjenengan namung mirsani pratilik CSS panjenengan.''''\n'''Pratilik iku durung kasimpen!'''",
        "userjspreview": "'''Pèngeten yèn sing panjenengan pirsani namung pratilik JavaScript panjenengan, lan menawa pratilik iku dèrèng kasimpen!'''",
-       "sitecsspreview": "'''Èling yèn Sampéyan mung ndelok pratayang CSS iki.'''\n'''Iki durung disimpen!'''",
-       "sitejspreview": "'''Èling yèn Sampéyan mung ndelok pratayang kodhé JavaScript iki.'''\n'''Iki durung disimpen!'''",
+       "sitecsspreview": "<strong>Élinga yèn Sampéyan mung mratuduh CSS iki.\nIki durung kasimpen!</strong>",
+       "sitejspreview": "<strong>Élinga yèn Sampéyan mung mratuduh kodhé JavaScript iki.\nIki durung kasimpen!</strong>",
        "userinvalidcssjstitle": "'''Pènget:''' Kulit \"$1\" ora ditemokaké. Muga dipèngeti yèn kaca .css lan .js nggunakaké huruf cilik, conto {{ns:user}}:Foo/vector.css lan dudu {{ns:user}}:Foo/Vector.css.",
        "updated": "(Kaanyaran)",
        "note": "<strong>Cathetan:</strong>",
-       "previewnote": "'''Èling yèn Sampéyan mung ndelok pratayang.'''\nOwahan Sampéyan durung kasimpen!",
+       "previewnote": "<strong>Élinga yèn iki mung pratuduh.</strong>\nOwahanmu durung kasimpen!",
        "continue-editing": "Menyang pambesutan",
        "previewconflict": "Pratilik iki nuduhaké tèks ing bagian dhuwur kothak suntingan tèks kayadéné bakal katon yèn panjenengan bakal simpen.",
        "session_fail_preview": "'''Nuwun sèwu, suntingan panjenengan ora bisa diolah amarga dhata sèsi kabusak.\nCoba kirim dhata manèh. Yèn tetep ora bisa, coba log metua lan mlebu log manèh.''''''Amerga wiki iki marengaké panggunan kodhe HTML mentah, mula pratilik didhelikaké minangka pancegahan marang serangan JavaScript.'''\n'''Menawa iki sawijining usaha panyuntingan sing sah, mangga dicoba manèh.\nYèn isih tetep ora kasil, cobanen metu log lan mlebu manèh.'''",
        "rev-delundel": "Owah kasatmatan",
        "rev-showdeleted": "tuduhaké",
        "revisiondelete": "Busak/batal busak revisi",
-       "revdelete-nooldid-title": "Target revisi ora ditemokaké",
+       "revdelete-nooldid-title": "Rèvisi tujuan ora sah",
        "revdelete-nooldid-text": "Panjenengan durung mènèhi target revisi kanggo nglakoni fungsi iki.",
        "revdelete-no-file": "Berkas sing dituju ora ana.",
        "revdelete-show-file-confirm": "Apa panjenengan yakin arep mirsani révisi sing wis kabusak saka berkas \"<nowiki>$1</nowiki>\" ing $2, jam $3?",
        "mergehistory-fail": "Ora bisa nggabung sajarah, coba dipriksa manèh kacané lan paramèter wektuné.",
        "mergehistory-no-source": "Kaca sumber $1 ora ana.",
        "mergehistory-no-destination": "Kaca paran $1 ora ana.",
-       "mergehistory-invalid-source": "Irah-irahan kaca sumber kudu irah-irahan utawa judhul sing bener.",
-       "mergehistory-invalid-destination": "Irah-irahan kaca tujuan kudu irah-irahan utawa judhul sing bener.",
+       "mergehistory-invalid-source": "Kaca sumber kudu asesirah sing sah.",
+       "mergehistory-invalid-destination": "Kaca tujuan kudu asesirah sing sah.",
        "mergehistory-autocomment": "Nggabung [[:$1]] menyang [[:$2]]",
        "mergehistory-comment": "Nggabung [[:$1]] menyang [[:$2]]: $3",
        "mergehistory-same-destination": "Jeneng kaca sumber lan tujuan ora kena padha",
        "difference-missing-revision": "{{PLURAL:$2|Sak pambenahan|$2 pambenahan}} saka prabédan iki ($1) {{PLURAL:$2|ora ditemokaké|ora ditemokaké}}.\n\nIki biasané kasebab pranala prabedan sing wis ora kanggo saka kaca isi wis dibusak.\nRinciané bisa ditemokaké nèng [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log busak].",
        "searchresults": "Kasiling golèk",
        "searchresults-title": "Kasiling golèk \"$1\"",
-       "titlematches": "Irah-irahan artikel sing cocog",
+       "titlematches": "Sesirah kaca cocog",
        "textmatches": "Tèks artikel sing cocog",
        "notextmatches": "Ora ana tèks kaca sing cocog",
        "prevn": "{{PLURAL:$1|$1}} sadurungé",
        "prefs-timeoffset": "Format wektu",
        "prefs-advancedediting": "Pilihan sabanjuré",
        "prefs-editor": "Wong besut",
-       "prefs-preview": "Pratayang",
+       "prefs-preview": "Pratuduh",
        "prefs-advancedrc": "Opsi lanjutan",
        "prefs-advancedrendering": "Opsi lanjutan",
        "prefs-advancedsearchoptions": "Opsi lanjutan",
        "license": "Jenis lisènsi:",
        "license-header": "Pamalilah",
        "nolicense": "Durung ana sing dipilih",
-       "license-nopreview": "(Pratayang ora sumedya)",
+       "license-nopreview": "(Pratuduh ora sumadhiya)",
        "upload_source_url": " (sawijining URL absah sing bisa diaksès publik)",
        "upload_source_file": " (sawijining berkas ing komputeré panjenengan)",
        "listfiles-summary": "Kaca mirunggan iki nuduhaké kabèh barkas sing kaunggah.",
        "protectedpages-page": "Kaca",
        "protectedpages-expiry": "Kadaluwarsa",
        "protectedpages-reason": "Alesan",
-       "protectedtitles": "Irah-irahan sing direksa",
+       "protectedtitles": "Sesirah direksa",
        "protectedtitlesempty": "Ora ana irah-irahan utawa judhul sing direksa karo paramèter-paramèter iki.",
        "listusers": "Daftar panganggo",
        "listusers-editsonly": "Tampilaké mung panganggo sing nduwèni kontribusi",
        "nopagetitle": "Kaca tujuan ora ditemokaké",
        "nopagetext": "Kaca sing panjenengan tuju ora ditemokaké.",
        "pager-newer-n": "{{PLURAL:$1|1 luwih anyar|$1 luwih anyar}}",
-       "pager-older-n": "{{PLURAL:$1|1 sing luwih lawas|$1 sing luwih lawas}}",
+       "pager-older-n": "{{PLURAL:$1|1 luwih lawas|$1 luwih lawas}}",
        "suppress": "Dhelikaké",
        "querypage-disabled": "Kaca kusus iki dipatèni kanggo alesan kinerja.",
        "apisandbox": "Kothak wedhi API",
        "all-logs-page": "Kabèh log publik",
        "alllogstext": "Gabungan tampilam kabèh log sing ana ing {{SITENAME}}.\nPanjenengan bisa mbatesi tampilan kanthi milih jinis log, jeneng panganggo (sènsitif aksara gedhé/cilik), utawa kaca sing magepokan (uga sènsitif aksara gedhé/cilik).",
        "logempty": "Ora ditemokaké èntri log sing pas.",
-       "log-title-wildcard": "Golèk irah-irahan utawa judhul sing diawali mawa tèks kasebut",
+       "log-title-wildcard": "Golèk sesirah sing diwiwiti tulisan iki",
        "showhideselectedlogentries": "Tuduhalé/dhelikaké èntri log kapilih",
        "allpages": "Kabèh kaca",
        "nextpage": "Kaca sabanjuré ($1)",
        "linksearch-error": "''Wildcards'' namung bisa dienggo ing bagéyan awal saka jeneng host.",
        "listusersfrom": "Tuduhna panganggo sing diawali karo:",
        "listusers-submit": "Tuduhna",
-       "listusers-noresult": "Panganggo ora ditemokaké.",
+       "listusers-noresult": "Naraguna ora ana.",
        "listusers-blocked": "(diblokir)",
        "activeusers": "Dhaptar panganggo aktif",
        "activeusers-intro": "Iki daptar panganggo sing katon lakuné ing $1 {{PLURAL:$1|dina|dina}} kapungkur.",
        "activeusers-from": "Tampilna panganggo wiwit saka:",
        "activeusers-hidebots": "Delikna bot",
        "activeusers-hidesysops": "Delikna pangurus",
-       "activeusers-noresult": "Panganggo ora ditemokaké.",
+       "activeusers-noresult": "Naraguna ora ana.",
        "listgrouprights": "Hak-hak grup panganggo",
        "listgrouprights-summary": "Ing ngisor iki kapacak dhaftar grup panganggo sing didéfinisi ing wiki iki, kanthi hak-hak aksès gandhèngané.\nInformasi tambahan perkara hak-hak individual bisa ditemokaké ing [[{{MediaWiki:Listgrouprights-helppage}}|kéné]].",
        "listgrouprights-key": "* <span class=\"listgrouprights-granted\">Hak sing diidinaké</span>\n* <span class=\"listgrouprights-revoked\">Hak sing dijabel</span>",
        "imagetypemismatch": "Èkstènsi anyar berkas ora cocog karo jenisé",
        "imageinvalidfilename": "Jeneng berkas tujuan ora sah",
        "fix-double-redirects": "Dandani kabèh pangalihan gandha sing tumuju marang irah-irahan asli",
-       "move-leave-redirect": "Gawé pangalihan menyang irah-irahan anyar",
+       "move-leave-redirect": "Ungkur kaca alihan",
        "protectedpagemovewarning": "'''Pènget:''' Kaca iki wis dikunci dadi mung panganggo sing nduwé hak aksès pangurus baé sing bisa mindhahaké.\nCathetan entri pungkasan disadiakaké ing ngisor kanggo referensi:",
        "semiprotectedpagemovewarning": "'''Cathetan:''' Kaca iki wis direksa saéngga mung panganggo kadhaptar sing bisa mindhahaké.\nEntri cathetan pungkasan disadiakake ing ngisor kanggo referensi:",
        "move-over-sharedrepo": "[[:$1]] ana ing panyimpenan barengan. Ngalih barkas mawa sesirah iki bakal ngamblegi barkas barengan iku.",
        "allmessages-language": "Basa:",
        "allmessages-filter-submit": "Tumuju menyang",
        "thumbnail-more": "Gedhèkaké",
-       "filemissing": "Berkas ora ditemokaké",
+       "filemissing": "Barkas ilang",
        "thumbnail_error": "Kaluputan nalika nggawé gambar cilik (''thumbnail''): $1",
        "thumbnail_error_remote": "Peringatan kasalahan saka $1:\n$2",
        "djvu_page_error": "Kaca DjVu ana ing sajabaning ranggèhan (''range'')",
        "tooltip-recreate": "Gawéa kaca iki manèh senadyan tau dibusak",
        "tooltip-upload": "Miwiti pangunggahan",
        "tooltip-rollback": "Balèkaké besutan-besutan kaca iki déning sing pungkasan nyumbang sarana saklikan.",
-       "tooltip-undo": "Mbalèkaké révisi iki lan mbukak kothak panyuntingan jroning mode pratayang. Wènèhi kasempatan kanggo ngisi alesan ing kothak ringkesan.",
+       "tooltip-undo": "\"Wurungaké\" mbalèkaké besutan iki lan mbukak blangko besutan sarana modhe pratuduh. Alesan kena diwuwuhaké ing babagan ringkesan.",
        "tooltip-preferences-save": "Simpen préperensi",
        "tooltip-summary": "Isi tingkesan cendhak",
        "anonymous": "{{PLURAL:$1|Panganggo|panganggo}} anon ing {{SITENAME}}.",
        "table_pager_limit": "Tuduhna $1 entri per kaca",
        "table_pager_limit_label": "Barang per kaca:",
        "table_pager_limit_submit": "Golèk",
-       "table_pager_empty": "Ora ditemokaké",
+       "table_pager_empty": "Ora ana",
        "autosumm-blank": "Ngothongaké kaca",
        "autosumm-replace": "←Ngganti kaca karo '$1'",
        "autoredircomment": "←Ngalihaké menyang [[$1]]",
        "watchlistedit-normal-title": "Besut pawawangan",
        "watchlistedit-normal-legend": "Busak sesirah saka pawawangan",
        "watchlistedit-normal-explain": "Irah-irahan utawa judhul ing daftar pangawasan panjenengan kapacak ing ngisor iki.\nKanggo mbusak sawijining irah-irahan, kliken kothak ing pinggiré, lan banjur kliken \"Busak judhul\".\nPanjenengan uga bisa [[Special:EditWatchlist/raw|nyunting daftar mentah]].",
-       "watchlistedit-normal-submit": "Busak irah-irahan",
+       "watchlistedit-normal-submit": "Busak sesirah",
        "watchlistedit-normal-done": "Irah-irahan {{PLURAL:$1|siji|$1}} wis dibusak saka daftar pangawasan panjenengan:",
        "watchlistedit-raw-title": "Besut pawawangan wantahan",
        "watchlistedit-raw-legend": "Besut pawawangan wantahan",
        "watchlistedit-raw-explain": "Irah-irahan ing daftar pangawasan panjenengan kapacak ing ngisor iki, lan bisa diowahi mawa nambahaké utawa mbusak daftar; sairah-irahan saban barisé.\nYèn wis rampung, anyarana kaca daftar pangawasan iki.\nPanjenengan uga bisa [[Special:EditWatchlist|nganggo éditor standar panjenengan]].",
-       "watchlistedit-raw-titles": "Irah-irahan:",
+       "watchlistedit-raw-titles": "Sesirah:",
        "watchlistedit-raw-submit": "Anyari pawawangan",
        "watchlistedit-raw-done": "Pawawanganing sampéyan wis dianyari.",
-       "watchlistedit-raw-added": "{{PLURAL:$1|1 irah-irahan wis|$1 irah-irahan wis}} ditambahaké:",
-       "watchlistedit-raw-removed": "{{PLURAL:$1|1 irah-irahan wis|$1 irah-irahan wis}} diwetokaké:",
+       "watchlistedit-raw-added": "{{PLURAL:$1|1 sesirah|$1 sesirah}} ditambahaké:",
+       "watchlistedit-raw-removed": "{{PLURAL:$1|1 sesirah|$1 sesirah}} dibusak:",
        "watchlisttools-view": "Tuduhna owah-owahan sing ana gandhèngané",
        "watchlisttools-edit": "Deleng lan besut pawawangan",
        "watchlisttools-raw": "Besut pawawangan wantahan",
        "feedback-bugornote": "Yèn Sampéyan siap njelasaké masalah tèhnis kanthi rinci mangga [$1 laporaké bug].\nUtawa, Sampéyan bisa nganggo pormulir gampang ngisor. Tanggepan Sampéyan bakal ditambahaké nèng kaca \"[$3 $2]\", bebarengan karo jeneng panganggo Sampéyan lan pramban sing Sampéyan anggo.",
        "feedback-cancel": "Batal",
        "feedback-close": "Rampung",
+       "feedback-error-title": "Cacad",
        "feedback-error1": "Kasalahan: Asil ora dikenal saka API",
        "feedback-error2": "Cacad: Gagal mbesut",
        "feedback-error3": "Kasalahan: Ora ana tanggepan saka API",
        "limitreport-expensivefunctioncount": "Expensive parser function count",
        "expandtemplates": "Cithakan dikembangaké",
        "expand_templates_intro": "Kaca astaméwa iki njupuk sawetara tèks lan ngembangaké kabèh cithakan sajroning iku sacara rékursif.\nKaca iki uga ngembangaké fungsi parser kaya ta\n<nowiki>{{</nowiki>#language:…}}, lan variabel kaya ta\n<nowiki>{{</nowiki>CURRENTDAY}}&mdash;sajatiné mèh kabèh sing ana ing antara rong tandha kurung akolade.",
-       "expand_templates_title": "Irah-irahan kontèks, kanggo {{FULLPAGENAME}} lan sabanjuré:",
+       "expand_templates_title": "Sesirah kontèks, kanggo {{FULLPAGENAME}}, lsp.:",
        "expand_templates_input": "Tèks sumber:",
        "expand_templates_output": "Pituwas (kasil)",
        "expand_templates_xml_output": "Pituwas XML",
        "expand_templates_remove_nowiki": "Brèdèl tag <nowiki> nèng asilé",
        "expand_templates_generate_xml": "Tuduhna uwit parser XML",
        "expand_templates_generate_rawhtml": "Show raw HTML",
-       "expand_templates_preview": "Pratayang",
+       "expand_templates_preview": "Pratuduh",
        "special-characters-group-latin": "Latin",
        "special-characters-group-latinextended": "Latin pepak",
        "special-characters-group-ipa": "IPA",
index e892af8..510249a 100644 (file)
        "rollbacklinkcount-morethan": "méi wéi {{PLURAL:$1|Eng Ännerung|$1 Ännerungen}} zrécksetzen",
        "rollbackfailed": "Zrécksetzen huet net geklappt",
        "rollback-missingparam": "An der Ufro feelen obligatoresch Parameteren.",
+       "rollback-missingrevision": "D'Donnéeë vun der Versioun konnten net geluede ginn.",
        "cantrollback": "Lescht Ännerung kann net zréckgesat ginn. De leschten Auteur ass deen eenzegen Auteur vun dëser Säit.",
        "alreadyrolled": "Déi lescht Ännerung vun der Säit [[:$1]] vum [[User:$2|$2]] ([[User talk:$2|talk]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); kann net zréckgesat ginn;\neen Aneren huet dat entweder scho gemaach oder nei Ännerungen agedroen.\n\nDéi lescht Ännerung vun der Säit war vum [[User:$3|$3]] ([[User talk:$3|Diskussioun]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "De Resumé vun der Ännerung war: <em>$1</em>.",
        "anoncontribs": "Kontributiounen",
        "contribsub2": "Fir {{GENDER:$3|den $1|d'$1|de Benotzer $1}} ($2)",
        "contributions-userdoesnotexist": "De Benotzerkont \"$1\" ass net registréiert.",
-       "nocontribs": "Et goufe keng Ännerunge fonnt, déi dëse Kritèren entspriechen.",
+       "nocontribs": "Et goufe keng Ännerunge fonnt, déi dëse Critèren entspriechen.",
        "uctop": "(aktuell)",
        "month": "Vum Mount (a virdrun):",
        "year": "Vum Joer (a virdrun):",
index e02a91c..595fdf5 100644 (file)
        "sqlite-no-fts": "$1 बिन पूर्ण-पाठ खोज सहायताक",
        "logentry-delete-delete": "$1 पृष्ठ $3 {{GENDER:$2|मेटौलक}}",
        "logentry-delete-restore": "$1 {{GENDER:$2|restored}} page $3",
-       "logentry-delete-event": "$1 {{लिंग:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 केँ",
-       "logentry-delete-revision": "$1 {{लिंग:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  पन्ना $3: $4 पर",
+       "logentry-delete-event": "$1 {{GENDER:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 केँ",
+       "logentry-delete-revision": "$1 {{GENDER:$2|परिवर्तन कियल गैल}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  पन्ना $3: $4 पर",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|changed}}  $3 पर वृत्तलेख दृश्य",
        "logentry-delete-revision-legacy": "$1 {{GENDER:$2|changed}}  $3 पर वृत्तलेख संशोधन",
-       "logentry-suppress-delete": "$1 {{लिंग:$2|दबाएल}} page $3",
-       "logentry-suppress-event": "$1 चोरिसँ {{लिंग:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 पर",
-       "logentry-suppress-revision": "$1 चोरिसँ {{लिंग:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  $3: $4 पर",
+       "logentry-suppress-delete": "$1 {{GENDER:$2|दबाएल}} page $3",
+       "logentry-suppress-event": "$1 चोरिसँ {{GENDER:$2|परिवर्तन कियल गैल}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 पर",
+       "logentry-suppress-revision": "$1 चोरिसँ {{GENDER:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  $3: $4 पर",
        "logentry-suppress-event-legacy": "$1 नुका क {{GENDER:$2|परिवर्तन}}  $3 पर वृत्तलेख दृश्य",
        "logentry-suppress-revision-legacy": "$1 नुका कऽ {{GENDER:$2|changed}}  $3 पर संशोधन दृश्य",
        "revdelete-content-hid": "सामिग्री नुकाएल",
        "logentry-move-move": "$1 हटाएल पन्ना $3 सँ $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआकेँ बिना छोड़ने",
        "logentry-move-move_redir": "$1 {{GENDER:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतिरिक्त",
-       "logentry-move-move_redir-noredirect": "$1 {{लिंग:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतितिक्त घुमौआकेँ बिना छोड़ने",
+       "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|हटाएल}} पन्ना $3 सँ $4 घुमौआक अतितिक्त घुमौआकेँ बिना छोड़ने",
        "logentry-patrol-patrol": "$1 {{GENDER:$2|चिन्हित}} संशोधन $4 $3 पन्नाक निरीक्षित",
        "logentry-patrol-patrol-auto": "$1 स्वतः {{GENDER:$2|चिन्हित}} संशोधन $4 $3 पन्नाक निरीक्षित",
        "logentry-newusers-newusers": "$1 {{GENDER:$2|बनाएल}} एकटा प्रयोक्ता खाता",
index 4a97196..cd91aec 100644 (file)
        "ipb-edit-dropdown": "निषेध कारण सम्पादन गर्नुहोस्",
        "ipb-unblock-addr": "$1 निषेध खारेज गर्ने",
        "ipb-unblock": "प्रयोगकर्ता वा IP माथिको निषेध खारेज गर्ने",
-       "ipb-blocklist": "हाल à¤°à¤¹à¥\87à¤\95ा à¤¨à¤¿à¤·à¥\87धहरà¥\81 हेर्नुहोस्",
+       "ipb-blocklist": "हाल à¤°à¤¹à¥\87à¤\95ा à¤¨à¤¿à¤·à¥\87धहरà¥\82 हेर्नुहोस्",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}}को लागि योगदान",
        "unblockip": "प्रयोगकर्ताको निषेध खारेज गर्नुहोस्",
        "unblockiptext": "IP ठेगाना अथवा प्रयोगकर्तामाथि पहिले लगाइएको रोक फुकुवा गर्न तलको प्रपत्र प्रयोग गर्नुहोस्।",
        "revdelete-content-unhid": "सामग्री देखाइएको",
        "revdelete-summary-unhid": "सम्पादन सारांस देखाइएको",
        "revdelete-uname-unhid": "प्रयोगकर्ता देखाइएको",
-       "revdelete-restricted": "पà¥\8dरबनà¥\8dधà¤\95हरà¥\81माथि सीमितता लागू गरियो",
-       "revdelete-unrestricted": "प्रवन्धककोलागि निषेधहरु हटाइयो ।",
+       "revdelete-restricted": "पà¥\8dरबनà¥\8dधà¤\95हरà¥\82 माथि सीमितता लागू गरियो",
+       "revdelete-unrestricted": "प्रवन्धकको लागि निषेधहरू हटाइयो ।",
        "logentry-block-block": "$1 {{GENDER:$2|प्रतिबन्धित}}{{GENDER:$4|$3}} जसमा समय समाप्तिको अवधि छ $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|खुल्ला गरिएो}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|परिवर्तन गर्यो}} प्रतिबन्ध सेटिङ्ग {{GENDER:$4|$3}} को लागि जसमा समय समाप्तिको अवधि छ $5 $6",
        "logentry-move-move": "$1 {{GENDER:$2|द्वारा}} $3 पृष्ठलाई $4 मा सारियो",
        "logentry-move-move-noredirect": "$1 ले $3 मा पुनर्निर्देश नछोडि त्यसलाई $4 मा {{GENDER:$2|सारेको}} हो",
        "logentry-move-move_redir": "$1 ले $4 बाट पुनर्निर्देश हटाएर $3 लाई त्यसमाथि {{GENDER:$2|सारेको}} हो",
-       "logentry-move-move_redir-noredirect": "$1 à¤²à¥\87 $4 à¤¬à¤¾à¤\9f à¤ªà¥\81नारà¥\8dनिरà¥\8dदà¥\87श à¤¹à¤\9fाà¤\8fर $3 à¤®à¤¾ à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87श à¤¨à¥\8dनाà¤\9bà¥\8bडि $3 लाई $4 मा {{GENDER:$2|सारेको}} हो",
+       "logentry-move-move_redir-noredirect": "$1 à¤²à¥\87 $4 à¤¬à¤¾à¤\9f à¤ªà¥\81नारà¥\8dनिरà¥\8dदà¥\87श à¤¹à¤\9fाà¤\8fर $3 à¤®à¤¾ à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87श à¤¨à¤\9bà¥\8bडà¥\80 $3 लाई $4 मा {{GENDER:$2|सारेको}} हो",
        "logentry-patrol-patrol": "$1 ले $3 पृष्ठको $4 अवतरणलाई गस्ती गरिएको {{GENDER:$2|चिन्हित}} गरेको हो",
        "logentry-patrol-patrol-auto": "$1 ले $3 पृष्ठको $4 अवतरणलाई स्वचालित रूपले गस्ती गरिएको {{GENDER:$2|चिन्हित}} गरेको हो",
        "logentry-newusers-newusers": "प्रयोगकर्ता खाता $1 {{GENDER:$2|खोलियो}}",
index f27f48e..810c6c5 100644 (file)
        "rollbacklinkcount-morethan": "откатить больше, чем $1 {{PLURAL:$1|правку|правки|правок}}",
        "rollbackfailed": "Ошибка при совершении отката",
        "rollback-missingparam": "Отсутствуют обязательные параметры по запросу.",
+       "rollback-missingrevision": "Не удалось загрузить данные версии.",
        "cantrollback": "Невозможно откатить изменения. Последним, кто вносил изменения, был единственный автор этой страницы.",
        "alreadyrolled": "Невозможно откатить последние изменения страницы «[[:$1]]», совершённые [[User:$2|$2]] ([[User talk:$2|обсуждение]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]),\nпоскольку кто-то другой уже успел откатить эти правки или отредактировать страницу.\n\nПоследние изменения {{GENDER:$3|внёс|внесла}} [[User:$3|$3]] ([[User talk:$3|обсуждение]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Было дано описание изменения: <em>$1</em>.",
        "linkaccounts-submit": "Связать учётные записи",
        "unlinkaccounts": "Отвязать учётные записи",
        "unlinkaccounts-success": "Учетная запись была отвязан.",
-       "authenticationdatachange-ignored": "Изменение данных для проверки подлинности не было обработано. Может быть, не был настроен ни один провайдер?"
+       "authenticationdatachange-ignored": "Изменение данных для проверки подлинности не было обработано. Может быть, не был настроен ни один провайдер?",
+       "userjsispublic": "Обратите внимание: подстраницы JavaScript не должны содержать конфиденциальные сведения, поскольку они доступны для просмотра другим участникам.",
+       "usercssispublic": "Обратите внимание: подстраницы CSS не должны содержать конфиденциальные сведения, поскольку они доступны для просмотра другим участникам."
 }
index 33c3522..c23dca5 100644 (file)
        "rollbacklinkcount-morethan": "rulla tillbaka mer än $1 {{PLURAL:$1|redigering|redigeringar}}",
        "rollbackfailed": "Tillbakarullning misslyckades",
        "rollback-missingparam": "Nödvändiga parametrar i begäran saknas.",
+       "rollback-missingrevision": "Kunde inte läsa in sidversionsdata.",
        "cantrollback": "Det gick inte att rulla tillbaka, då sidan endast redigerats av en användare.",
        "alreadyrolled": "Det gick inte att rulla tillbaka den senaste redigeringen av [[User:$2|$2]] ([[User talk:$2|diskussion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) på sidan [[:$1|$1]]. Någon annan har redan rullat tillbaka eller redigerat sidan.\n\nSidan ändrades senast av [[User:$3|$3]] ([[User talk:$3|diskussion]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]).",
        "editcomment": "Redigeringskommentaren var: <em>$1</em>.",
        "whatlinkshere": "Vad som länkar hit",
        "whatlinkshere-title": "Sidor som länkar till \"$1\"",
        "whatlinkshere-page": "Sida:",
-       "linkshere": "Följande sidor länkar till '''[[:$1]]''':",
+       "linkshere": "Följande sidor länkar till <strong>[[:$1]]</strong>:",
        "nolinkshere": "Inga sidor länkar till '''[[:$1]]'''.",
        "nolinkshere-ns": "Inga sidor i den angivna namnrymden länkar till '''[[:$1]]'''.",
        "isredirect": "omdirigeringssida",
index 4377326..7f2f2ea 100644 (file)
        "log-title-wildcard": "ఈ పాఠ్యంతో మొదలయ్యే పుస్తకాల కొరకు వెతుకు",
        "showhideselectedlogentries": "ఎంచుకున్న చిట్టా పద్దులను చూపించు/దాచు",
        "log-edit-tags": "ఎంచుకున్న చిట్టా ప్రవేశాల ట్యాగులను సవరించు",
+       "checkbox-all": "అన్నీ",
+       "checkbox-none": "దేన్నీ వద్దు",
+       "checkbox-invert": "తిరగవెయ్యి",
        "allpages": "అన్ని పేజీలు",
        "nextpage": "తరువాతి పేజీ ($1)",
        "prevpage": "మునుపటి పేజీ ($1)",
        "activeusers-hidebots": "బాట్లను దాచు",
        "activeusers-hidesysops": "నిర్వాహకులను దాచు",
        "activeusers-noresult": "వాడుకరులెవరూ లేరు.",
+       "activeusers-submit": "చేతనంగా ఉన్న వాడుకరులను చూపించు",
        "listgrouprights": "వాడుకరి గుంపుల హక్కులు",
        "listgrouprights-summary": "కింది జాబితాలో ఈ వికీలో నిర్వచించిన వాడుకరి గుంపులు, వాటికి సంబంధించిన హక్కులు ఉన్నాయి.\nవిడివిడిగా హక్కులకు సంబంధించిన మరింత సమాచారం [[{{MediaWiki:Listgrouprights-helppage}}]] వద్ద లభించవచ్చు.",
        "listgrouprights-key": "సూచిక:\n* <span class=\"listgrouprights-granted\">ప్రసాదించిన హక్కు</span>\n* <span class=\"listgrouprights-revoked\">వెనక్కి తీసుకున్న హక్కు</span>",
        "listgrouprights-namespaceprotection-header": "పేరుబరి నిబంధనలు",
        "listgrouprights-namespaceprotection-namespace": "పేరుబరి",
        "listgrouprights-namespaceprotection-restrictedto": "వాడుకరి మార్పు చేయుటకు హక్కు(లు)",
+       "listgrants": "గ్రాంట్లు",
+       "listgrants-grant": "గ్రాంటు",
+       "listgrants-rights": "హక్కులు",
        "trackingcategories": "పహారా కాయు వర్గాలు",
        "trackingcategories-msg": "పహారా కార్యు వర్గము",
        "trackingcategories-name": "సందేశం పేరు",
        "movepagetext-noredirectfixer": "కింది ఫారాన్ని వాడి, ఓ పేజీ పేరు మార్చవచ్చు. దాని చరిత్ర పూర్తిగా కొత్త పేరుకు తరలిపోతుంది. \nపాత శీర్షిక కొత్తదానికి దారిమార్పు పేజీగా మారిపోతుంది.\n[[Special:DoubleRedirects|double]] లేదా [[Special:BrokenRedirects|broken redirects]] లను చూడటం మరువకండి.\nలింకులు వెళ్ళాల్సిన చోటికి వెళ్తున్నాయని నిర్ధారించుకోవాల్సిన బాధ్యత మీదే.\nకొత్త పేరుతో ఈసరికే ఏదైనా పేజీ ఉంటే - అది ఖాళీగా ఉన్నా లేక మార్పుచేర్పుల చరిత్ర ఏమీ లేని దారిమార్పు పేజీ అయినా తప్ప- తరలింపు ’’’జరుగదు’’’ అని గమనించండి.\nఅంటే, ఏదైనా పొరపాటు జరిగితే పేరును తిరిగి పాత పేరుకే మార్చగలరు తప్ప, ఈపాటికే ఉన్న పేజీపై ఓవరరైటు చెయ్యలేరు.\n\n'''హెచ్చరిక!'''\nబహుళ వ్యాప్తి పొందిన ఓ పేజీలో ఈ మార్పు చాలా తీవ్రమైనది, ఊహించనిదీ అవుతుంది.\nదాని పర్యవసానాలు అర్థం చేసుకున్నాకే ముందుకు వెళ్ళండి.",
        "movepagetalktext": "దానితో పాటు సంబంధిత చర్చా పేజీ కూడా ఆటోమాటిక్‌‌గా తరలించబడుతుంది, '''కింది సందర్భాలలో తప్ప:'''\n*ఒక నేంస్పేసు నుండి ఇంకోదానికి తరలించేటపుడు,\n*కొత్త పేరుతో ఇప్పటికే ఒక చర్చా పేజీ ఉంటే,\n*కింది చెక్‌బాక్సులో టిక్కు పెట్టకపోతే.\n\nఆ సందర్భాలలో, మీరు చర్చా పేజీని కూడా పనిగట్టుకుని తరలించవలసి ఉంటుంది, లేదా ఏకీకృత పరచవలసి ఉంటుంది.",
        "moveuserpage-warning": "'''హెచ్చరిక:''' మీరు ఒక వాడుకరి పేజీని తరలించబోతున్నారు. పేజీ మాత్రమే తరలించబడుతుందనీ, వాడుకరి పేరుమార్పు జరగదనీ గమనించండి.",
+       "movecategorypage-warning": "<strong>హెచ్చరిక:</strong> మీరు ఓ వర్గం పేజీని తరలించబోతున్నారు. కేవలం పేజీ మాత్రమే తరలుతుందని, పాత వర్గంలో ఉన్న పేజీలేవీ కొత్త వర్గంలోకి <em>చేరవని</em>  గ్రహించండి.",
        "movenologintext": "పేజీని తరలించడానికి మీరు [[Special:UserLogin|లాగిన్‌]] అయిఉండాలి.",
        "movenotallowed": "పేజీలను తరలించడానికి మీకు అనుమతి లేదు.",
        "movenotallowedfile": "మీకు ఫైళ్ళను తరలించే అనుమతి లేదు.",
index 464655a..656ea39 100644 (file)
@@ -25,7 +25,8 @@
                        "Macofe",
                        "Pilarbini",
                        "Matma Rex",
-                       "B20180"
+                       "B20180",
+                       "Pon44695"
                ]
        },
        "tog-underline": "การขีดเส้นใต้ลิงก์:",
        "whatlinkshere-prev": "{{PLURAL:$1|ก่อนหน้า|ก่อนหน้า $1}}",
        "whatlinkshere-next": "{{PLURAL:$1|ถัดไป|ถัดไป $1}}",
        "whatlinkshere-links": "← ลิงก์",
-       "whatlinkshere-hideredirs": "$1การเปลี่ยนทาง",
+       "whatlinkshere-hideredirs": "$1 การเปลี่ยนทาง",
        "whatlinkshere-hidetrans": "$1 ถูกรวมอยู่",
        "whatlinkshere-hidelinks": "$1 ลิงก์",
        "whatlinkshere-hideimages": "$1ลิงก์ไฟล์",
index 66e7a0e..2c5bf98 100644 (file)
        "print": "Yazdır",
        "view": "Görüntüle",
        "view-foreign": "$1 üzerinde gör",
-       "edit": "Düzenle",
+       "edit": "Değiştir",
        "edit-local": "Yerel açıklamayı düzenle",
        "create": "Oluştur",
        "create-local": "Yerel açıklama ekle",
index 922cc87..930f533 100644 (file)
@@ -101,7 +101,7 @@ TEXT
                        'STRAIGHT_JOIN' // per T58041
                ];
 
-               if ( $force || $dryRun ) {
+               if ( $force ) {
                        $collationConds = [];
                } else {
                        if ( $this->hasOption( 'previous-collation' ) ) {
@@ -132,7 +132,11 @@ TEXT
 
                                return;
                        }
-                       $this->output( "Fixing collation for $count rows.\n" );
+                       if ( $dryRun ) {
+                               $this->output( "$count rows would be updated.\n" );
+                       } else {
+                               $this->output( "Fixing collation for $count rows.\n" );
+                       }
                        wfWaitForSlaves();
                }
                $count = 0;
index 3d90307..5c3715d 100644 (file)
 
                capsuleWidget: {
                        getApiValue: function () {
-                               return this.getItemsData().join( '|' );
+                               var items = this.getItemsData();
+                               if ( items.join( '' ).indexOf( '|' ) === -1 ) {
+                                       return items.join( '|' );
+                               } else {
+                                       return '\x1f' + items.join( '\x1f' );
+                               }
                        },
                        setApiValue: function ( v ) {
-                               this.setItemsFromData( v === undefined || v === '' ? [] : String( v ).split( '|' ) );
+                               if ( v === undefined || v === '' || v === '\x1f' ) {
+                                       this.setItemsFromData( [] );
+                               } else {
+                                       v = String( v );
+                                       if ( v.indexOf( '\x1f' ) !== 0 ) {
+                                               this.setItemsFromData( v.split( '|' ) );
+                                       } else {
+                                               this.setItemsFromData( v.substr( 1 ).split( '\x1f' ) );
+                                       }
+                               }
                        },
                        apiCheckValid: function () {
                                var ok = this.getApiValue() !== undefined || suppressErrors;
index 946823d..4d86cfd 100644 (file)
                        prop: [ 'info' ],
                        titles: titles
                } ).done( function ( response ) {
+                       var
+                               normalized = {},
+                               pages = {};
+                       $.each( response.query.normalized || [], function ( index, data ) {
+                               normalized[ data.fromencoded ? decodeURIComponent( data.from ) : data.from ] = data.to;
+                       } );
                        $.each( response.query.pages, function ( index, page ) {
-                               var title = new ForeignTitle( page.title ).getPrefixedText();
-                               cache.existenceCache[ title ] = !page.missing;
-                               if ( !queue[ title ] ) {
-                                       // Debugging for T139130
-                                       throw new Error( 'No queue for "' + title + '", requested "' + titles.join( '|' ) + '"' );
+                               pages[ page.title ] = !page.missing;
+                       } );
+                       $.each( titles, function ( index, title ) {
+                               var normalizedTitle = title;
+                               while ( normalized[ normalizedTitle ] ) {
+                                       normalizedTitle = normalized[ normalizedTitle ];
                                }
+                               cache.existenceCache[ title ] = pages[ normalizedTitle ];
                                queue[ title ].resolve( cache.existenceCache[ title ] );
                        } );
                } );
index a8ee4c7..b7579ff 100644 (file)
@@ -9,6 +9,9 @@
         *     `options` to mw.Api constructor.
         * @property {Object} defaultOptions.parameters Default query parameters for API requests.
         * @property {Object} defaultOptions.ajax Default options for jQuery#ajax.
+        * @property {boolean} defaultOptions.useUS Whether to use U+001F when joining multi-valued
+        *     parameters (since 1.28). Default is true if ajax.url is not set, false otherwise for
+        *     compatibility.
         * @private
         */
        var defaultOptions = {
@@ -95,6 +98,8 @@
                        options.ajax.url = String( options.ajax.url );
                }
 
+               options = $.extend( { useUS: !options.ajax || !options.ajax.url }, options );
+
                options.parameters = $.extend( {}, defaultOptions.parameters, options.parameters );
                options.ajax = $.extend( {}, defaultOptions.ajax, options.ajax );
 
                 *
                 * @private
                 * @param {Object} parameters (modified in-place)
+                * @param {boolean} useUS Whether to use U+001F when joining multi-valued parameters.
                 */
-               preprocessParameters: function ( parameters ) {
+               preprocessParameters: function ( parameters, useUS ) {
                        var key;
                        // Handle common MediaWiki API idioms for passing parameters
                        for ( key in parameters ) {
                                // Multiple values are pipe-separated
                                if ( $.isArray( parameters[ key ] ) ) {
-                                       parameters[ key ] = parameters[ key ].join( '|' );
+                                       if ( !useUS || parameters[ key ].join( '' ).indexOf( '|' ) === -1 ) {
+                                               parameters[ key ] = parameters[ key ].join( '|' );
+                                       } else {
+                                               parameters[ key ] = '\x1f' + parameters[ key ].join( '\x1f' );
+                                       }
                                }
                                // Boolean values are only false when not given at all
                                if ( parameters[ key ] === false || parameters[ key ] === undefined ) {
                                delete parameters.token;
                        }
 
-                       this.preprocessParameters( parameters );
+                       this.preprocessParameters( parameters, this.defaults.useUS );
 
                        // If multipart/form-data has been requested and emulation is possible, emulate it
                        if (
index 9ba562e..077e84d 100644 (file)
@@ -37,7 +37,7 @@
                },
 
                /**
-                * Loads a set of mesages and add them to mw.messages.
+                * Loads a set of messages and add them to mw.messages.
                 *
                 * @param {Array} messages Messages to retrieve
                 * @return {jQuery.Promise}
@@ -47,7 +47,7 @@
                },
 
                /**
-                * Loads a set of mesages and add them to mw.messages. Only messages that are not already known
+                * Loads a set of messages and add them to mw.messages. Only messages that are not already known
                 * are loaded. If all messages are known, the returned promise is resolved immediately.
                 *
                 * @param {Array} messages Messages to retrieve
index 0af2a75..069fbbf 100644 (file)
                                value = options[ name ] === null ? null : String( options[ name ] );
 
                                // Can we bundle this option, or does it need a separate request?
-                               bundleable =
-                                       ( value === null || value.indexOf( '|' ) === -1 ) &&
-                                       ( name.indexOf( '|' ) === -1 && name.indexOf( '=' ) === -1 );
+                               if ( this.defaults.useUS ) {
+                                       bundleable = name.indexOf( '=' ) === -1;
+                               } else {
+                                       bundleable =
+                                               ( value === null || value.indexOf( '|' ) === -1 ) &&
+                                               ( name.indexOf( '|' ) === -1 && name.indexOf( '=' ) === -1 );
+                               }
 
                                if ( bundleable ) {
                                        if ( value !== null ) {
index 5d1ead0..8b75d56 100644 (file)
@@ -43,4 +43,87 @@ class ApiBaseTest extends ApiTestCase {
                );
        }
 
+       /**
+        * @dataProvider provideGetParameterFromSettings
+        * @param string|null $input
+        * @param array $paramSettings
+        * @param mixed $expected
+        * @param string[] $warnings
+        */
+       public function testGetParameterFromSettings( $input, $paramSettings, $expected, $warnings ) {
+               $mock = new MockApi();
+               $wrapper = TestingAccessWrapper::newFromObject( $mock );
+
+               $context = new DerivativeContext( $mock );
+               $context->setRequest( new FauxRequest( $input !== null ? [ 'foo' => $input ] : [] ) );
+               $wrapper->mMainModule = new ApiMain( $context );
+
+               if ( $expected instanceof UsageException ) {
+                       try {
+                               $wrapper->getParameterFromSettings( 'foo', $paramSettings, true );
+                       } catch ( UsageException $ex ) {
+                               $this->assertEquals( $expected, $ex );
+                       }
+               } else {
+                       $result = $wrapper->getParameterFromSettings( 'foo', $paramSettings, true );
+                       $this->assertSame( $expected, $result );
+                       $this->assertSame( $warnings, $mock->warnings );
+               }
+       }
+
+       public static function provideGetParameterFromSettings() {
+               $warnings = [
+                       'The value passed for \'foo\' contains invalid or non-normalized data. Textual data should ' .
+                       'be valid, NFC-normalized Unicode without C0 control characters other than ' .
+                       'HT (\\t), LF (\\n), and CR (\\r).'
+               ];
+
+               $c0 = '';
+               $enc = '';
+               for ( $i = 0; $i < 32; $i++ ) {
+                       $c0 .= chr( $i );
+                       $enc .= ( $i === 9 || $i === 10 || $i === 13 )
+                               ? chr( $i )
+                               : '�';
+               }
+
+               return [
+                       'Basic param' => [ 'bar', null, 'bar', [] ],
+                       'Basic param, C0 controls' => [ $c0, null, $enc, $warnings ],
+                       'String param' => [ 'bar', '', 'bar', [] ],
+                       'String param, defaulted' => [ null, '', '', [] ],
+                       'String param, empty' => [ '', 'default', '', [] ],
+                       'String param, required, empty' => [
+                               '',
+                               [ ApiBase::PARAM_DFLT => 'default', ApiBase::PARAM_REQUIRED => true ],
+                               new UsageException( 'The foo parameter must be set', 'nofoo' ),
+                               []
+                       ],
+                       'Multi-valued parameter' => [
+                               'a|b|c',
+                               [ ApiBase::PARAM_ISMULTI => true ],
+                               [ 'a', 'b', 'c' ],
+                               []
+                       ],
+                       'Multi-valued parameter, alternative separator' => [
+                               "\x1fa|b\x1fc|d",
+                               [ ApiBase::PARAM_ISMULTI => true ],
+                               [ 'a|b', 'c|d' ],
+                               []
+                       ],
+                       'Multi-valued parameter, other C0 controls' => [
+                               $c0,
+                               [ ApiBase::PARAM_ISMULTI => true ],
+                               [ $enc ],
+                               $warnings
+                       ],
+                       'Multi-valued parameter, other C0 controls (2)' => [
+                               "\x1f" . $c0,
+                               [ ApiBase::PARAM_ISMULTI => true ],
+                               [ substr( $enc, 0, -3 ), '' ],
+                               $warnings
+                       ],
+               ];
+       }
+
 }
index 367210a..ad1deee 100644 (file)
@@ -75,4 +75,25 @@ class ApiPageSetTest extends ApiTestCase {
 
                return [ $target, $pageSet ];
        }
+
+       public function testHandleNormalization() {
+               $context = new RequestContext();
+               $context->setRequest( new FauxRequest( [ 'titles' => "a|B|a\xcc\x8a" ] ) );
+               $main = new ApiMain( $context );
+               $pageSet = new ApiPageSet( $main );
+               $pageSet->execute();
+
+               $this->assertSame(
+                       [ 0 => [ 'A' => -1, 'B' => -2, 'Å' => -3 ] ],
+                       $pageSet->getAllTitlesByNamespace()
+               );
+               $this->assertSame(
+                       [
+                               [ 'fromencoded' => true, 'from' => 'a%CC%8A', 'to' => 'å' ],
+                               [ 'fromencoded' => false, 'from' => 'a', 'to' => 'A' ],
+                               [ 'fromencoded' => false, 'from' => 'å', 'to' => 'Å' ],
+                       ],
+                       $pageSet->getNormalizedTitlesAsResult()
+               );
+       }
 }
index 9a64d08..d7db538 100644 (file)
@@ -1,12 +1,18 @@
 <?php
 
 class MockApi extends ApiBase {
+       public $warnings = [];
+
        public function execute() {
        }
 
        public function __construct() {
        }
 
+       public function setWarning( $warning ) {
+               $this->warnings[] = $warning;
+       }
+
        public function getAllowedParams() {
                return [
                        'filename' => null,
index 504b16a..8cb2327 100644 (file)
@@ -43,6 +43,7 @@ class ApiQueryTest extends ApiTestCase {
 
                $this->assertEquals(
                        [
+                               'fromencoded' => false,
                                'from' => 'Project:articleA',
                                'to' => $to->getPrefixedText(),
                        ],
@@ -51,6 +52,7 @@ class ApiQueryTest extends ApiTestCase {
 
                $this->assertEquals(
                        [
+                               'fromencoded' => false,
                                'from' => 'article_B',
                                'to' => 'Article B'
                        ],
index bc7542a..607f25c 100644 (file)
@@ -31,6 +31,8 @@
 class FakeDatabaseMysqlBase extends DatabaseMysqlBase {
        // From DatabaseBase
        function __construct() {
+               $this->profiler = new ProfilerStub( [] );
+               $this->trxProfiler = new TransactionProfiler();
        }
 
        protected function closeConnection() {
index aa8b8e8..d6ca596 100644 (file)
@@ -27,6 +27,9 @@ class DatabaseTestHelper extends DatabaseBase {
 
        public function __construct( $testName ) {
                $this->testName = $testName;
+
+               $this->profiler = new ProfilerStub( [] );
+               $this->trxProfiler = new TransactionProfiler();
        }
 
        /**
index 90c9f38..0be04ef 100644 (file)
@@ -2,11 +2,11 @@
 
 /**
  * @group ResourceLoader
+ * @covers DerivativeResourceLoaderContext
  */
 class DerivativeResourceLoaderContextTest extends PHPUnit_Framework_TestCase {
 
-       protected static function getResourceLoaderContext() {
-               $resourceLoader = new ResourceLoader();
+       protected static function getContext() {
                $request = new FauxRequest( [
                                'lang' => 'zh',
                                'modules' => 'test.context',
@@ -14,42 +14,76 @@ class DerivativeResourceLoaderContextTest extends PHPUnit_Framework_TestCase {
                                'skin' => 'fallback',
                                'target' => 'test',
                ] );
-               return new ResourceLoaderContext( $resourceLoader, $request );
+               return new ResourceLoaderContext( new ResourceLoader(), $request );
        }
 
-       public function testGet() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+       public function testGetInherited() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
 
+               // Request parameters
+               $this->assertEquals( $derived->getDebug(), false );
                $this->assertEquals( $derived->getLanguage(), 'zh' );
                $this->assertEquals( $derived->getModules(), [ 'test.context' ] );
                $this->assertEquals( $derived->getOnly(), 'scripts' );
                $this->assertEquals( $derived->getSkin(), 'fallback' );
+               $this->assertEquals( $derived->getUser(), null );
+
+               // Misc
+               $this->assertEquals( $derived->getDirection(), 'ltr' );
                $this->assertEquals( $derived->getHash(), 'zh|fallback|||scripts|||||' );
        }
 
-       public function testSetLanguage() {
-               $context = self::getResourceLoaderContext();
+       public function testModules() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setModules( [ 'test.override' ] );
+               $this->assertEquals( $derived->getModules(), [ 'test.override' ] );
+       }
+
+       public function testLanguage() {
+               $context = self::getContext();
                $derived = new DerivativeResourceLoaderContext( $context );
 
                $derived->setLanguage( 'nl' );
                $this->assertEquals( $derived->getLanguage(), 'nl' );
+       }
+
+       public function testDirection() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setLanguage( 'nl' );
+               $this->assertEquals( $derived->getDirection(), 'ltr' );
 
                $derived->setLanguage( 'he' );
                $this->assertEquals( $derived->getDirection(), 'rtl' );
+
+               $derived->setDirection( 'ltr' );
+               $this->assertEquals( $derived->getDirection(), 'ltr' );
        }
 
-       public function testSetModules() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+       public function testSkin() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
 
-               $derived->setModules( [ 'test.override' ] );
-               $this->assertEquals( $derived->getModules(), [ 'test.override' ] );
+               $derived->setSkin( 'override' );
+               $this->assertEquals( $derived->getSkin(), 'override' );
        }
 
-       public function testSetOnly() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+       public function testUser() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setUser( 'Example' );
+               $this->assertEquals( $derived->getUser(), 'Example' );
+       }
+
+       public function testDebug() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setDebug( true );
+               $this->assertEquals( $derived->getDebug(), true );
+       }
+
+       public function testOnly() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
 
                $derived->setOnly( 'styles' );
                $this->assertEquals( $derived->getOnly(), 'styles' );
@@ -58,21 +92,35 @@ class DerivativeResourceLoaderContextTest extends PHPUnit_Framework_TestCase {
                $this->assertEquals( $derived->getOnly(), null );
        }
 
-       public function testSetSkin() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+       public function testVersion() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
 
-               $derived->setSkin( 'override' );
-               $this->assertEquals( $derived->getSkin(), 'override' );
+               $derived->setVersion( 'hw1' );
+               $this->assertEquals( $derived->getVersion(), 'hw1' );
+       }
+
+       public function testRaw() {
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $derived->setRaw( true );
+               $this->assertEquals( $derived->getRaw(), true );
        }
 
        public function testGetHash() {
-               $context = self::getResourceLoaderContext();
-               $derived = new DerivativeResourceLoaderContext( $context );
+               $derived = new DerivativeResourceLoaderContext( self::getContext() );
+
+               $this->assertEquals( $derived->getHash(), 'zh|fallback|||scripts|||||' );
 
                $derived->setLanguage( 'nl' );
+               $derived->setUser( 'Example' );
                // Assert that subclass is able to clear parent class "hash" member
-               $this->assertEquals( $derived->getHash(), 'nl|fallback|||scripts|||||' );
+               $this->assertEquals( $derived->getHash(), 'nl|fallback||Example|scripts|||||' );
        }
 
+       public function testAccessors() {
+               $context = self::getContext();
+               $derived = new DerivativeResourceLoaderContext( $context );
+               $this->assertSame( $derived->getRequest(), $context->getRequest() );
+               $this->assertSame( $derived->getResourceLoader(), $context->getResourceLoader() );
+       }
 }
diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderContextTest.php b/tests/phpunit/includes/resourceloader/ResourceLoaderContextTest.php
new file mode 100644 (file)
index 0000000..1093039
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * See also:
+ * - ResourceLoaderTest::testExpandModuleNames
+ * - ResourceLoaderImageModuleTest::testContext
+ *
+ * @group Cache
+ * @covers ResourceLoaderContext
+ */
+class ResourceLoaderContextTest extends PHPUnit_Framework_TestCase {
+       protected static function getResourceLoader() {
+               return new EmptyResourceLoader( new HashConfig( [
+                       'ResourceLoaderDebug' => false,
+                       'DefaultSkin' => 'fallback',
+                       'LanguageCode' => 'nl',
+               ] ) );
+       }
+
+       public function testEmpty() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [] ) );
+
+               // Request parameters
+               $this->assertEquals( [], $ctx->getModules() );
+               $this->assertEquals( 'nl', $ctx->getLanguage() );
+               $this->assertEquals( false, $ctx->getDebug() );
+               $this->assertEquals( null, $ctx->getOnly() );
+               $this->assertEquals( 'fallback', $ctx->getSkin() );
+               $this->assertEquals( null, $ctx->getUser() );
+
+               // Misc
+               $this->assertEquals( 'ltr', $ctx->getDirection() );
+               $this->assertEquals( 'nl|fallback||||||||', $ctx->getHash() );
+               $this->assertInstanceOf( User::class, $ctx->getUserObj() );
+       }
+
+       public function testDummy() {
+               $this->assertInstanceOf(
+                       ResourceLoaderContext::class,
+                       ResourceLoaderContext::newDummyContext()
+               );
+       }
+
+       public function testAccessors() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [] ) );
+               $this->assertInstanceOf( WebRequest::class, $ctx->getRequest() );
+               $this->assertInstanceOf( \Psr\Log\LoggerInterface::class, $ctx->getLogger() );
+       }
+
+       public function testTypicalRequest() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [
+                       'debug' => 'false',
+                       'lang' => 'zh',
+                       'modules' => 'foo|foo.quux,baz,bar|baz.quux',
+                       'only' => 'styles',
+                       'skin' => 'fallback',
+               ] ) );
+
+               // Request parameters
+               $this->assertEquals(
+                       $ctx->getModules(),
+                       [ 'foo', 'foo.quux', 'foo.baz', 'foo.bar', 'baz.quux' ]
+               );
+               $this->assertEquals( false, $ctx->getDebug() );
+               $this->assertEquals( 'zh', $ctx->getLanguage() );
+               $this->assertEquals( 'styles', $ctx->getOnly() );
+               $this->assertEquals( 'fallback', $ctx->getSkin() );
+               $this->assertEquals( null, $ctx->getUser() );
+
+               // Misc
+               $this->assertEquals( 'ltr', $ctx->getDirection() );
+               $this->assertEquals( 'zh|fallback|||styles|||||', $ctx->getHash() );
+       }
+
+       public function testShouldInclude() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [] ) );
+               $this->assertTrue( $ctx->shouldIncludeScripts(), 'Scripts in combined' );
+               $this->assertTrue( $ctx->shouldIncludeStyles(), 'Styles in combined' );
+               $this->assertTrue( $ctx->shouldIncludeMessages(), 'Messages in combined' );
+
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [
+                       'only' => 'styles'
+               ] ) );
+               $this->assertFalse( $ctx->shouldIncludeScripts(), 'Scripts not in styles-only' );
+               $this->assertTrue( $ctx->shouldIncludeStyles(), 'Styles in styles-only' );
+               $this->assertFalse( $ctx->shouldIncludeMessages(), 'Messages not in styles-only' );
+
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [
+                       'only' => 'scripts'
+               ] ) );
+               $this->assertTrue( $ctx->shouldIncludeScripts(), 'Scripts in scripts-only' );
+               $this->assertFalse( $ctx->shouldIncludeStyles(), 'Styles not in scripts-only' );
+               $this->assertFalse( $ctx->shouldIncludeMessages(), 'Messages not in scripts-only' );
+       }
+
+       public function testGetUser() {
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [] ) );
+               $this->assertSame( null, $ctx->getUser() );
+               $this->assertTrue( $ctx->getUserObj()->isAnon() );
+
+               $ctx = new ResourceLoaderContext( $this->getResourceLoader(), new FauxRequest( [
+                       'user' => 'Example'
+               ] ) );
+               $this->assertSame( 'Example', $ctx->getUser() );
+               $this->assertEquals( 'Example', $ctx->getUserObj()->getName() );
+       }
+}
index f61540d..aeb82d1 100644 (file)
@@ -154,6 +154,49 @@ class ResourceLoaderImageModuleTest extends ResourceLoaderTestCase {
                $styles = $module->getStyles( $this->getResourceLoaderContext() );
                $this->assertEquals( $expected, $styles['all'] );
        }
+
+       /**
+        * @covers ResourceLoaderContext::getImageObj
+        */
+       public function testContext() {
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest() );
+               $this->assertFalse( $context->getImageObj(), 'Missing image parameter' );
+
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'image' => 'example',
+               ] ) );
+               $this->assertFalse( $context->getImageObj(), 'Missing module parameter' );
+
+               $context = new ResourceLoaderContext( new EmptyResourceLoader(), new FauxRequest( [
+                       'modules' => 'unknown',
+                       'image' => 'example',
+               ] ) );
+               $this->assertFalse( $context->getImageObj(), 'Not an image module' );
+
+               $rl = new EmptyResourceLoader();
+               $rl->register( 'test', [
+                       'class' => ResourceLoaderImageModule::class,
+                       'prefix' => 'test',
+                       'images' => [ 'example' => 'example.png' ],
+               ] );
+               $context = new ResourceLoaderContext( $rl, new FauxRequest( [
+                       'modules' => 'test',
+                       'image' => 'unknown',
+               ] ) );
+               $this->assertFalse( $context->getImageObj(), 'Unknown image' );
+
+               $rl = new EmptyResourceLoader();
+               $rl->register( 'test', [
+                       'class' => ResourceLoaderImageModule::class,
+                       'prefix' => 'test',
+                       'images' => [ 'example' => 'example.png' ],
+               ] );
+               $context = new ResourceLoaderContext( $rl, new FauxRequest( [
+                       'modules' => 'test',
+                       'image' => 'example',
+               ] ) );
+               $this->assertInstanceOf( ResourceLoaderImage::class, $context->getImageObj() );
+       }
 }
 
 class ResourceLoaderImageModuleTestable extends ResourceLoaderImageModule {
index 53c9926..9a3e222 100644 (file)
@@ -163,6 +163,12 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                                [ 'single.module', 'foobar', 'foobaz' ],
                                'single.module|foobar,foobaz',
                        ],
+                       [
+                               'Ordering',
+                               [ 'foo', 'foo.baz', 'baz.quux', 'foo.bar' ],
+                               'foo|foo.baz,bar|baz.quux',
+                               [ 'foo', 'foo.baz', 'foo.bar', 'baz.quux' ],
+                       ]
                ];
        }
 
@@ -178,8 +184,12 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
         * @dataProvider providePackedModules
         * @covers ResourceLoaderContext::expandModuleNames
         */
-       public function testexpandModuleNames( $desc, $modules, $packed ) {
-               $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc );
+       public function testExpandModuleNames( $desc, $modules, $packed, $unpacked = null ) {
+               $this->assertEquals(
+                       $unpacked ?: $modules,
+                       ResourceLoaderContext::expandModuleNames( $packed ),
+                       $desc
+               );
        }
 
        public static function provideAddSource() {
index a480671..0797f32 100644 (file)
                assert.deepEqual( stub.getCall( 0 ).args, [ { foo: 'bar' } ], '#saveOptions called correctly' );
        } );
 
-       QUnit.test( 'saveOptions', function ( assert ) {
+       QUnit.test( 'saveOptions without Unit Separator', function ( assert ) {
                QUnit.expect( 13 );
 
-               var api = new mw.Api();
+               var api = new mw.Api( { useUS: false } );
 
                // We need to respond to the request for token first, otherwise the other requests won't be sent
                // until after the server.respond call, which confuses sinon terribly. This sucks a lot.
                        }
                } );
        } );
+
+       QUnit.test( 'saveOptions with Unit Separator', function ( assert ) {
+               QUnit.expect( 14 );
+
+               var api = new mw.Api( { useUS: true } );
+
+               // We need to respond to the request for token first, otherwise the other requests won't be sent
+               // until after the server.respond call, which confuses sinon terribly. This sucks a lot.
+               api.getToken( 'options' );
+               this.server.respond(
+                       /meta=tokens&type=csrf/,
+                       [ 200, { 'Content-Type': 'application/json' },
+                               '{ "query": { "tokens": { "csrftoken": "+\\\\" } } }' ]
+               );
+
+               api.saveOptions( {} ).done( function () {
+                       assert.ok( true, 'Request completed: empty case' );
+               } );
+               api.saveOptions( { foo: 'bar' } ).done( function () {
+                       assert.ok( true, 'Request completed: simple' );
+               } );
+               api.saveOptions( { foo: 'bar', baz: 'quux' } ).done( function () {
+                       assert.ok( true, 'Request completed: two options' );
+               } );
+               api.saveOptions( { foo: 'bar|quux', bar: 'a|b|c', baz: 'quux' } ).done( function () {
+                       assert.ok( true, 'Request completed: bundleable with unit separator' );
+               } );
+               api.saveOptions( { foo: 'bar|quux', bar: 'a|b|c', 'baz=baz': 'quux' } ).done( function () {
+                       assert.ok( true, 'Request completed: not bundleable with unit separator' );
+               } );
+               api.saveOptions( { foo: null } ).done( function () {
+                       assert.ok( true, 'Request completed: reset an option' );
+               } );
+               api.saveOptions( { 'foo|bar=quux': null } ).done( function () {
+                       assert.ok( true, 'Request completed: reset an option, not bundleable' );
+               } );
+
+               // Requests are POST, match requestBody instead of url
+               this.server.respond( function ( request ) {
+                       switch ( request.requestBody ) {
+                               // simple
+                               case 'action=options&format=json&formatversion=2&change=foo%3Dbar&token=%2B%5C':
+                               // two options
+                               case 'action=options&format=json&formatversion=2&change=foo%3Dbar%7Cbaz%3Dquux&token=%2B%5C':
+                               // bundleable with unit separator
+                               case 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc%1Fbaz%3Dquux&token=%2B%5C':
+                               // not bundleable with unit separator
+                               case 'action=options&format=json&formatversion=2&optionname=baz%3Dbaz&optionvalue=quux&token=%2B%5C':
+                               case 'action=options&format=json&formatversion=2&change=%1Ffoo%3Dbar%7Cquux%1Fbar%3Da%7Cb%7Cc&token=%2B%5C':
+                               // reset an option
+                               case 'action=options&format=json&formatversion=2&change=foo&token=%2B%5C':
+                               // reset an option, not bundleable
+                               case 'action=options&format=json&formatversion=2&optionname=foo%7Cbar%3Dquux&token=%2B%5C':
+                                       assert.ok( true, 'Repond to ' + request.requestBody );
+                                       request.respond( 200, { 'Content-Type': 'application/json' },
+                                               '{ "options": "success" }' );
+                                       break;
+                               default:
+                                       assert.ok( false, 'Unexpected request: ' + request.requestBody );
+                       }
+               } );
+       } );
 }( mediaWiki ) );