Merge "Fix SpecialBlock validation for ipb_allow_usertalk"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 31 Jul 2019 12:36:45 +0000 (12:36 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 31 Jul 2019 12:36:45 +0000 (12:36 +0000)
234 files changed:
RELEASE-NOTES-1.34
autoload.php
includes/Autopromote.php
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/Revision/RenderedRevision.php
includes/Revision/RevisionRenderer.php
includes/Revision/RevisionStore.php
includes/ServiceWiring.php
includes/SiteStatsInit.php
includes/Storage/PageEditStash.php
includes/Storage/SqlBlobStore.php
includes/api/ApiImportReporter.php
includes/api/ApiMain.php
includes/api/ApiUpload.php
includes/api/i18n/eu.json
includes/api/i18n/mk.json
includes/api/i18n/nl.json
includes/api/i18n/zh-hant.json
includes/block/AbstractBlock.php
includes/block/BlockManager.php
includes/block/DatabaseBlock.php
includes/cache/MessageCache.php
includes/content/WikitextContent.php
includes/context/RequestContext.php
includes/db/DatabaseOracle.php
includes/db/MWLBFactory.php
includes/diff/SlotDiffRenderer.php
includes/export/DumpFileOutput.php
includes/export/WikiExporter.php
includes/externalstore/ExternalStoreDB.php
includes/htmlform/HTMLForm.php
includes/import/UploadSourceAdapter.php
includes/import/WikiImporter.php
includes/import/WikiRevision.php
includes/installer/i18n/af.json
includes/installer/i18n/ar.json
includes/installer/i18n/ast.json
includes/installer/i18n/ba.json
includes/installer/i18n/be-tarask.json
includes/installer/i18n/bg.json
includes/installer/i18n/bn.json
includes/installer/i18n/br.json
includes/installer/i18n/bs.json
includes/installer/i18n/bto.json
includes/installer/i18n/ca.json
includes/installer/i18n/cs.json
includes/installer/i18n/csb.json
includes/installer/i18n/da.json
includes/installer/i18n/de.json
includes/installer/i18n/diq.json
includes/installer/i18n/el.json
includes/installer/i18n/eo.json
includes/installer/i18n/es.json
includes/installer/i18n/eu.json
includes/installer/i18n/fa.json
includes/installer/i18n/fi.json
includes/installer/i18n/fr.json
includes/installer/i18n/frc.json
includes/installer/i18n/frp.json
includes/installer/i18n/gl.json
includes/installer/i18n/he.json
includes/installer/i18n/hrx.json
includes/installer/i18n/hsb.json
includes/installer/i18n/hu.json
includes/installer/i18n/ia.json
includes/installer/i18n/id.json
includes/installer/i18n/io.json
includes/installer/i18n/is.json
includes/installer/i18n/it.json
includes/installer/i18n/ja.json
includes/installer/i18n/ka.json
includes/installer/i18n/ko.json
includes/installer/i18n/ksh.json
includes/installer/i18n/ku-latn.json
includes/installer/i18n/lb.json
includes/installer/i18n/lij.json
includes/installer/i18n/lt.json
includes/installer/i18n/lv.json
includes/installer/i18n/mg.json
includes/installer/i18n/mk.json
includes/installer/i18n/ms.json
includes/installer/i18n/mt.json
includes/installer/i18n/nap.json
includes/installer/i18n/nb.json
includes/installer/i18n/nl-informal.json
includes/installer/i18n/nl.json
includes/installer/i18n/oc.json
includes/installer/i18n/olo.json
includes/installer/i18n/pl.json
includes/installer/i18n/pms.json
includes/installer/i18n/pt-br.json
includes/installer/i18n/pt.json
includes/installer/i18n/ro.json
includes/installer/i18n/roa-tara.json
includes/installer/i18n/ru.json
includes/installer/i18n/sco.json
includes/installer/i18n/sh.json
includes/installer/i18n/si.json
includes/installer/i18n/sl.json
includes/installer/i18n/sr-ec.json
includes/installer/i18n/sr-el.json
includes/installer/i18n/sv.json
includes/installer/i18n/te.json
includes/installer/i18n/th.json
includes/installer/i18n/tl.json
includes/installer/i18n/tr.json
includes/installer/i18n/tt-cyrl.json
includes/installer/i18n/uk.json
includes/installer/i18n/vi.json
includes/installer/i18n/war.json
includes/installer/i18n/zh-hans.json
includes/installer/i18n/zh-hant.json
includes/jobqueue/jobs/AssembleUploadChunksJob.php
includes/libs/mime/MimeAnalyzer.php
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/MediumSpecificBagOStuff.php
includes/libs/objectcache/WANObjectCache.php
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseMssql.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/logging/LogFormatter.php
includes/media/BitmapHandler.php
includes/media/BmpHandler.php
includes/media/DjVuImage.php
includes/media/ExifBitmapHandler.php
includes/media/MediaHandler.php
includes/media/SVGMetadataExtractor.php
includes/media/SvgHandler.php
includes/media/XCFHandler.php
includes/objectcache/SqlBagOStuff.php
includes/pager/AlphabeticPager.php
includes/pager/Pager.php
includes/parser/CoreParserFunctions.php
includes/parser/Parser.php
includes/parser/ParserFactory.php
includes/parser/ParserOptions.php
includes/parser/ParserOutput.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderImage.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/search/BaseSearchResultSet.php [new file with mode: 0644]
includes/search/ISearchResultSet.php
includes/search/SearchEngine.php
includes/search/SearchResult.php
includes/search/SearchResultSet.php
includes/search/SearchResultSetTrait.php [new file with mode: 0644]
includes/skins/Skin.php
includes/specialpage/QueryPage.php
includes/specials/SpecialBlock.php
includes/specials/SpecialUnlinkAccounts.php
includes/templates/EnhancedChangesListGroup.mustache
includes/upload/UploadBase.php
includes/watcheditem/WatchedItemStore.php
languages/i18n/ar.json
languages/i18n/as.json
languages/i18n/ast.json
languages/i18n/az.json
languages/i18n/bcc.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/br.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/de.json
languages/i18n/en.json
languages/i18n/eu.json
languages/i18n/exif/tt-cyrl.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/haw.json
languages/i18n/he.json
languages/i18n/hy.json
languages/i18n/hyw.json
languages/i18n/id.json
languages/i18n/io.json
languages/i18n/it.json
languages/i18n/ko.json
languages/i18n/lij.json
languages/i18n/lrc.json
languages/i18n/lt.json
languages/i18n/min.json
languages/i18n/nds-nl.json
languages/i18n/nl.json
languages/i18n/nqo.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ru.json
resources/Resources.php
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterTagMultiselectWidgetMobile.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less
resources/src/mediawiki.rcfilters/ui/ChangesLimitPopupWidget.js
resources/src/mediawiki.rcfilters/ui/FilterTagMultiselectWidget.js
resources/src/mediawiki.rcfilters/ui/FilterWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/MenuSelectWidget.js
resources/src/mediawiki.special.apisandbox/apisandbox.js
resources/src/mediawiki.widgets/mw.widgets.CopyTextLayout.js
resources/src/startup/mediawiki.js
resources/src/startup/startup.js
tests/parser/ParserTestRunner.php
tests/phpunit/MediaWikiCoversValidator.php
tests/phpunit/data/media/zip-comment-overflow.png [new file with mode: 0644]
tests/phpunit/data/media/zip-kind-of-valid-2.png [new file with mode: 0644]
tests/phpunit/data/media/zip-kind-of-valid.png [new file with mode: 0644]
tests/phpunit/data/media/zip-sig-near-end.png [new file with mode: 0644]
tests/phpunit/includes/Permissions/PermissionManagerTest.php
tests/phpunit/includes/Revision/RevisionStoreTest.php
tests/phpunit/includes/block/BlockManagerTest.php
tests/phpunit/includes/libs/mime/MimeAnalyzerTest.php
tests/phpunit/includes/libs/objectcache/BagOStuffTest.php
tests/phpunit/includes/libs/objectcache/WANObjectCacheTest.php
tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php
tests/phpunit/includes/logging/BlockLogFormatterTest.php
tests/phpunit/includes/logging/DeleteLogFormatterTest.php
tests/phpunit/includes/logging/LogFormatterTestCase.php
tests/phpunit/includes/media/SVGMetadataExtractorTest.php [deleted file]
tests/phpunit/includes/media/SVGReaderTest.php [new file with mode: 0644]
tests/phpunit/includes/parser/ParserOutputTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderWikiModuleTest.php
tests/phpunit/includes/search/SearchResultSetTest.php
tests/phpunit/includes/user/UserTest.php
tests/phpunit/suites/ParserTestTopLevelSuite.php

index 7a24818..1610637 100644 (file)
@@ -61,6 +61,10 @@ For notes on 1.33.x and older releases, see HISTORY.
   1.23, is now hard-deprecated.
 * $wgProfileOnly — Setting this, deprecated in 1.23, is now hard-deprecated.
   Instead, set the log file in $wgDebugLogGroups['profileoutput'].
+* $wgProxyList — Setting this to an array with IP addresses in the array keys,
+  which was deprecated in 1.30, no longer works. Instead, $wgProxyList should be
+  an array with IP addresses as the values, or a string path to a file
+  containing one IP address per line.
 * …
 
 ==== Removed configuration ====
@@ -72,6 +76,8 @@ For notes on 1.33.x and older releases, see HISTORY.
   configurable via $wgDebugLogFile.
 * $wgPasswordSalt – This setting, used for migrating exceptionally old, insecure
   password setups and deprecated since 1.24, is now removed.
+* $wgDBOracleDRCP - If you must use persistent connections, set DBO_PERSISTENT
+  in the 'flags' field for servers in $wgDBServers (or $wgLBFactoryConf).
 
 === New user-facing features in 1.34 ===
 * Special:Mute has been added as a quick way for users to block unwanted emails
@@ -309,11 +315,24 @@ because of Phabricator reports.
   deprecated since 1.33.
 * The static properties mw.Api.errors and mw.Api.warnings, deprecated in 1.29,
   have been removed.
+* ParserOption::getSpeculativeRevIdCallback(), deprecated in 1.28, has been
+  removed.
 * The UploadVerification hook, deprecated in 1.28, has been removed. Instead,
   use the UploadVerifyFile hook.
 * UploadBase:: and UploadFromChunks::stashFileGetKey() and stashSession(),
   deprecated in 1.28, have been removed. Instead, please use the getFileKey()
   method on the response from doStashFile().
+* LBFactory::setDomainPrefix() and LoadBalancer::setDomainPrefix(), deprecated
+  in 1.33, have been removed. Use setLocalDomainPrefix() instead.
+* IDatabase::implicitGroupby(), deprecated in 1.30, has been removed.
+* IDatabase::doneWrites(), deprecated in 1.31, has been removed.
+  Use IDatabase::lastDoneWrites() instead.
+* Database::reportConnectionError(), deprecated in 1.32, has been removed.
+* LoadBalancer::laggedSlaveUsed(), deprecated in 1.28, has been removed.
+  Use LoadBalancer::laggedReplicaUsed() instead.
+* Database::getProperty(), deprecated in 1.28, has been removed.
+* IDatabase::getWikiId(), deprecated in 1.30, has been removed.
+  Use IDatabase::getDomainID() instead.
 * …
 
 === Deprecations in 1.34 ===
@@ -396,6 +415,13 @@ because of Phabricator reports.
   PermissionManager::getUserPermissions() instead.
 * The LocalisationCacheRecache hook no longer allows purging of message blobs
   to be prevented. Modifying the $purgeBlobs parameter now has no effect.
+* SVGMetadataExtractor::getMetadata has been deprecated. Instead, you should
+  use SVGReader->getMetadata() directly.
+* The following public properties on AbstractBlock are deprecated: $mReason,
+  $mTimestamp, $mExpiry, $mHideName. Use the getters/setters instead.
+* The following public properties on DatabaseBlock are deprecated: $mAuto,
+  $mParentBlockId. To check for an autoblock use DatabaseBlock::getType; to
+  check for the parent ID, use DatabaseBlock::getParentBlockId.
 
 === Other changes in 1.34 ===
 * …
index e6e6504..3525b48 100644 (file)
@@ -181,6 +181,7 @@ $wgAutoloadLocalClasses = [
        'BadTitleError' => __DIR__ . '/includes/exception/BadTitleError.php',
        'BagOStuff' => __DIR__ . '/includes/libs/objectcache/BagOStuff.php',
        'BaseDump' => __DIR__ . '/includes/export/BaseDump.php',
+       'BaseSearchResultSet' => __DIR__ . '/includes/search/BaseSearchResultSet.php',
        'BaseTemplate' => __DIR__ . '/includes/skins/BaseTemplate.php',
        'BashkirUppercaseCollation' => __DIR__ . '/includes/collation/BashkirUppercaseCollation.php',
        'BatchRowIterator' => __DIR__ . '/includes/utils/BatchRowIterator.php',
@@ -1321,6 +1322,7 @@ $wgAutoloadLocalClasses = [
        'SearchPostgres' => __DIR__ . '/includes/search/SearchPostgres.php',
        'SearchResult' => __DIR__ . '/includes/search/SearchResult.php',
        'SearchResultSet' => __DIR__ . '/includes/search/SearchResultSet.php',
+       'SearchResultSetTrait' => __DIR__ . '/includes/search/SearchResultSetTrait.php',
        'SearchSqlite' => __DIR__ . '/includes/search/SearchSqlite.php',
        'SearchSuggestion' => __DIR__ . '/includes/search/SearchSuggestion.php',
        'SearchSuggestionSet' => __DIR__ . '/includes/search/SearchSuggestionSet.php',
index a413037..b17f1ab 100644 (file)
@@ -198,8 +198,7 @@ class Autopromote {
                        case APCOND_IPINRANGE:
                                return IP::isInRange( $user->getRequest()->getIP(), $cond[1] );
                        case APCOND_BLOCKED:
-                               // @TODO Should partial blocks prevent auto promote?
-                               return (bool)$user->getBlock();
+                               return $user->getBlock() && $user->getBlock()->isSitewide();
                        case APCOND_ISBOT:
                                return in_array( 'bot', User::getGroupPermissions( $user->getGroups() ) );
                        default:
index 6a1f7b5..608ef6a 100644 (file)
@@ -2052,23 +2052,21 @@ $wgSharedSchema = false;
  *                  sent to it. It will be excluded from lag checks in maintenance scripts.
  *                  The only way it can receive traffic is if groupLoads is used.
  *
- *   - groupLoads:  array of load ratios, the key is the query group name. A query may belong
- *                  to several groups, the most specific group defined here is used.
- *
- *   - flags:       bit field
- *                  - DBO_DEFAULT -- turns on DBO_TRX only if "cliMode" is off (recommended)
- *                  - DBO_DEBUG -- equivalent of $wgDebugDumpSql
- *                  - DBO_TRX -- wrap entire request in a transaction
- *                  - DBO_NOBUFFER -- turn off buffering (not useful in LocalSettings.php)
- *                  - DBO_PERSISTENT -- enables persistent database connections
- *                  - DBO_SSL -- uses SSL/TLS encryption in database connections, if available
- *                  - DBO_COMPRESS -- uses internal compression in database connections,
- *                                    if available
+ *   - groupLoads:  (optional) Array of load ratios, the key is the query group name. A query
+ *                  may belong to several groups, the most specific group defined here is used.
+ *
+ *   - flags:       (optional) Bit field of properties:
+ *                  - DBO_DEFAULT:    Transactionalize web requests and use autocommit otherwise
+ *                  - DBO_DEBUG:      Equivalent of $wgDebugDumpSql
+ *                  - DBO_SSL:        Use TLS connection encryption if available
+ *                  - DBO_COMPRESS:   Use protocol compression with database connections
+ *                  - DBO_PERSISTENT: Enables persistent database connections
  *
  *   - max lag:     (optional) Maximum replication lag before a replica DB goes out of rotation
  *   - is static:   (optional) Set to true if the dataset is static and no replication is used.
  *   - cliMode:     (optional) Connection handles will not assume that requests are short-lived
  *                  nor that INSERT..SELECT can be rewritten into a buffered SELECT and INSERT.
+ *                  This is what DBO_DEFAULT uses to determine when a web request is present.
  *                  [Default: uses value of $wgCommandLineMode]
  *
  *   These and any other user-defined properties will be assigned to the mLBInfo member
@@ -2138,34 +2136,6 @@ $wgDBerrorLog = false;
  */
 $wgDBerrorLogTZ = false;
 
-/**
- * Set true to enable Oracle DCRP (supported from 11gR1 onward)
- *
- * To use this feature set to true and use a datasource defined as
- * POOLED (i.e. in tnsnames definition set server=pooled in connect_data
- * block).
- *
- * Starting from 11gR1 you can use DCRP (Database Resident Connection
- * Pool) that maintains established sessions and reuses them on new
- * connections.
- *
- * Not completely tested, but it should fall back on normal connection
- * in case the pool is full or the datasource is not configured as
- * pooled.
- * And the other way around; using oci_pconnect on a non pooled
- * datasource should produce a normal connection.
- *
- * When it comes to frequent shortlived DB connections like with MW
- * Oracle tends to s***. The problem is the driver connects to the
- * database reasonably fast, but establishing a session takes time and
- * resources. MW does not rely on session state (as it does not use
- * features such as package variables) so establishing a valid session
- * is in this case an unwanted overhead that just slows things down.
- *
- * @warning EXPERIMENTAL!
- */
-$wgDBOracleDRCP = false;
-
 /**
  * Other wikis on this site, can be administered from a single developer account.
  *
@@ -5462,7 +5432,7 @@ $wgAutoConfirmCount = 0;
  *  - [ APCOND_IPINRANGE, range ]:
  *      true if the user has an IP address in the range of the passed parameter
  *  - [ APCOND_BLOCKED ]:
- *      true if the user is blocked
+ *      true if the user is sitewide blocked
  *  - [ APCOND_ISBOT ]:
  *      true if the user is a bot
  *  - similar constructs can be defined by extensions
@@ -6002,9 +5972,8 @@ $wgSecretKey = false;
  * Big list of banned IP addresses.
  *
  * This can have the following formats:
- * - An array of addresses, either in the values
- *   or the keys (for backward compatibility, deprecated since 1.30)
- * - A string, in that case this is the path to a file
+ * - An array of addresses
+ * - A string, in which case this is the path to a file
  *   containing the list of IP addresses, one per line
  */
 $wgProxyList = [];
index 7b4b502..1741958 100644 (file)
@@ -2563,10 +2563,10 @@ function wfWikiID() {
  * @todo Replace calls to wfGetDB with calls to LoadBalancer::getConnection()
  *       on an injected instance of LoadBalancer.
  *
- * @return \Wikimedia\Rdbms\Database
+ * @return \Wikimedia\Rdbms\DBConnRef
  */
 function wfGetDB( $db, $groups = [], $wiki = false ) {
-       return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
+       return wfGetLB( $wiki )->getMaintenanceConnectionRef( $db, $groups, $wiki );
 }
 
 /**
index cf1cc94..a913244 100644 (file)
@@ -292,6 +292,7 @@ class RenderedRevision implements SlotRenderingProvider {
                $this->setRevisionInternal( $rev );
 
                $this->pruneRevisionSensitiveOutput(
+                       $this->revision->getPageId(),
                        $this->revision->getId(),
                        $this->revision->getTimestamp()
                );
@@ -300,28 +301,38 @@ class RenderedRevision implements SlotRenderingProvider {
        /**
         * Prune any output that depends on the revision ID.
         *
+        * @param int|bool $actualPageId The actual page id, to check the used speculative page ID
+        *        against; false, to not purge on vary-page-id; true, to purge on vary-page-id
+        *        unconditionally.
         * @param int|bool $actualRevId The actual rev id, to check the used speculative rev ID
-        *        against, or false to not purge on vary-revision-id, or true to purge on
+        *        against,; false, to not purge on vary-revision-id; true, to purge on
         *        vary-revision-id unconditionally.
         * @param string|bool $actualRevTimestamp The actual rev timestamp, to check against the
-        *        parser output revision timestamp, or false to not purge on vary-revision-timestamp
+        *        parser output revision timestamp; false, to not purge on vary-revision-timestamp;
+        *        true, to purge on vary-revision-timestamp unconditionally.
         */
-       private function pruneRevisionSensitiveOutput( $actualRevId, $actualRevTimestamp ) {
+       private function pruneRevisionSensitiveOutput(
+               $actualPageId,
+               $actualRevId,
+               $actualRevTimestamp
+       ) {
                if ( $this->revisionOutput ) {
                        if ( $this->outputVariesOnRevisionMetaData(
                                $this->revisionOutput,
+                               $actualPageId,
                                $actualRevId,
                                $actualRevTimestamp
                        ) ) {
                                $this->revisionOutput = null;
                        }
                } else {
-                       $this->saveParseLogger->debug( __METHOD__ . ": no prepared revision output...\n" );
+                       $this->saveParseLogger->debug( __METHOD__ . ": no prepared revision output" );
                }
 
                foreach ( $this->slotsOutput as $role => $output ) {
                        if ( $this->outputVariesOnRevisionMetaData(
                                $output,
+                               $actualPageId,
                                $actualRevId,
                                $actualRevTimestamp
                        ) ) {
@@ -384,51 +395,58 @@ class RenderedRevision implements SlotRenderingProvider {
 
        /**
         * @param ParserOutput $out
-        * @param int|bool  $actualRevId The actual rev id, to check the used speculative rev ID
-        *        against, false to not purge on vary-revision-id, or true to purge on
+        * @param int|bool $actualPageId The actual page id, to check the used speculative page ID
+        *        against; false, to not purge on vary-page-id; true, to purge on vary-page-id
+        *        unconditionally.
+        * @param int|bool $actualRevId The actual rev id, to check the used speculative rev ID
+        *        against,; false, to not purge on vary-revision-id; true, to purge on
         *        vary-revision-id unconditionally.
         * @param string|bool $actualRevTimestamp The actual rev timestamp, to check against the
-        *        parser output revision timestamp, false to not purge on vary-revision-timestamp,
-        *        or true to purge on vary-revision-timestamp unconditionally.
+        *        parser output revision timestamp; false, to not purge on vary-revision-timestamp;
+        *        true, to purge on vary-revision-timestamp unconditionally.
         * @return bool
         */
        private function outputVariesOnRevisionMetaData(
                ParserOutput $out,
+               $actualPageId,
                $actualRevId,
                $actualRevTimestamp
        ) {
-               $method = __METHOD__;
+               $logger = $this->saveParseLogger;
+               $varyMsg = __METHOD__ . ": cannot use prepared output for '{title}'";
+               $context = [ 'title' => $this->title->getPrefixedText() ];
 
                if ( $out->getFlag( 'vary-revision' ) ) {
                        // If {{PAGEID}} resolved to 0, then that word need to resolve to the actual page ID
-                       $this->saveParseLogger->info(
-                               "$method: Prepared output has vary-revision..."
-                       );
+                       $logger->info( "$varyMsg (vary-revision)", $context );
                        return true;
-               } elseif ( $out->getFlag( 'vary-revision-id' )
+               } elseif (
+                       $out->getFlag( 'vary-revision-id' )
                        && $actualRevId !== false
                        && ( $actualRevId === true || $out->getSpeculativeRevIdUsed() !== $actualRevId )
                ) {
-                       $this->saveParseLogger->info(
-                               "$method: Prepared output has vary-revision-id with wrong ID..."
-                       );
+                       $logger->info( "$varyMsg (vary-revision-id and wrong ID)", $context );
                        return true;
-               } elseif ( $out->getFlag( 'vary-revision-timestamp' )
+               } elseif (
+                       $out->getFlag( 'vary-revision-timestamp' )
                        && $actualRevTimestamp !== false
                        && ( $actualRevTimestamp === true ||
                                $out->getRevisionTimestampUsed() !== $actualRevTimestamp )
                ) {
-                       $this->saveParseLogger->info(
-                               "$method: Prepared output has vary-revision-timestamp with wrong timestamp..."
-                       );
+                       $logger->info( "$varyMsg (vary-revision-timestamp and wrong timestamp)", $context );
+                       return true;
+               } elseif (
+                       $out->getFlag( 'vary-page-id' )
+                       && $actualPageId !== false
+                       && ( $actualPageId === true || $out->getSpeculativePageIdUsed() !== $actualPageId )
+               ) {
+                       $logger->info( "$varyMsg (vary-page-id and wrong ID)", $context );
                        return true;
                } elseif ( $out->getFlag( 'vary-revision-exists' ) ) {
                        // If {{REVISIONID}} resolved to '', it now needs to resolve to '-'.
                        // Note that edit stashing always uses '-', which can be used for both
                        // edit filter checks and canonical parser cache.
-                       $this->saveParseLogger->info(
-                               "$method: Prepared output has vary-revision-exists..."
-                       );
+                       $logger->info( "$varyMsg (vary-revision-exists)", $context );
                        return true;
                } elseif (
                        $out->getFlag( 'vary-revision-sha1' ) &&
@@ -436,22 +454,18 @@ class RenderedRevision implements SlotRenderingProvider {
                ) {
                        // If a self-transclusion used the proposed page text, it must match the final
                        // page content after PST transformations and automatically merged edit conflicts
-                       $this->saveParseLogger->info(
-                               "$method: Prepared output has vary-revision-sha1 with wrong SHA-1..."
-                       );
+                       $logger->info( "$varyMsg (vary-revision-sha1 with wrong SHA-1)" );
                        return true;
-               } else {
-                       // NOTE: In the original fix for T135261, the output was discarded if 'vary-user' was
-                       // set for a null-edit. The reason was that the original rendering in that case was
-                       // targeting the user making the null-edit, not the user who made the original edit,
-                       // causing {{REVISIONUSER}} to return the wrong name.
-                       // This case is now expected to be handled by the code in RevisionRenderer that
-                       // constructs the ParserOptions: For a null-edit, setCurrentRevisionCallback is called
-                       // with the old, existing revision.
-
-                       $this->saveParseLogger->debug( "$method: Keeping prepared output..." );
-                       return false;
                }
-       }
 
+               // NOTE: In the original fix for T135261, the output was discarded if 'vary-user' was
+               // set for a null-edit. The reason was that the original rendering in that case was
+               // targeting the user making the null-edit, not the user who made the original edit,
+               // causing {{REVISIONUSER}} to return the wrong name.
+               // This case is now expected to be handled by the code in RevisionRenderer that
+               // constructs the ParserOptions: For a null-edit, setCurrentRevisionCallback is called
+               // with the old, existing revision.
+               $logger->debug( __METHOD__ . ": reusing prepared output for '{title}'", $context );
+               return false;
+       }
 }
index 99150c1..bbda0e5 100644 (file)
@@ -130,6 +130,9 @@ class RevisionRenderer {
                $options->setSpeculativeRevIdCallback( function () use ( $dbIndex ) {
                        return $this->getSpeculativeRevId( $dbIndex );
                } );
+               $options->setSpeculativePageIdCallback( function () use ( $dbIndex ) {
+                       return $this->getSpeculativePageId( $dbIndex );
+               } );
 
                if ( !$rev->getId() && $rev->getTimestamp() ) {
                        // This is an unsaved revision with an already determined timestamp.
@@ -166,7 +169,8 @@ class RevisionRenderer {
                // HACK: But don't use a fresh connection in unit tests, since it would not have
                // the fake tables. This should be handled by the LoadBalancer!
                $flags = defined( 'MW_PHPUNIT_TEST' ) || $dbIndex === DB_REPLICA
-                       ? 0 : ILoadBalancer::CONN_TRX_AUTOCOMMIT;
+                       ? 0
+                       : ILoadBalancer::CONN_TRX_AUTOCOMMIT;
 
                $db = $this->loadBalancer->getConnectionRef( $dbIndex, [], $this->dbDomain, $flags );
 
@@ -178,6 +182,25 @@ class RevisionRenderer {
                );
        }
 
+       private function getSpeculativePageId( $dbIndex ) {
+               // Use a fresh master connection in order to see the latest data, by avoiding
+               // stale data from REPEATABLE-READ snapshots.
+               // HACK: But don't use a fresh connection in unit tests, since it would not have
+               // the fake tables. This should be handled by the LoadBalancer!
+               $flags = defined( 'MW_PHPUNIT_TEST' ) || $dbIndex === DB_REPLICA
+                       ? 0
+                       : ILoadBalancer::CONN_TRX_AUTOCOMMIT;
+
+               $db = $this->loadBalancer->getConnectionRef( $dbIndex, [], $this->wikiId, $flags );
+
+               return 1 + (int)$db->selectField(
+                       'page',
+                       'MAX(page_id)',
+                       [],
+                       __METHOD__
+               );
+       }
+
        /**
         * This implements the layout for combining the output of multiple slots.
         *
index 8a4b6dc..fe5b5b9 100644 (file)
@@ -284,7 +284,7 @@ class RevisionStore
         */
        private function getDBConnection( $mode, $groups = [] ) {
                $lb = $this->getDBLoadBalancer();
-               return $lb->getConnection( $mode, $groups, $this->dbDomain );
+               return $lb->getConnectionRef( $mode, $groups, $this->dbDomain );
        }
 
        /**
index 1bb848f..9073de1 100644 (file)
@@ -263,6 +263,7 @@ return [
 
        'LocalServerObjectCache' => function ( MediaWikiServices $services ) : BagOStuff {
                $cacheId = \ObjectCache::detectLocalServerCache();
+
                return \ObjectCache::newFromId( $cacheId );
        },
 
@@ -439,7 +440,8 @@ return [
                        wfUrlProtocols(),
                        $services->getSpecialPageFactory(),
                        $services->getLinkRendererFactory(),
-                       $services->getNamespaceInfo()
+                       $services->getNamespaceInfo(),
+                       LoggerFactory::getInstance( 'Parser' )
                );
        },
 
@@ -620,9 +622,10 @@ return [
        'SiteStore' => function ( MediaWikiServices $services ) : SiteStore {
                $rawSiteStore = new DBSiteStore( $services->getDBLoadBalancer() );
 
-               // TODO: replace wfGetCache with a CacheFactory service.
-               // TODO: replace wfIsHHVM with a capabilities service.
-               $cache = wfGetCache( wfIsHHVM() ? CACHE_ACCEL : CACHE_ANYTHING );
+               $cache = $services->getLocalServerObjectCache();
+               if ( $cache instanceof EmptyBagOStuff ) {
+                       $cache = ObjectCache::getLocalClusterInstance();
+               }
 
                return new CachingSiteStore( $rawSiteStore, $cache );
        },
index 932e1c3..2252f8f 100644 (file)
@@ -195,8 +195,8 @@ class SiteStatsInit {
         * @return IDatabase
         */
        private static function getDB( $index, $groups = [] ) {
-               $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
-
-               return $lb->getConnection( $index, $groups );
+               return MediaWikiServices::getInstance()
+                       ->getDBLoadBalancer()
+                       ->getConnectionRef( $index, $groups );
        }
 }
index 4671d99..a0ef07d 100644 (file)
@@ -271,7 +271,7 @@ class PageEditStash {
                        // This can be used for the initial parse, e.g. for filters or doEditContent(),
                        // but a second parse will be triggered in doEditUpdates() no matter what
                        $logger->info(
-                               "Cache for key '{key}' has 'vary-revision'; post-insertion parse inevitable.",
+                               "Cache for key '{key}' has vary-revision; post-insertion parse inevitable.",
                                $context
                        );
                } else {
@@ -281,7 +281,9 @@ class PageEditStash {
                                // Similar to the above if we didn't guess the timestamp correctly
                                'vary-revision-timestamp',
                                // Similar to the above if we didn't guess the content correctly
-                               'vary-revision-sha1'
+                               'vary-revision-sha1',
+                               // Similar to the above if we didn't guess page ID correctly
+                               'vary-page-id'
                        ];
                        foreach ( $flagsMaybeReparse as $flag ) {
                                if ( $editInfo->output->getFlag( $flag ) ) {
index 5260754..d1b688b 100644 (file)
@@ -207,7 +207,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
         */
        private function getDBConnection( $index ) {
                $lb = $this->getDBLoadBalancer();
-               return $lb->getConnection( $index, [], $this->dbDomain );
+               return $lb->getConnectionRef( $index, [], $this->dbDomain );
        }
 
        /**
index 21d9d23..be53c67 100644 (file)
@@ -29,13 +29,13 @@ class ApiImportReporter extends ImportReporter {
 
        /**
         * @param Title $title
-        * @param Title $origTitle
+        * @param ForeignTitle $foreignTitle
         * @param int $revisionCount
         * @param int $successCount
         * @param array $pageInfo
         * @return void
         */
-       public function reportPage( $title, $origTitle, $revisionCount, $successCount, $pageInfo ) {
+       public function reportPage( $title, $foreignTitle, $revisionCount, $successCount, $pageInfo ) {
                // Add a result entry
                $r = [];
 
@@ -51,7 +51,7 @@ class ApiImportReporter extends ImportReporter {
                $this->mResultArr[] = $r;
 
                // Piggyback on the parent to do the logging
-               parent::reportPage( $title, $origTitle, $revisionCount, $successCount, $pageInfo );
+               parent::reportPage( $title, $foreignTitle, $revisionCount, $successCount, $pageInfo );
        }
 
        public function getData() {
index a77136d..8389b24 100644 (file)
@@ -593,9 +593,13 @@ class ApiMain extends ApiBase {
                // Printer may not be initialized if the extractRequestParams() fails for the main module
                $this->createErrorPrinter();
 
+               // Get desired HTTP code from an ApiUsageException. Don't use codes from other
+               // exception types, as they are unlikely to be intended as an HTTP code.
+               $httpCode = $e instanceof ApiUsageException ? $e->getCode() : 0;
+
                $failed = false;
                try {
-                       $this->printResult( $e->getCode() );
+                       $this->printResult( $httpCode );
                } catch ( ApiUsageException $ex ) {
                        // The error printer itself is failing. Try suppressing its request
                        // parameters and redo.
@@ -617,10 +621,10 @@ class ApiMain extends ApiBase {
                        $this->mPrinter = null;
                        $this->createErrorPrinter();
                        $this->mPrinter->forceDefaultParams();
-                       if ( $e->getCode() ) {
+                       if ( $httpCode ) {
                                $response->statusHeader( 200 ); // Reset in case the fallback doesn't want a non-200
                        }
-                       $this->printResult( $e->getCode() );
+                       $this->printResult( $httpCode );
                }
        }
 
index fc41e4e..b15b998 100644 (file)
@@ -658,7 +658,7 @@ class ApiUpload extends ApiBase {
         * @return array
         */
        protected function getApiWarnings() {
-               $warnings = $this->mUpload->checkWarnings();
+               $warnings = UploadBase::makeWarningsSerializable( $this->mUpload->checkWarnings() );
 
                return $this->transformWarnings( $warnings );
        }
@@ -670,9 +670,8 @@ class ApiUpload extends ApiBase {
 
                        if ( isset( $warnings['duplicate'] ) ) {
                                $dupes = [];
-                               /** @var File $dupe */
                                foreach ( $warnings['duplicate'] as $dupe ) {
-                                       $dupes[] = $dupe->getName();
+                                       $dupes[] = $dupe['fileName'];
                                }
                                ApiResult::setIndexedTagName( $dupes, 'duplicate' );
                                $warnings['duplicate'] = $dupes;
@@ -681,27 +680,24 @@ class ApiUpload extends ApiBase {
                        if ( isset( $warnings['exists'] ) ) {
                                $warning = $warnings['exists'];
                                unset( $warnings['exists'] );
-                               /** @var LocalFile $localFile */
                                $localFile = $warning['normalizedFile'] ?? $warning['file'];
-                               $warnings[$warning['warning']] = $localFile->getName();
+                               $warnings[$warning['warning']] = $localFile['fileName'];
                        }
 
                        if ( isset( $warnings['no-change'] ) ) {
-                               /** @var File $file */
                                $file = $warnings['no-change'];
                                unset( $warnings['no-change'] );
 
                                $warnings['nochange'] = [
-                                       'timestamp' => wfTimestamp( TS_ISO_8601, $file->getTimestamp() )
+                                       'timestamp' => wfTimestamp( TS_ISO_8601, $file['timestamp'] )
                                ];
                        }
 
                        if ( isset( $warnings['duplicate-version'] ) ) {
                                $dupes = [];
-                               /** @var File $dupe */
                                foreach ( $warnings['duplicate-version'] as $dupe ) {
                                        $dupes[] = [
-                                               'timestamp' => wfTimestamp( TS_ISO_8601, $dupe->getTimestamp() )
+                                               'timestamp' => wfTimestamp( TS_ISO_8601, $dupe['timestamp'] )
                                        ];
                                }
                                unset( $warnings['duplicate-version'] );
index 2f95348..81bd127 100644 (file)
@@ -6,7 +6,8 @@
                        "An13sa",
                        "Gorkaazk",
                        "Mikel Ibaiba",
-                       "Iñaki LL"
+                       "Iñaki LL",
+                       "Xabier Armendaritz"
                ]
        },
        "apihelp-main-param-action": "Zein ekintza burutuko da.",
@@ -37,7 +38,7 @@
        "apihelp-compare-param-torev": "Aldaratzeko bigarren berrikusketa.",
        "apihelp-compare-param-prop": "Hartu beharreko informazio zatiak.",
        "apihelp-compare-paramvalue-prop-diff": "HTML diff-a",
-       "apihelp-compare-paramvalue-prop-diffsize": "HTML diff-aren tamainia, byte-tan",
+       "apihelp-compare-paramvalue-prop-diffsize": "Aldeen HTMLaren tamaina, bytetan",
        "apihelp-compare-paramvalue-prop-size": "\"nondik\" eta \"nora\" berrikuspenen tamaina.",
        "apihelp-compare-example-1": "1. eta 2. berrikusketen arteko \"diff\"-a sortu.",
        "apihelp-createaccount-summary": "Erabiltzaile kontu berria sortu.",
index f91cf3d..9fb5f02 100644 (file)
@@ -54,6 +54,7 @@
        "apihelp-delete-param-title": "Наслов на страницата што сакате да ја избришете. Не може да се користи заедно со <var>$1pageid</var>.",
        "apihelp-delete-param-pageid": "Назнака на страницата што сакате да ја избришете. Не може да се користи заедно со <var>$1title</var>.",
        "apihelp-delete-param-reason": "Причина за бришење. Ако не се зададе, ќе се наведе автоматска причина.",
+       "apihelp-delete-param-tags": "Ознаки за примена врз ставката во дневникот на бришења.",
        "apihelp-delete-param-watch": "Додај ја страницата во набљудуваните на тековниот корисник.",
        "apihelp-delete-param-watchlist": "Безусловно додај или отстрани ја страницата од набљудуваните на тековниот корисник, користете ги нагодувањата или не ги менувајте набљудуваните.",
        "apihelp-delete-param-unwatch": "Отстрани ја страницата од набљудуваните на тековниот корисник.",
        "apihelp-query+allcategories-param-dir": "Насока на подредувањето.",
        "apihelp-query+allcategories-param-limit": "Колку категории да се дадат.",
        "apihelp-query+allcategories-param-prop": "Кои својства да се дадат:",
+       "apihelp-query+alldeletedrevisions-param-start": "Од кој датум и време да почне набројувањето.",
+       "apihelp-query+alldeletedrevisions-param-end": "На кој датум и време да запре набројувањето.",
        "apihelp-query+alldeletedrevisions-param-from": "Почни го исписот од овој наслов.",
        "apihelp-query+alldeletedrevisions-param-to": "Запри го исписот на овој наслов.",
+       "apihelp-query+alldeletedrevisions-param-prefix": "Пребарај ги сите наслови на страници што почнуваат со оваа вредност.",
        "apihelp-query+alldeletedrevisions-example-user": "Список на последните 50 избришани придонеси на корисникот <kbd>Example</kbd>.",
        "apihelp-query+alldeletedrevisions-example-ns-main": "Список на последните 50 избришани преработки во главниот именски простор.",
+       "apihelp-query+allfileusages-param-from": "Наслов на податотеката од која ќе почне набројувањето.",
+       "apihelp-query+allfileusages-param-to": "Наслов на податотеката на која ќе запре набројувањето.",
+       "apihelp-query+allfileusages-param-prefix": "Пребарај ги сите наслови на податотеки што почнуваат со оваа вредност.",
+       "apihelp-query+allfileusages-param-unique": "Прикажувај само различни податотечни наслови. Не може да се користи со $1prop=ids.\nКога се користи како создавач, дава целни страници наместо изворни.",
        "apihelp-query+allfileusages-param-prop": "Кои информации да се вклучат:",
+       "apihelp-query+allfileusages-paramvalue-prop-ids": "Ја додава назнаката на страницата од страниците што ја користат (не може да се користи со $1unique).",
        "apihelp-query+allfileusages-paramvalue-prop-title": "Го додава насловот на податотеката.",
        "apihelp-query+allfileusages-param-limit": "Колку вкупно ставки да се дадат.",
        "apihelp-query+allfileusages-param-dir": "Насока на исписот.",
        "apihelp-query+allfileusages-example-unique-generator": "Ги дава сите наслови на податотеки, означувајќи ги отсутните.",
        "apihelp-query+allfileusages-example-generator": "Дава страници што ги содржат податотеките.",
        "apihelp-query+allimages-param-dir": "Насока на исписот.",
+       "apihelp-query+allimages-param-minsize": "Ограничи на слики со барем олку бајти.",
+       "apihelp-query+allimages-param-maxsize": "Ограничи на слики со највеќе олку бајти.",
        "apihelp-query+allimages-example-b": "Прикажи список на податотеки што почнуваат со буквата <kbd>B</kbd>.",
        "apihelp-query+allimages-example-recent": "Прикажи список на неодамна подигнати податотеки сличен на [[Special:NewFiles]]",
        "apihelp-query+allimages-example-generator": "Прикажи информации за околу 4 податотеки што почнуваат со буквата <kbd>T</kbd>.",
        "apihelp-query+allredirects-param-namespace": "Именскиот простор што се набројува.",
        "apihelp-query+allredirects-param-limit": "Колку вкупно ставки да се дадат.",
        "apihelp-query+allredirects-param-dir": "Насока на исписот.",
+       "apihelp-query+allredirects-example-unique-generator": "Ги дава сите целни страници, означувајќи ги отсутните.",
        "apihelp-query+allrevisions-param-start": "Од кој датум и време да почне набројувањето.",
        "apihelp-query+allrevisions-param-end": "На кој датум и време да запре набројувањето.",
        "apihelp-query+alltransclusions-param-prop": "Кои информации да се вклучат:",
index 968920b..1fa4751 100644 (file)
        "apihelp-query+filearchive-example-simple": "Toon een lijst met alle verwijderde bestanden.",
        "apihelp-query+fileusage-paramvalue-prop-pageid": "Pagina-ID van elke pagina.",
        "apihelp-query+fileusage-paramvalue-prop-title": "Titel van elke pagina.",
+       "apihelp-query+imageinfo-paramvalue-prop-mime": "Voegt het MIME-type van het bestand toe.",
        "apihelp-query+imageinfo-paramvalue-prop-mediatype": "Voegt het mediatype van het bestand toe.",
        "apihelp-query+imageusage-param-namespace": "De door te lopen naamruimte.",
        "apihelp-query+imageusage-example-simple": "Toon pagina's die [[:File:Albert Einstein Head.jpg]] gebruiken.",
        "apihelp-query+iwbacklinks-param-prefix": "Voorvoegsel voor de interwiki.",
        "apihelp-query+iwlinks-paramvalue-prop-url": "Voegt de volledige URL toe.",
        "apihelp-query+langbacklinks-example-simple": "Toon de pagina's die verwijzen naar [[:fr:Test]].",
+       "apihelp-query+langbacklinks-example-generator": "Informatie verkrijgen over pagina's die gekoppeld zijn aan [[:fr:Test]].",
+       "apihelp-query+langlinks-param-limit": "Hoeveel intertaalkoppelingen er getoont moeten worden.",
        "apihelp-query+langlinks-paramvalue-prop-url": "Voegt de volledige URL toe.",
+       "apihelp-query+languageinfo-paramvalue-prop-bcp47": "De BCP-47 taalcode.",
+       "apihelp-query+languageinfo-paramvalue-prop-dir": "De schrijfrichting van de taal (<code>ltr</code> of <code>rtl</code>).",
        "apihelp-query+linkshere-paramvalue-prop-pageid": "Pagina-ID van elke pagina.",
        "apihelp-query+linkshere-paramvalue-prop-title": "Titel van elke pagina.",
        "apihelp-query+linkshere-param-namespace": "Toon alleen pagina's in deze naamruimten.",
index 1bdac01..c434a5b 100644 (file)
@@ -67,7 +67,7 @@
        "apihelp-clearhasmsg-example-1": "清除目前使用者的 <code>hasmsg</code> 標記。",
        "apihelp-clientlogin-summary": "使用互動流程來登入 wiki。",
        "apihelp-clientlogin-example-login": "開始以使用者 <kbd>Example</kbd> 與密碼 <kbd>ExamplePassword</kbd> 來登入至 wiki 的過程。",
-       "apihelp-clientlogin-example-login2": "在 <samp>UI</samp> 回應雙重認證後繼續登入,提供 <kbd>987654</kbd> 的 <var>OATHToken</var>。",
+       "apihelp-clientlogin-example-login2": "在 <samp>UI</samp> 回應雙因素驗證後繼續登入,提供 <kbd>987654</kbd> 的 <var>OATHToken</var>。",
        "apihelp-compare-summary": "比較 2 個頁面間的差異。",
        "apihelp-compare-extended-description": "\"from\" 以及 \"to\" 的修訂編號,頁面標題或頁面 ID 為必填。",
        "apihelp-compare-param-fromtitle": "要比對的第一個標題。",
index d24a2a5..f654404 100644 (file)
@@ -31,13 +31,22 @@ use User;
  * @since 1.34 Factored out from DatabaseBlock (previously Block).
  */
 abstract class AbstractBlock {
-       /** @var string */
+       /**
+        * @deprecated since 1.34. Use getReason and setReason instead.
+        * @var string
+        */
        public $mReason;
 
-       /** @var string */
+       /**
+        * @deprecated since 1.34. Use getTimestamp and setTimestamp instead.
+        * @var string
+        */
        public $mTimestamp;
 
-       /** @var string */
+       /**
+        * @deprecated since 1.34. Use getExpiry and setExpiry instead.
+        * @var string
+        */
        public $mExpiry = '';
 
        /** @var bool */
@@ -49,7 +58,10 @@ abstract class AbstractBlock {
        /** @var bool */
        protected $blockCreateAccount = false;
 
-       /** @var bool */
+       /**
+        * @deprecated since 1.34. Use getHideName and setHideName instead.
+        * @var bool
+        */
        public $mHideName = false;
 
        /** @var User|string */
index 68141a1..c82ed1c 100644 (file)
@@ -293,32 +293,7 @@ class BlockManager {
                        $proxyList = array_map( 'trim', file( $proxyList ) );
                }
 
-               $resultProxyList = [];
-               $deprecatedIPEntries = [];
-
-               // backward compatibility: move all ip addresses in keys to values
-               foreach ( $proxyList as $key => $value ) {
-                       $keyIsIP = IP::isIPAddress( $key );
-                       $valueIsIP = IP::isIPAddress( $value );
-                       if ( $keyIsIP && !$valueIsIP ) {
-                               $deprecatedIPEntries[] = $key;
-                               $resultProxyList[] = $key;
-                       } elseif ( $keyIsIP && $valueIsIP ) {
-                               $deprecatedIPEntries[] = $key;
-                               $resultProxyList[] = $key;
-                               $resultProxyList[] = $value;
-                       } else {
-                               $resultProxyList[] = $value;
-                       }
-               }
-
-               if ( $deprecatedIPEntries ) {
-                       wfDeprecated(
-                               'IP addresses in the keys of $wgProxyList (found the following IP addresses in keys: ' .
-                               implode( ', ', $deprecatedIPEntries ) . ', please move them to values)', '1.30' );
-               }
-
-               $proxyListIPSet = new IPSet( $resultProxyList );
+               $proxyListIPSet = new IPSet( $proxyList );
                return $proxyListIPSet->match( $ip );
        }
 
index fbf9a07..2fd62ee 100644 (file)
@@ -53,10 +53,16 @@ use Wikimedia\Rdbms\IDatabase;
  * @since 1.34 Renamed from Block.
  */
 class DatabaseBlock extends AbstractBlock {
-       /** @var bool */
+       /**
+        * @deprecated since 1.34. Use getType to check whether a block is autoblocking.
+        * @var bool
+        */
        public $mAuto;
 
-       /** @var int */
+       /**
+        * @deprecated since 1.34. Use getParentBlockId instead.
+        * @var int
+        */
        public $mParentBlockId;
 
        /** @var int */
index a8bcfc6..5745451 100644 (file)
@@ -98,6 +98,12 @@ class MessageCache {
        /** @var Language */
        protected $contLang;
 
+       /**
+        * Track which languages have been loaded by load().
+        * @var array
+        */
+       private $loadedLanguages = [];
+
        /**
         * Singleton instance
         *
@@ -264,23 +270,12 @@ class MessageCache {
                }
 
                # Don't do double loading...
-               if ( $this->cache->has( $code ) && $mode != self::FOR_UPDATE ) {
+               if ( isset( $this->loadedLanguages[$code] ) && $mode != self::FOR_UPDATE ) {
                        return true;
                }
 
                $this->overridable = array_flip( Language::getMessageKeysFor( $code ) );
 
-               // T208897 array_flip can fail and return null
-               if ( is_null( $this->overridable ) ) {
-                       LoggerFactory::getInstance( 'MessageCache' )->error(
-                               __METHOD__ . ': $this->overridable is null',
-                               [
-                                       'message_keys' => Language::getMessageKeysFor( $code ),
-                                       'code' => $code
-                               ]
-                       );
-               }
-
                # 8 lines of code just to say (once) that message cache is disabled
                if ( $this->mDisable ) {
                        static $shownDisabled = false;
@@ -396,6 +391,9 @@ class MessageCache {
                        wfDebugLog( 'MessageCacheError', __METHOD__ . ": Failed to load $code\n" );
                        # This used to throw an exception, but that led to nasty side effects like
                        # the whole wiki being instantly down if the memcached server died
+               } else {
+                       # All good, just record the success
+                       $this->loadedLanguages[$code] = true;
                }
 
                if ( !$this->cache->has( $code ) ) { // sanity
@@ -1300,6 +1298,7 @@ class MessageCache {
                        $this->wanCache->touchCheckKey( $this->getCheckKey( $code ) );
                }
                $this->cache->clear();
+               $this->loadedLanguages = [];
        }
 
        /**
index 455eb0d..8e5e0a8 100644 (file)
@@ -329,7 +329,7 @@ class WikitextContent extends TextContent {
         * using the global Parser service.
         *
         * @param Title $title
-        * @param int $revId Revision to pass to the parser (default: null)
+        * @param int|null $revId Revision to pass to the parser (default: null)
         * @param ParserOptions $options (default: null)
         * @param bool $generateHtml (default: true)
         * @param ParserOutput &$output ParserOutput representing the HTML form of the text,
index 4393abb..afc7045 100644 (file)
@@ -371,33 +371,27 @@ class RequestContext implements IContextSource, MutableContext {
                        Hooks::run( 'RequestContextCreateSkin', [ $this, &$skin ] );
                        $factory = MediaWikiServices::getInstance()->getSkinFactory();
 
-                       // If the hook worked try to set a skin from it
                        if ( $skin instanceof Skin ) {
+                               // The hook provided a skin object
                                $this->skin = $skin;
                        } elseif ( is_string( $skin ) ) {
+                               // The hook provided a skin name
                                // Normalize the key, just in case the hook did something weird.
                                $normalized = Skin::normalizeKey( $skin );
                                $this->skin = $factory->makeSkin( $normalized );
-                       }
-
-                       // If this is still null (the hook didn't run or didn't work)
-                       // then go through the normal processing to load a skin
-                       if ( $this->skin === null ) {
+                       } else {
+                               // No hook override, go through normal processing
                                if ( !in_array( 'skin', $this->getConfig()->get( 'HiddenPrefs' ) ) ) {
-                                       # get the user skin
                                        $userSkin = $this->getUser()->getOption( 'skin' );
                                        $userSkin = $this->getRequest()->getVal( 'useskin', $userSkin );
                                } else {
-                                       # if we're not allowing users to override, then use the default
                                        $userSkin = $this->getConfig()->get( 'DefaultSkin' );
                                }
 
-                               // Normalize the key in case the user is passing gibberish
-                               // or has old preferences (T71566).
+                               // Normalize the key in case the user is passing gibberish query params
+                               // or has old user preferences (T71566).
+                               // Skin::normalizeKey will also validate it, so makeSkin() won't throw.
                                $normalized = Skin::normalizeKey( $userSkin );
-
-                               // Skin::normalizeKey will also validate it, so
-                               // this won't throw an exception
                                $this->skin = $factory->makeSkin( $normalized );
                        }
 
index 501f01a..82fff6b 100644 (file)
@@ -28,7 +28,6 @@ use Wikimedia\Rdbms\DatabaseDomain;
 use Wikimedia\Rdbms\Blob;
 use Wikimedia\Rdbms\ResultWrapper;
 use Wikimedia\Rdbms\IResultWrapper;
-use Wikimedia\Rdbms\DBConnectionError;
 use Wikimedia\Rdbms\DBUnexpectedError;
 use Wikimedia\Rdbms\DBExpectedError;
 
@@ -80,101 +79,96 @@ class DatabaseOracle extends Database {
                return 'oracle';
        }
 
-       function implicitGroupby() {
-               return false;
-       }
-
        function implicitOrderby() {
                return false;
        }
 
        protected function open( $server, $user, $password, $dbName, $schema, $tablePrefix ) {
                if ( !function_exists( 'oci_connect' ) ) {
-                       throw new DBConnectionError(
-                               $this,
+                       throw $this->newExceptionAfterConnectError(
                                "Oracle functions missing, have you compiled PHP with the --with-oci8 option?\n " .
-                                       "(Note: if you recently installed PHP, you may need to restart your webserver\n " .
-                                       "and database)\n" );
+                               "(Note: if you recently installed PHP, you may need to restart your webserver\n " .
+                               "and database)"
+                       );
                }
 
+               $this->close();
+
                if ( $schema !== null ) {
-                       // We use the *database* aspect of $domain for schema, not the domain schema
-                       throw new DBExpectedError(
-                               $this,
-                               __CLASS__ . ": cannot use schema '$schema'; " .
-                               "the database component '$dbName' is actually interpreted as the Oracle schema."
+                       // This uses the *database* aspect of $domain for schema, not the domain schema
+                       throw $this->newExceptionAfterConnectError(
+                               "Got schema '$schema'; not supported. " .
+                               "The database component '$dbName' is actually interpreted as the Oracle schema."
                        );
                }
 
-               $this->close();
                $this->user = $user;
                $this->password = $password;
-               if ( !$server ) {
-                       // Backward compatibility (server used to be null and TNS was supplied in dbname)
+               if ( strlen( $server ) ) {
+                       // Transparent Network Substrate (TNS) endpoint
+                       $this->server = $server;
+                       // Database name, defaulting to the user name
+                       $realDatabase = strlen( $dbName ) ? $dbName : $user;
+               } else {
+                       // Backward compatibility; $server used to be null and $dbName was the TNS
                        $this->server = $dbName;
                        $realDatabase = $user;
-               } else {
-                       // $server now holds the TNS endpoint
-                       $this->server = $server;
-                       // $dbName is schema name if different from username
-                       $realDatabase = $dbName ?: $user;
-               }
-
-               if ( !strlen( $user ) ) { # e.g. the class is being loaded
-                       return null;
                }
-
                $session_mode = ( $this->flags & DBO_SYSDBA ) ? OCI_SYSDBA : OCI_DEFAULT;
 
-               Wikimedia\suppressWarnings();
-               if ( $this->flags & DBO_PERSISTENT ) {
-                       $this->conn = oci_pconnect(
-                               $this->user,
-                               $this->password,
-                               $this->server,
-                               $this->defaultCharset,
-                               $session_mode
-                       );
-               } elseif ( $this->flags & DBO_DEFAULT ) {
-                       $this->conn = oci_new_connect(
-                               $this->user,
-                               $this->password,
-                               $this->server,
-                               $this->defaultCharset,
-                               $session_mode
-                       );
-               } else {
-                       $this->conn = oci_connect(
-                               $this->user,
-                               $this->password,
-                               $this->server,
-                               $this->defaultCharset,
-                               $session_mode
-                       );
-               }
-               Wikimedia\restoreWarnings();
-
-               if ( $this->user != $realDatabase ) {
-                       // change current schema in session
-                       $this->selectDB( $realDatabase );
-               } else {
-                       $this->currentDomain = new DatabaseDomain(
-                               $realDatabase,
-                               null,
-                               $tablePrefix
-                       );
-               }
+               $this->installErrorHandler();
+               try {
+                       $this->conn = $this->getFlag( DBO_PERSISTENT )
+                               ? oci_pconnect(
+                                       $this->user,
+                                       $this->password,
+                                       $this->server,
+                                       $this->defaultCharset,
+                                       $session_mode
+                               )
+                               : oci_new_connect(
+                                       $this->user,
+                                       $this->password,
+                                       $this->server,
+                                       $this->defaultCharset,
+                                       $session_mode
+                               );
+               } catch ( Exception $e ) {
+                       $this->restoreErrorHandler();
+                       throw $this->newExceptionAfterConnectError( $e->getMessage() );
+               }
+               $error = $this->restoreErrorHandler();
 
                if ( !$this->conn ) {
-                       throw new DBConnectionError( $this, $this->lastError() );
+                       throw $this->newExceptionAfterConnectError( $error ?: $this->lastError() );
                }
 
-               # removed putenv calls because they interfere with the system globaly
-               $this->doQuery( 'ALTER SESSION SET NLS_TIMESTAMP_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'' );
-               $this->doQuery( 'ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT=\'DD-MM-YYYY HH24:MI:SS.FF6\'' );
-               $this->doQuery( 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS=\'.,\'' );
-
-               return (bool)$this->conn;
+               try {
+                       if ( $this->user != $realDatabase ) {
+                               // Change current schema for the entire session
+                               $this->selectDomain( new DatabaseDomain(
+                                       $realDatabase,
+                                       $this->currentDomain->getSchema(),
+                                       $this->currentDomain->getTablePrefix()
+                               ) );
+                       } else {
+                               $this->currentDomain = new DatabaseDomain( $realDatabase, null, $tablePrefix );
+                       }
+                       $set = [
+                               'NLS_TIMESTAMP_FORMAT' => 'DD-MM-YYYY HH24:MI:SS.FF6',
+                               'NLS_TIMESTAMP_TZ_FORMAT' => 'DD-MM-YYYY HH24:MI:SS.FF6',
+                               'NLS_NUMERIC_CHARACTERS' => '.,'
+                       ];
+                       foreach ( $set as $var => $val ) {
+                               $this->query(
+                                       "ALTER SESSION SET {$var}=" . $this->addQuotes( $val ),
+                                       __METHOD__,
+                                       self::QUERY_IGNORE_DBO_TRX | self::QUERY_NO_RETRY
+                               );
+                       }
+               } catch ( Exception $e ) {
+                       throw $this->newExceptionAfterConnectError( $e->getMessage() );
+               }
        }
 
        /**
index 3d404d3..0c17840 100644 (file)
@@ -212,9 +212,6 @@ abstract class MWLBFactory {
                $flags = DBO_DEFAULT;
                $flags |= $options->get( 'DebugDumpSql' ) ? DBO_DEBUG : 0;
                $flags |= $options->get( 'DebugLogFile' ) ? DBO_DEBUG : 0;
-               if ( $server['type'] === 'oracle' ) {
-                       $flags |= $options->get( 'DBOracleDRCP' ) ? DBO_PERSISTENT : 0;
-               }
 
                $server += [
                        'tablePrefix' => $options->get( 'DBprefix' ),
index b30607f..969e0ba 100644 (file)
@@ -25,13 +25,13 @@ use Wikimedia\Assert\Assert;
 /**
  * Renders a diff for a single slot (that is, a diff between two content objects).
  *
- * Callers should obtain this class by invoking ContentHandler::getSlotDiffRendererClass
+ * Callers should obtain instances of this class by invoking ContentHandler::getSlotDiffRenderer
  * on the content handler of the new content object (ie. the one shown on the right side
  * of the diff), or of the old one if the new one does not exist.
  *
  * The default implementation just does a text diff on the native text representation.
  * Content handler extensions can subclass this to provide a more appropriate diff method by
- * overriding ContentHandler::getSlotDiffRendererClass. Other extensions that want to interfere
+ * overriding ContentHandler::getSlotDiffRendererInternal. Other extensions that want to interfere
  * with diff generation in some way can use the GetSlotDiffRenderer hook.
  *
  * @ingroup DifferenceEngine
index 4bec7d4..d0256fd 100644 (file)
  * @ingroup Dump
  */
 class DumpFileOutput extends DumpOutput {
-       protected $handle = false, $filename;
+       /** @var resource|false */
+       protected $handle = false;
+       /** @var string */
+       protected $filename;
 
        /**
         * @param string $file
@@ -73,7 +76,7 @@ class DumpFileOutput extends DumpOutput {
        }
 
        /**
-        * @param array $newname
+        * @param string|string[] $newname
         * @return string
         * @throws MWException
         */
index fe6dadf..3ab88e2 100644 (file)
@@ -125,7 +125,7 @@ class WikiExporter {
         * various row objects and XML output for filtering. Filters
         * can be chained or used as callbacks.
         *
-        * @param DumpOutput &$sink
+        * @param DumpOutput|DumpFilter &$sink
         */
        public function setOutputSink( &$sink ) {
                $this->sink =& $sink;
@@ -240,7 +240,7 @@ class WikiExporter {
         * Not called by default (depends on $this->list_authors)
         * Can be set by Special:Export when not exporting whole history
         *
-        * @param array $cond
+        * @param string $cond
         */
        protected function do_list_authors( $cond ) {
                $this->author_list = "<contributors>";
index 4d70d66..4db351b 100644 (file)
@@ -154,12 +154,13 @@ class ExternalStoreDB extends ExternalStoreMedium {
         */
        public function getSlave( $cluster ) {
                $lb = $this->getLoadBalancer( $cluster );
-               $domainId = $this->getDomainId( $lb->getServerInfo( $lb->getWriterIndex() ) );
-
-               $db = $lb->getConnectionRef( DB_REPLICA, [], $domainId );
-               $db->clearFlag( DBO_TRX ); // sanity
 
-               return $db;
+               return $lb->getConnectionRef(
+                       DB_REPLICA,
+                       [],
+                       $this->getDomainId( $lb->getServerInfo( $lb->getWriterIndex() ) ),
+                       $lb::CONN_TRX_AUTOCOMMIT
+               );
        }
 
        /**
@@ -170,12 +171,13 @@ class ExternalStoreDB extends ExternalStoreMedium {
         */
        public function getMaster( $cluster ) {
                $lb = $this->getLoadBalancer( $cluster );
-               $domainId = $this->getDomainId( $lb->getServerInfo( $lb->getWriterIndex() ) );
-
-               $db = $lb->getMaintenanceConnectionRef( DB_MASTER, [], $domainId );
-               $db->clearFlag( DBO_TRX ); // sanity
 
-               return $db;
+               return $lb->getMaintenanceConnectionRef(
+                       DB_MASTER,
+                       [],
+                       $this->getDomainId( $lb->getServerInfo( $lb->getWriterIndex() ) ),
+                       $lb::CONN_TRX_AUTOCOMMIT
+               );
        }
 
        /**
index a7cef3c..ed151e6 100644 (file)
@@ -23,7 +23,7 @@
 
 /**
  * Object handling generic submission, CSRF protection, layout and
- * other logic for UI forms. in a reusable manner.
+ * other logic for UI forms in a reusable manner.
  *
  * In order to generate the form, the HTMLForm object takes an array
  * structure detailing the form fields available. Each element of the
index 7ac895c..8768f07 100644 (file)
@@ -29,7 +29,7 @@
  * @ingroup SpecialPage
  */
 class UploadSourceAdapter {
-       /** @var array */
+       /** @var ImportSource[] */
        public static $sourceRegistrations = [];
 
        /** @var ImportSource */
@@ -56,7 +56,7 @@ class UploadSourceAdapter {
        /**
         * @param string $path
         * @param string $mode
-        * @param array $options
+        * @param int $options
         * @param string &$opened_path
         * @return bool
         */
@@ -104,14 +104,14 @@ class UploadSourceAdapter {
 
        /**
         * @param string $data
-        * @return bool
+        * @return false
         */
        function stream_write( $data ) {
                return false;
        }
 
        /**
-        * @return mixed
+        * @return int
         */
        function stream_tell() {
                return $this->mPosition;
@@ -125,7 +125,7 @@ class UploadSourceAdapter {
        }
 
        /**
-        * @return array
+        * @return int[]
         */
        function url_stat() {
                $result = [];
index 00bb61f..68f5b9b 100644 (file)
@@ -466,7 +466,7 @@ class WikiImporter {
 
        /**
         * Notify the callback function when a new "<page>" is reached.
-        * @param Title $title
+        * @param array $title
         */
        function pageCallback( $title ) {
                if ( isset( $this->mPageCallback ) ) {
index cae9542..e36d673 100644 (file)
@@ -352,7 +352,7 @@ class WikiRevision implements ImportableUploadRevision, ImportableOldRevision {
 
        /**
         * @since 1.12.2
-        * @param array $params
+        * @param string $params
         */
        public function setParams( $params ) {
                $this->params = $params;
index c74f637..04aba37 100644 (file)
@@ -74,7 +74,6 @@
        "config-db-web-account": "Databasisgebruiker vir toegang tot die web",
        "config-mysql-engine": "Stoor-enjin:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Naam van die wiki:",
        "config-site-name-blank": "Verskaf 'n naam vir u webwerf.",
        "config-project-namespace": "Projeknaamruimte:",
index 78f0c09..46b9c21 100644 (file)
        "config-db-web-no-create-privs": "الحساب الذي حددته لتركيب ليس لديه امتيازات كافية لإنشاء حساب.\nالحساب الذي حددته هنا موجود بالفعل.",
        "config-mysql-engine": "محرك التخزين",
        "config-mysql-innodb": "InnoDB (مستحسن)",
-       "config-mysql-myisam": "ماي إسام",
-       "config-mysql-myisam-dep": "<strong>تحذير:</strong> لقد اخترت MyISAM كمحرك تخزين لـMySQL، والذي لا يُنصَح باستخدامه مع ميدياويكي; لأنه:\n* بالكاد يدعم التزامن بسبب قفل الجدول \n* أكثر عرضة للفساد من المحركات الأخرى\n* لا يقوم الكود الأساسي لميدياويكي بمعالجة MyISAM دائما كما يجب\n\nإذا كان تثبيت MySQL يدعم InnoDB، فمن المستحسن جدا أن تختاره بدلا منه، \nإذا كان تثبيت MySQL لا يدعم InnoDB، فربما حان الوقت للترقية.",
-       "config-mysql-only-myisam-dep": "<strong>تحذير:</strong> MyISAMهو محرك التخزين الوحيد المتاح لـMySQL على هذا الجهاز، ولا يُنصَح باستخدامه مع ميدياويكي; لأنه:\n* بالكاد يدعم التزامن بسبب قفل الجدول \n* أكثر عرضة للفساد من المحركات الأخرى\n* لا يقوم الكود الأساسي لميدياويكي بمعالجة MyISAM دائما كما يجب\n\nتثبيت MySQL لا يدعم InnoDB; ربما حان الوقت للترقية.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> هو دائما الخيار الأفضل; لأنه يحتوي على دعم تزامن جيد.\n\nقد يكون <strong>MyISAM</strong> أسرع في تثبيت المستخدم الفردي أو للقراءة فقط،\nتميل قواعد بيانات MyISAM للتلف أكثر من قواعد بيانات InnoDB.",
        "config-mssql-auth": "نوع الاستيثاق:",
        "config-mssql-install-auth": "حدد نوع المصادقة الذي سيتم استخدامه للاتصال بقاعدة البيانات أثناء عملية التثبيت. \nإذا حددت \"{{int:config-mssql-windowsauth}}\"، فسيتم استخدام بيانات اعتماد أي مستخدم يعمل عليه خادم الويب.",
index 12c6375..6b2024f 100644 (file)
        "config-db-web-no-create-privs": "La cuenta qu'especificasti pa la instalación nun tien permisos abondo pa crear una cuenta.\nLa cuenta qu'especifiques equí yá tien d'esistir.",
        "config-mysql-engine": "Motor d'almacenamientu:",
        "config-mysql-innodb": "InnoDB (aconséyase)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Triba d'autenticación:",
        "config-mssql-sqlauth": "Autenticación de SQL Server",
        "config-mssql-windowsauth": "Autenticación de Windows",
index e437503..23e5388 100644 (file)
        "config-db-web-no-create-privs": "Ҡуйылыш өсөн күрһәтелгән иҫәп яҙмағыҙҙың уны барлыҡҡа килтереү өсөн етерлек хоҡуҡтары юҡ. \nКүрһәтелгән иҫәп яҙма бында булырға тейеш инде.",
        "config-mysql-engine": "Мәғлүмәт базаһы шыуҙырмаһы",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "\"Иғтибар\" Һеҙ MySQL мәғлүмәтен һаҡлау өсөн MyISAM механизмын һайланығыҙ. Түбәндәге сәбәптәр арҡаһында уны ҡулланыу тәҡдим ителмәй:\n* параллелизмда эшләп булмай;\n* башҡа механизмдар менән сағыштырғанда мәғлүмәттәр юғала;\n* MediaWiki коды  MyISAM үҙенсәләген иҫәпкә алмай.\n\nҺеҙҙең MySQL InnoDB менән яраҡлы эшләһә ошо механизмды һайларға тәҡдим итебеҙ.\n\nҺеҙҙең MySQL InnoDB менән яраҡһыҙ эшләһә  механизмды яңыртырға тәҡдим итебеҙ.",
-       "config-mysql-only-myisam-dep": "<strong>Иҫкәртеү:</strong> MyISAM — был компьютерҙә MySQL өсөн берҙән-бер асыҡ мәғлүмәттәр һаҡлау системаһы, һәм  MediaWiki менән берлектә ҡулланырға рөхсәт ителмәй,сөнки:\n* таблицаларҙы блокировкалау һөҙөмтәһендә параллелизмды көсһөҙ тота;\n* башҡа системаларға ҡарағанда, ватылыуға күберәк дусар ителгән;\n* MediaWiki код базаһы MyISAM -ды ғәҙәттәгесә эшкәртеп бөтә алмай\nҺеҙҙең MySQL  InnoDB -ды тотмай, бәлки, яңыртыу ваҡыты еткәндер.",
        "config-mysql-engine-help": "Параллель рәүештә яҡшыраҡ эшләгәне өсөн '''InnoDB''' өҫтөнлөрәк.\n\nБер ҡулланыусы йәки төҙәтеүҙәр әҙ булғанда вики өсөн '''MyISAM'''тың тиҙлеге  шәберәк, әммә унда мәғлүмәт базаһы InnoDB-ҡа ҡарағанда йышыраҡ сафтан сыға.",
        "config-mssql-auth": "Аутентификация төрө :",
        "config-mssql-install-auth": "Ҡуйыу процесында мәғлүмәт базаһына инеү өсөн файҙаланылған төп нөсхәне тикшереү тибын һайлағыҙ. \n\nӘгәр «{{int:config-mssql-windowsauth}}» һайлаһығыҙ, ҡулланыусының веб-сервер эшләгән иҫәп яҙмаһы файҙаланыласаҡ.",
index 7e0e6de..c29f5f7 100644 (file)
        "config-db-web-no-create-privs": "Рахунак, які Вы пазначылі для ўсталяваньня ня мае правоў для стварэньня рахунку.\nРахунак, які Вы пазначылі тут, мусіць ужо існаваць.",
        "config-mysql-engine": "Рухавік сховішча:",
        "config-mysql-innodb": "InnoDB (рэкамэндавана)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Папярэджаньне''': Вы выбралі MyISAM у якасьці рухавіка для захоўваньня зьвестак у MySQL, які не рэкамэндуецца да выкарыстаньня з MediaWiki па прычынах:\n* кепская падтрымка паралельнай апрацоўкі з-за таблічных блякаваньняў;\n* большая імавернасьць пашкоджаньня зьвестак у параўнаньні зь іншымі рухавікамі;\n* код MediaWiki не ва ўсіх выпадках улічвае асаблівасьці MyISAM.\n\nКалі Ваш MySQL-сэрвэр падтрымлівае InnoDB, вельмі рэкамэндуецца выкарыстаньне менавіта гэтага рухавіка.\nКалі MySQL-сэрвэр не падтрымлівае InnoDB, пэўна, настаў час абнавіць яго.",
-       "config-mysql-only-myisam-dep": "<strong>Папярэджаньне:</strong> MyISAM — адзіная даступная сыстэма захоўваньня зьвестак для MySQL на гэтым кампутары, яна не рэкамэндуецца для ўжываньня з MediaWiki, таму што:\n* слаба падтрымлівае паралельнасьць праз блякаваньне табліцаў\n* больш за іншыя сыстэмы схільная да пашкоджаньняў\n* кодавая база MediaWiki не заўсёды належна апрацоўвае MyISAM\n\nВашае ўсталяваньне MySQL не падтрымлівае InnoDB, магчыма, час для абнаўленьня.",
        "config-mysql-engine-help": "'''InnoDB''' — звычайна найбольш слушны варыянт, таму што добра падтрымлівае паралелізм.\n\n'''MyISAM''' можа быць хутчэйшай у вікі з адным удзельнікам, ці толькі для чытаньня.\nБазы зьвестак на MyISAM вядомыя тым, што ў іх зьвесткі шкодзяцца нашмат часьцей за InnoDB.",
        "config-mssql-auth": "Тып аўтэнтыфікацыі:",
        "config-mssql-install-auth": "Абярыце тып аўтэнтыфікацыі, які будзе выкарыстаны для злучэньня з базай зьвестак падчас працэсу ўсталяваньня.\nКалі вы абярэце «{{int:config-mssql-windowsauth}}», будуць выкарыстаныя ўліковыя зьвесткі карыстальніка, пад якім працуе вэб-сэрвэр.",
index e7e59a8..de2f0cb 100644 (file)
        "config-db-web-no-create-privs": "Посочената сметка за инсталацията не разполага с достатъчно права за създаване на нова сметка.\nНеобходимо е посочената сметка вече да съществува.",
        "config-mysql-engine": "Хранилище на данни:",
        "config-mysql-innodb": "InnoDB (препоръчително)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Внимание:</strong> Избрана е MyISAM като система за складиране в MySQL, която не се препоръчва за използване с МедияУики, защото:\n* почти не поддържа паралелност заради заключване на таблиците\n* е по-податлива на повреди в сравнение с други системи\n* кодът на МедияУики не винаги поддържа MyISAM коректно\n\nАко инсталацията на MySQL поддържа InnoDB, силно е препоръчително да се използва тя.\nАко инсталацията на MySQL не поддържа InnoDB, вероятно е време за обновяване.",
-       "config-mysql-only-myisam-dep": "<strong>Внимание:</strong> MyISAM e единственият наличен на тази машина тип на таблиците за MySQL и не е препоръчителен за употреба при МедияУики защото:\n* има слаба поддръжка на конкурентност на заявките, поради закючването на таблиците\n* е много по-податлив на грешки в базите от данни от другите типове таблици\n* кодът на МедияУики не винаги работи с MyISAM както трябва\n\nВашият MySQL не поддържа InnoDB, така че може би е дошло време за актуализиране.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> почти винаги е най-добрата възможност заради навременната си поддръжка.\n\n<strong>MyISAM</strong> може да е по-бърза при инсталации с един потребител или само за четене.\nБазите от данни MyISAM се повреждат по-често от InnoDB.",
        "config-mssql-auth": "Тип на удостоверяването:",
        "config-mssql-install-auth": "Изберете начин за удостоверяване, който ще бъде използван за връзка с базата от данни по време на инсталацията.\nАко изберете \"{{int:config-mssql-windowsauth}}\", ще се използват идентификационните данни на потребителя под който работи уеб сървъра.",
index 2392f73..0debe4a 100644 (file)
@@ -87,7 +87,6 @@
        "config-regenerate": "LocalSettings.php পুনরূত্পাদিত করুন →",
        "config-mysql-engine": "সংগ্রহস্থল ইঞ্জিন:",
        "config-mysql-innodb": "InnoDB (সুপারিশকৃত)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-windowsauth": "উইন্ডোজ প্রমাণীকরণ",
        "config-site-name": "উইকির নাম:",
        "config-site-name-blank": "একটি সাইটের নাম প্রবেশ করান।",
index 93bec19..de6655b 100644 (file)
        "config-db-web-no-create-privs": "Ar gont ho peus diferet evit ar staliañ n'he deus ket gwirioù a-walc'h evit krouiñ ur gont.\nRet eo d'ar gont diferet amañ bezañ anezhi dija.",
        "config-mysql-engine": "Lusker stokañ :",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Diwallit :</strong> Diuzet eo bet ganeoc'h MyISAM evel keflusker stokañ evit MySQL, ar pezh n'eo ket erbedet evit implijout gant MediaWiki, rak :\n* a-boan m'eo skoret gantañ ober meur a dra war un dro peogwir eo prennet an taolennoù\n* techetoc'h eo d'ar gwastoù eget kefluskerioù all\n* kod diazez MediaWiki n'eo ket atav embreget MyISAM gantañ evel m'eo dleet\n\nM'eo skoret InnoDB gant ho staliadur MySQL, ez eo kuzuliet c'hwek deoc'h dibab hennezh kentoc'h.\nMa n'eo ket skoret InnoDB gant ho staliadur MySQL, e c'hallfe bezañ poent deoc'h ober un hizivadenn.",
-       "config-mysql-only-myisam-dep": "<strong>Taolit evezh :</strong> MyISAM eo ar c'heflusker stokañ nemetañ a c'haller ober gantañ war ar mekanik-mañ evit MySQL, padal n'eo ket erbedet e implij gant MediaWiki, rak :\n* a-boan ma skor ar c'hevezerezh abalamour m'eo prennet an taolennoù\n* aesoc'h eo e wastañ eget kefluskerioù all\n* n'eo ket atav embreget MyIsam evel ma tlefe bezañ gant kod diazez MediaWiki\n\nN'eo ket skoret InnoDB gant ho staliadur MySQL. Poent eo hizivaat anezhañ marteze.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> eo an dibab gwellañ koulz lavaret atav, kemer a ra e kont ar monedoù kevezus.\n\n<strong>MyISAM</strong> a c'hall bezañ fonnusoc'h evit ar staliadurioù unpost pe ar re lenn hepken.\nDiazoù roadennoù MyISAM zo techet da vezañ gwastet aliesoc'h eget re InnoDB.",
        "config-mssql-auth": "Seut anaoudadur :",
        "config-mssql-install-auth": "Diuzañ ar seurt dilesa a vo implijet evit kevreañ ouzh an diaz roadennoù e-pad ar staliañ.\nMa tibabit \"{{int:config-mssql-windowsauth}}\", e vo implijet titouroù anaout an implijer a laka ar servijer da dreiñ.",
index e6118f8..50421ab 100644 (file)
        "config-db-web-create": "Napravi račun ako već ne postoji",
        "config-mysql-engine": "Skladišni pogon:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Vrsta autentifikacije:",
        "config-site-name": "Ime wikija:",
        "config-site-name-blank": "Upišite ime sajta.",
index 6fb1bbe..19d6e45 100644 (file)
@@ -38,7 +38,6 @@
        "config-header-oracle": "Oracle settings",
        "config-header-mssql": "Microsoft SQL Server settings",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Ngaran ka wiki",
        "config-site-name-blank": "Ibutang a ngaran ka site.",
        "config-project-namespace": "Bibutangan ka proyekto:",
index 26b33af..d56295b 100644 (file)
@@ -52,7 +52,7 @@
        "config-restart": "Sí, torna a començar",
        "config-welcome": "=== Comprovacions de l'entorn ===\nS'efectuaran comprovacions bàsiques per veure si l'entorn és adequat per a la instal·lació del MediaWiki.\nRecordeu d'incloure aquesta informació si heu de demanar ajuda sobre com completar la instal·lació.",
        "config-welcome-section-copyright": "=== Drets d'autor i condicions ===\n\n$1\n\nAquest programa és de programari lliure; podeu redistribuir-lo i/o modificar-lo sota les condicions de la Llicència Pública General GNU com es publicada per la Free Software Foundation; qualsevol versió 2 de la llicència, o (opcionalment) qualsevol versió posterior.\n\nAquest programa és distribueix amb l'esperança que serà útil, però <strong>sense cap garantia</strong>; sense ni tan sols la garantia implícita de <strong>\ncomerciabilitat</strong> o <strong>idoneïtat per a un propòsit particular</strong>.\nConsulteu la Llicència Pública General GNU, per a més detalls.\n\nHauríeu d'haver rebut [$2 una còpia de la Llicència Pública General GNU] amb aquest programa; si no, escriviu a la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA o [https://www.gnu.org/copyleft/gpl.html per llegir-lo en línia].",
-       "config-sidebar": "* [https://www.mediawiki.org la Pàgina d'inici]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guia de l'usuari]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Guia de l'administrador]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ PMF]\n----\n* <doclink href=Readme>Llegeix-me</doclink>\n* <doclink href=ReleaseNotes>Notes de la versió</doclink>\n* <doclink href=Còpia>Còpia</doclink>\n* <doclink href=UpgradeDoc>Actualització</doclink>",
+       "config-sidebar": "* [https://www.mediawiki.org la Pàgina d'inici]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guia de l'usuari]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Guia de l'administrador]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ PMF]",
        "config-sidebar-readme": "Llegeix-me",
        "config-sidebar-relnotes": "Notes de la versió",
        "config-sidebar-license": "Còpia",
@@ -88,6 +88,7 @@
        "config-uploads-not-safe": "<strong>Avís:</strong> El directori de càrregues per defecte <code>$1</code> és vulnerable a l'execució d'scripts arbitraris.\nEncara que el MediaWiki comprova tots els fitxers que es carreguen davant d'amenaces de seguretat, és molt recomanable [https://www.mediawiki.org/ wiki/Special:MyLanguage/Manual:Security#Upload_security tancar aquesta vulnerabilitat de seguretat] abans d'habilitar les càrregues.",
        "config-no-cli-uploads-check": "<strong>Avís</strong>: no s'ha comprovat el directori per defecte per a càrregues (<code><span class=\"notranslate\">$1</span></code>$) per vulnerabilitats en l'execució arbitrària durant la instal·lació amb la línia d'ordres.",
        "config-brokenlibxml": "El vostre sistema té una combinació de versions de PHP i libxml2 que són problemàtiques i que poden causar corrupció de dades no aparent a MediaWiki i a altres aplicacions web.\nActualitzeu-vos a libxml2 2.7.3 o superior ([https://bugs.php.net/bug.php?id=45996 informe d'error al projecte PHP]).\nS'ha interromput la instal·lació.",
+       "config-using-32bit": "<strong>Avís</strong>: el vostre sistema sembla que s'executa amb enters de 32 bits. Això [https://www.mediawiki.org/wiki/special:MyLanguage/Manual:32-bit no és aconsellable].",
        "config-db-type": "Tipus de base de dades:",
        "config-db-host": "Servidor de la base de dades:",
        "config-db-host-help": "Si el servidor de base de dades és en un servidor diferent, introduïu el nom del servidor o l'adreça IP a continuació.\n\nSi feu servir un hostatge web compartit, el vostre proveïdor us hauria de proporcionar el nom del servidor a la documentació.\n\nSi feu servir MySQL, «localhost» podria no funcionar com a nom de servidor. Si no funciona, proveu «127.0.0.1» com a adreça IP local.\n\nSi feu servir PostgreSQL, deixeu aquest camp en blanc per a connectar-vos a través d'un sòcol Unix.",
        "config-postgres-old": "Cal el PostgreSQL $1 o posterior. Teniu el $2.",
        "config-mssql-old": "Cal utilitzar el Microsoft SQL Server $1 o posterior. Teniu la versió $2.",
        "config-sqlite-name-help": "Trieu un nom per identificar el wiki.\nNo feu servir espais ni guionets.\nAquest nom s’utilitzarà per a denominar el fitxer de les dades de l’SQLite.",
+       "config-sqlite-parent-unwritable-group": "No es pot crear el directori de dades <code><nowiki>$1</nowiki></code>, perquè el directori pare <code><nowiki>$2</nowiki></code> no el pot escriure el servidor web.\n\nL'instal·lador no pot determinar l'usuari amb què s'executa el servidor web.\nFeu el directori <code><nowiki>$3</nowiki></code> escrivible globalment per l'usuari del servidor web (i altres) per continuar.\nEn un sistema Unix/Linux feu:\n\n<pre>cd $2\nmkdir $3\nchgrp $4 $3\nchmod g+w $3</pre>",
+       "config-sqlite-parent-unwritable-nogroup": "No es pot crear el directori de dades <code><nowiki>$1</nowiki></code>, perquè el directori pare <code><nowiki>$2</nowiki></code> no el pot escriure el servidor web.\n\nL'instal·lador no pot determinar l'usuari amb què s'executa el servidor web.\nFeu el directori <code><nowiki>$3</nowiki></code> escrivible globalment per l'usuari del servidor web (i altres) per continuar.\nEn un sistema Unix/Linux feu:\n\n<pre>cd $2\nmkdir $3\nchmod a+w $3</pre>",
        "config-sqlite-mkdir-error": "S'ha produït un error en crear el directori de dades «$1».\nComproveu la ubicació i torneu-ho a provar.",
        "config-sqlite-dir-unwritable": "No s'ha pogut escriure al directori «$1».\nCanvieu els permisos perquè el servidor web pugui escriure-hi i torneu-ho a provar.",
        "config-sqlite-connection-error": "$1. \n\nComproveu el directori de dades i el nom de la base de dades a continuació i torneu-ho a provar.",
        "config-db-web-no-create-privs": "El compte que heu especificat a la instal·lació no té suficients privilegis per crear un compte. El compte que especifiqueu aquí ja ha d'existir.",
        "config-mysql-engine": "Motor d'emmagatzemament:",
        "config-mysql-innodb": "InnoDB (recomanat)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Avís:</strong> Heu seleccionat MyISAM com a motor d'emmagatzemament de MySQL, que no és recomanat per utilitzar amb MediaWiki, perquè:\n* no té un bon suport de concurrència a causa del blocatge de les taules\n* té més tendència a corrompre's que altres motors\n* el codi base de MediaWiki no sempre gestiona MyISAM adequadament\n\nSi la vostra instal·lació de MySQL permet l'ús d'InnoDB, és molt més recomanable que l'utilitzeu.\nSi, per contra, no el permet. Potser val la pena que considereu actualitzar-la.",
-       "config-mysql-only-myisam-dep": "<strong>Avís:</strong> MyISAM és l'únic motor d'emmagatzemament de MySQL d'aquesta màquina, que no és recomanat per utilitzar amb MediaWiki, perquè:\n* no té un bon suport de concurrència a causa del blocatge de les taules\n* té més tendència a corrompre's que altres motors\n* el codi base de MediaWiki no sempre gestiona MyISAM adequadament\n\nLa vostra instal·lació de MySQL no permet l'ús d'InnoDB. Potser val la pena que considereu actualitzar-la.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> és gairebé sempre la millor opció perquè té una bona implementació de concurrència.\n\n<strong>MyISAM</strong> pot ser més ràpid en instal·lacions d'un únic usuari o de només lectura.\nLes bases de dades MyISAM tendeixen a corrompre's més sovint que les InnoDB.",
        "config-mssql-auth": "Tipus d'autenticació:",
        "config-mssql-install-auth": "Seleccioneu el tipus d'autenticació que s'utilitzarà per connectar-se amb el servidor de base de dades durant el procés d'instal·lació.\nSi seleccioneu «{{int:config-mssql-windowsauth}}», s'utilitzaran les credencials de l'usuari amb què s'executa el servidor web.",
        "config-admin-error-password": "S'ha produït un error intern en definir una contrasenya per a l'administrador «<nowiki>$1</nowiki>»: <pre>$2</pre>",
        "config-admin-error-bademail": "Heu introduït una adreça electrònica no vàlida.",
        "config-subscribe": "Subscriu a la [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce llista de correu d'anunci de noves versions].",
+       "config-subscribe-help": "És una llista de poc volum que s'utilitza per fer anuncis de noves versions, incloent-hi aquells de seguretat importants.\nCal que us hi subscriviu i actualitzeu la instal·lació de MediaWiki quan apareguin noves versions.",
        "config-subscribe-noemail": "Us heu provat de subscriure a la llista de correu d'anuncis de noves versions sense proporcionar-hi una adreça electrònica.\nProporcioneu-ne una si voleu subscriure-us a la llista de correu electrònic.",
        "config-pingback": "Comparteix dades d'aquesta instal·lació amb els desenvolupadors de MediaWiki.",
+       "config-pingback-help": "Si seleccioneu aquesta opció, el MediaWiki farà ping periòdicament a https://www.mediawiki.org amb dades bàsiques d'aquesta instància. Les dades inclouen, per exemple, el tipus de sistema, la versió PHP i el sistema de bases de dades que s'utilitza. La Fundació Wikimedia comparteix les dades amb els desenvolupadors de MediaWiki per tal d'ajudar-los a guiar empreses de desenvolupament futures. Les dades següents s'enviaran del vostre sistema:\n<pre>$1</pre>",
        "config-almost-done": "Gairebé ja heu acabat!\nPodeu ometre el que queda de la configuració i procedir amb la instal·lació del wiki.",
        "config-optional-continue": "Fes-me més preguntes.",
        "config-optional-skip": "Ja estic avorrit. Simplement instal·leu el wiki.",
index 7c72530..aef912c 100644 (file)
        "config-db-web-no-create-privs": "Účet uvedený pro instalaci nemá oprávnění dostatečná pro založení nového účtu.\nÚčet, který zde uvedete, již musí existovat.",
        "config-mysql-engine": "Typ úložiště:",
        "config-mysql-innodb": "InnoDB (doporučeno)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Upozornění:</strong> Jako typ úložiště pro MySQL jste zvolili MyISAM, které není pro použití v MediaWiki doporučeno, neboť:\n* stěží podporuje současný přístup kvůli zamykání tabulek,\n* je náchylnější na poškození dat než jiná úložiště,\n* kód MediaWiki nepodporuje MyISAM vždy tak dobře, jak by měl.\n\nPokud vaše instalace MySQL podporuje InnoDB, důrazně doporučujeme použít spíše to.\nPokud vaše instalace MySQL InnoDB nepodporuje, možná je čas na aktualizaci.",
-       "config-mysql-only-myisam-dep": "<strong>Upozornění:</strong> Jediným dostupným úložištěm dat pro MySQL je MyISAM, který se k užití s MediaWiki nedoporučuje, neboť:\n* téměř nepodporuje paralelní přístup kvůli zamykání tabulek,\n* oproti jiným formátům je náchylnější k poškození,\n* MediaWiki nepodporuje MyISAM tak dobře, jak by bylo třeba.\n\nVaše instalace MySQL nepodporuje InnoDB, možná je na čase upgradovat.",
        "config-mysql-engine-help": "'''InnoDB''' je téměř vždy nejlepší volba, neboť má dobrou podporu současného přístupu.\n\n'''MyISAM''' může být rychlejší u instalací pro jednoho uživatele nebo jen pro čtení.\nDatabáze MyISAM bývají poškozeny častěji než databáze InnoDB.",
        "config-mssql-auth": "Typ autentizace:",
        "config-mssql-install-auth": "Zvolte si typ autentizace, který se bude používat pro připojení k databázi v průběhu instalace.\nPokud zvolíte možnost „{{int:config-mssql-windowsauth}}“, použijí se přihlašovací údaje uživatele, pod kterým běží webový server.",
index f7df024..38bb36b 100644 (file)
@@ -39,7 +39,6 @@
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] je wjinstalowóny",
        "config-diff3-bad": "Felënk GNU diff3.",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Miono wiki:",
        "config-site-name-blank": "Wpiszë miono starnów.",
        "config-ns-other-default": "MòjôWiki",
index 3798468..8924964 100644 (file)
@@ -69,7 +69,6 @@
        "config-sqlite-cant-create-db": "Kunne ikke oprette databasefilen <code>$1</code>.",
        "config-db-web-create": "Opret kontoen hvis den ikke allerede findes",
        "config-mysql-innodb": "InnoDB (anbefalet)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-windowsauth": "Windows-godkendelse",
        "config-site-name": "Navn på wiki:",
        "config-site-name-blank": "Indtast et hjemmesidenavn.",
index b2c16c5..bdf1c6f 100644 (file)
        "config-db-web-no-create-privs": "Das angegebene und für den Installationsvorgang vorgesehene Datenbankkonto verfügt nicht über ausreichend Berechtigungen, um ein weiteres Datenbankkonto zu erstellen.\nDas hier angegebene Datenbankkonto muss daher bereits vorhanden sein.",
        "config-mysql-engine": "Datenbanksystem:",
        "config-mysql-innodb": "InnoDB (empfohlen)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Warnung:</strong> Es wurde MyISAM als Speichersubsystem für das Datenbanksystem MySQL ausgewählt. Aus folgenden Gründen wird es nicht für den Einsatz mit MediaWiki empfohlen:\n* Es unterstützt aufgrund von Tabellensperrungen kaum die nebenläufige Ausführung von Aktionen.\n* Es ist anfälliger für Datenprobleme.\n* Es wird von MediaWiki nicht immer adäquat unterstützt.\n\nSofern die vorhandene MySQL-Installation das Speichersubsystem InnoDB unterstützt, wird deren Verwendung eindringlich empfohlen.\nSofern sie es nicht unterstützt, sollte nunmehr eine entsprechende Aktualisierung in Erwägung gezogen werden.",
-       "config-mysql-only-myisam-dep": "<strong>Warnung:</strong> MyISAM ist das einzige verfügbare Speichersubsystem für das Datenbanksystem MySQL auf diesem Server. Es wird nicht für die Verwendung mit MediaWiki empfohlen, da es\n* aufgrund von Tabellensperrungen kaum die nebenläufige Ausführung von Aktionen unterstützt,\n* anfälliger für Datenprobleme ist und\n* von MediaWiki nicht immer adäquat unterstützt wird.\n\nDeine MySQL-Installation unterstützt nicht das Speichersubsystem InnoDB. Eine Aktualisierung wird nunmehr empfohlen.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> als Speichersubsystem für das Datenbanksystem MySQL ist fast immer die bessere Wahl, da es gleichzeitige Zugriffe gut unterstützt.\n\n<strong>MyISAM</strong> als Speichersubsystem für das Datenbanksystem MySQL ist hingegen in Einzelnutzerumgebungen oder bei schreibgeschützten Wikis schneller.\nDatenbanken, die MyISAM verwenden, sind indes tendenziell fehleranfälliger als solche, die InnoDB verwenden.",
        "config-mssql-auth": "Authentifikationstyp:",
        "config-mssql-install-auth": "Wähle den Authentifikationstyp aus, der zur Verbindung mit der Datenbank während des Installationsprozesses verwendet wird.\nFalls du „{{int:config-mssql-windowsauth}}“ auswählst, werden die Anmeldeinformationen eines beliebigen Benutzers verwendet, der den Webserver ausführt.",
index 21c7249..d596784 100644 (file)
@@ -58,7 +58,6 @@
        "config-missing-db-server-oracle": "\"{{int:config-db-host-oracle}}\" rë jew erc gerek keno",
        "config-mysql-engine": "Motorë depok kerdışi",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-sqlauth": "SQL Server araştnayış",
        "config-mssql-windowsauth": "Windows kamiye araştnayış",
        "config-site-name": "Namey wiki:",
index 21a0e7d..97b4fd3 100644 (file)
        "config-db-web-create": "Να δημιουργηθεί ο λογαριασμός αν δεν υπάρχει ήδη",
        "config-mysql-engine": "Μηχανή αποθήκευσης:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-mysql-engine-help": "Το <strong>InnoDB</strong> είναι σχεδόν πάντα η καλύτερη επιλογή, αφού έχει καλή υποστήριξη ταυτόχρονης λειτουργίας.\n\nΤο <strong>MyISAM</strong> μπορεί να είναι ταχύτερο σε εγκαταστάσεις του ενός χρήστη ή μόνο ανάγνωσης. \nΟι βάσεις δεδομένων MyISAM τείνουν να φθείρονται συχνότερα από τις βάσεις δεδομένων InnoDB.",
        "config-mssql-auth": "Τύπος ελέγχου ταυτότητας:",
        "config-mssql-sqlauth": "Έλεγχος ταυτότητας του SQL Server",
index 6d52241..3f83612 100644 (file)
@@ -75,7 +75,6 @@
        "config-regenerate": "Refari dosieron LocalSettings.php →",
        "config-mysql-engine": "Konservada modulo:",
        "config-mysql-innodb": "InnoDB (rekomendata)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Speco de aŭtentokontrolo:",
        "config-mssql-sqlauth": "Aŭtentokontrolo de Microsoft SQL-Servilo",
        "config-mssql-windowsauth": "Aŭtentokontrolo de Windows",
index c1f393a..5e3d3a1 100644 (file)
        "config-db-web-no-create-privs": "La cuenta que has especificado para la instalación no tiene privilegios suficientes para crear una cuenta.\nLa cuenta que especifiques aquí ya debe existir.",
        "config-mysql-engine": "Motor de almacenamiento:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Atención:</strong> has seleccionado MyISAM como motor de almacenamiento de MySQL, el cual no está recomendado para usarse con MediaWiki, porque:\n* apenas admite la concurrencia debido al bloqueo de tablas\n* es más propenso a daños que otros motores\n* el código MediaWiki no siempre controla MyISAM como debería\n\nSi tu instalación de MySQL admite InnoDB, es muy recomendable que lo elijas en su lugar.\nSi tu instalación de MySQL no admite InnoDB, quizás es el momento de una modernización.",
-       "config-mysql-only-myisam-dep": "<strong>Advertencia:</strong> solo se ha encontrado el motor de almacenamiento MyISAM para MySQL en esta máquina, y no se recomienda su uso con MediaWiki, porque:\n* apenas admite la concurrencia debido al bloqueo de tablas\n* es más propenso a daños que otros motores\n* el código de MediaWiki no siempre controla MyISAM como debería\n\nTu instalación de MySQL no admite InnoDB; quizás es el momento de una actualización.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> es casi siempre la mejor opción, dado que soporta bien los accesos simultáneos.\n\n<strong>MyISAM</strong> puede ser más rápido en instalaciones con usuario único o de sólo lectura.\nLas bases de datos MyISAM tienden a corromperse más a menudo que las bases de datos InnoDB.",
        "config-mssql-auth": "Tipo de autenticación:",
        "config-mssql-install-auth": "Selecciona el tipo de autenticación que se utilizará para conectarse a la base de datos durante el proceso de instalación.\nSi seleccionas \"{{int:config-mssql-windowsauth}}\", se usarán las credenciales del usuario con el que se ejecuta el servidor web.",
index 21c7fe2..4e004f9 100644 (file)
        "config-db-web-no-create-privs": "Zehaztu duzun kontuak ez dauka pribilegio nahikoak kontu bat sortzeko.\nZehaztu duzun kontua existitu behar da.",
        "config-mysql-engine": "Biltegiratze motorea:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Oharra:</strong> MyISAM MySQL biltegiratze-motor gisa aukeratu duzu, MediaWikirekin erabiltzeko gomendagarria ez dena honengatik:\n*taula blokeoak direla-eta gauza gutxi onartu ohi du\n*beste motore batzuek baino ustelkeria gehiago izateko aukerak ditu\n*MediaWiki-ren kode baseak ez du beti kudeatzen MyISAM behar bezala\n\nZure MySQL instalazioa InnoDB onartzen badu, hori aukeratzeko gomendatzen da.\nZure MySQL instalazioa InnoDB ez badu onartzen, baliteke bertsioa berritzeko ordua izatea.",
-       "config-mysql-only-myisam-dep": "<strong> Oharra: </strong> MyISAM makinaren MySQL biltegiratze motarako bakarra da, eta hau ez da MediaWiki-rekin erabiltzeko gomendatzen, honengatik:\n* maiztasunez taula blokeoek konkurrentzia ez dute onartzen \n* Beste motore batzuek baino ustelkeria gehiago izaten dute\n* MediaWiki-ren kodekak ez du beti kudeatzen MyISAM behar bezala\n\nZure MySQL instalazioak ez du InnoDB onartzen, agian bertsio berritzeko ordua da.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> ia beti aukerarik onena da, konkurrentzia-laguntza ona duelako.\n\n<strong>MyISAM</strong> erabiltzaile bakarreko edo irakurketa bakarreko instalazioetan azkarragoa izan daiteke.\nMyISAM datu-basea gehiagokotan hondatuta ageri da InnoDB datu-baseareakin baino.",
        "config-mssql-auth": "Autentifikazio mota:",
        "config-mssql-install-auth": "Aukeratu instalazio prozesuan zehar datu-basera konektatzeko erabiliko den autentifikazio mota.\n\"{{Int: config-mssql-windowsauth}}\" hautatzen baduzu, web zerbitzariak duen edozein erabiltzailek erabiliko duen kredentziala erabiliko da.",
index 43f4c93..7cac681 100644 (file)
        "config-db-web-no-create-privs": "حسابی که شما برای نصب تعیین کردید،مزایای کافی برای ایجاد یک حساب را ندارد.\nحسابی که شما اینجا تعیین کرده‌اید باید در حال حاضر وجود داشته باشد.",
        "config-mysql-engine": "موتور ذخیره سازی:",
        "config-mysql-innodb": "اینودی‌بی (پیشنهاد می‌شود)",
-       "config-mysql-myisam": "می‌ای‌سم",
-       "config-mysql-myisam-dep": "'''هشدار:''' شما مای‌آی‌اس‌ای‌ام را به عنوان موتور ذخیره برای مای‌آی‌اس‌ای‌ام انتخاب کرده‌اید، که برای استفاده با مدیاویکی توصیه نمی‌شود زیرا:\n* به‌علت قفل شدن جدول اجمالاً به طور همزمان پشتیبانی می کند\n* بیشتر از دیگر موتورها برای از بین‌ رفتن مستعد است.\n* مبنای رمز مدیاویکی همیشه مای‌آی‌اس‌ای‌ام را همان طور که باید باشد،کنترل نمی‌کند\nاگر نصب مای‌اس‌کیو‌ال شما اینودی‌بی را پشتیبانی می‌کند،بسیار توصیه می‌شود  که در عوض ،آن را انتخاب کنید.\nاگر نصب مای‌اس‌کیو‌ال شما، اینودی‌بی را پشتیبانی نمی‌کند، ممکن است زمان ارتقاء رسیده باشد.",
-       "config-mysql-only-myisam-dep": "'''هشدار:''' مای‌آی‌اس‌ای‌ام تنها موتور ذخیره‌سازی اطلاعات برای مای‌اس‌کیو‌ال در این دستگاه است، و برای استفاده با مدیاویکی توصیه نمی‌شود، زیرا:\n* به‌علت قفل شدن جدول اجمالاً به طور همزمان پشتیبانی می کند\n* بیشتر از دیگر موتورها برای از بین‌ رفتن مستعد است.\n* مبنای رمز مدیاویکی همیشه مای‌آی‌اس‌ای‌ام را همان طور که باید باشد،کنترل نمی‌کند\nنصب مای‌اس‌کیو‌ال شما اینودی‌بی را پشتیبانی نمی‌کند،ممکن است زمان یک ارتقاء رسیده باشد.",
        "config-mysql-engine-help": "'''اینودی‌بی''' تقریباً همیشه بهترین گزینه است،زیرا پشتیبانی همزمان خوبی دارد.\n'''مای‌آی‌اس‌ای‌ام''' ممکن است در نصب‌های کاربر جداگانه یا فقط خواندنی سریع‌تر باشد.\nپایگاه‌های اطلاعاتی مای‌آی‌اس‌ای‌ام اغلب بیشتر از پایگاه‌های اطلاعاتی اینودی‌بی مستعد ازبین رفتن هستند.",
        "config-mssql-auth": "نوع تأیید:",
        "config-mssql-install-auth": "نوع تأییدی را که برای اتصال به پایگاه اطلاعاتی حین فرآیند نصب مورد استفاده قرار گیرد را انتخاب کنید.\nاگر \"{{int:config-mssql-windowsauth}}\" را انتخاب می‌کنید، اعتبارات هرآنچه کاربر وب سرور به عنوان آن  مورد استفاده قرار می‌دهد مورد استفاده قرار خواهد گرفت.",
index 16ee054..8c338f8 100644 (file)
        "config-db-web-no-create-privs": "Tilillä jota käytetään asennuksessa ei ole oikeuksia luoda uutta tiliä.\nTähän määriteltävä tili täytyy olla jo olemassa.",
        "config-mysql-engine": "Tallennusmoottori",
        "config-mysql-innodb": "InnoDB (suositeltu)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Varmennuksen tyyppi:",
        "config-mssql-install-auth": "Valitse varmennuksen tyyppi, jota käytetään yhdistäessä tietokantaan asennuksen aikana.\nJos valitset \"{{int:config-mssql-windowsauth}}\", käytetään verkkopalvelimen käyttäjän kirjautumistietoja.",
        "config-mssql-web-auth": "Valitse varmennuksen tyyppi, jota verkkopalvelin käyttää yhdistäessään tietokantapalvelimeen wikin tavallisen toiminnan aikana.\nJos valitset \"{{int:config-mssql-windowsauth}}\", käytetään verkkopalvelimen käyttäjän kirjautumistietoja.",
index aa37a12..b07c83e 100644 (file)
        "config-db-web-no-create-privs": "Le compte que vous avez spécifié pour l'installation n'a pas de privilèges suffisants pour créer un compte.\nLe compte que vous spécifiez ici doit déjà exister.",
        "config-mysql-engine": "Moteur de stockage :",
        "config-mysql-innodb": "InnoDB (recommandé)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong> Avertissement </strong>: vous avez sélectionné MyISAM comme moteur de stockage pour MySQL, ce qui n’est pas recommandé pour une utilisation avec MediaWiki, parce que :\n * il prend à peine en charge la simultanéité en raison de verrouillage de table\n * il est plus sujet à la corruption que les autres moteurs\n * le code de base MediaWiki ne gère pas toujours MyISAM comme il se doit\n\nSi votre installation MySQL prenden charge InnoDB, il est fortement recommandé que vous le choisissiez plutôt. \nSi votre installation MySQL ne prend pas en charge les tables InnoDB, il est peut-être temps de faire une mise à niveau.",
-       "config-mysql-only-myisam-dep": "<strong>Attention :</strong> MyISAM est le seul moteur de stockage disponible pour MySQL sur cette machine, et cela n’est pas recommandé pour une utilisation avec MédiaWiki, car :\n* il prend très peu en charge les accès concurrents à cause du verrouillage des tables\n* il est plus sujet à corruption que les autres moteurs\n* le code de base de MédiaWiki ne gère pas toujours MyISAM comme il faudrait\n\nVotre installation MySQL ne prend pas en charge InnoDB ; il est peut-être temps de la mettre à jour.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> est presque toujours la meilleure option, car il prend bien en charge les accès concurrents.\n\n<strong>MyISAM</strong> peut être plus rapide dans les installations monoposte ou en lecture seule.\nLes bases de données MyISAM ont tendance à se corrompre plus souvent que les bases d’InnoDB.",
        "config-mssql-auth": "Type d’authentification :",
        "config-mssql-install-auth": "Sélectionner le type d’authentification qui sera utilisé pour se connecter à la base de données pendant le processus d’installation.\nSi vous sélectionnez « {{int:config-mssql-windowsauth}} », les informations d’identification de l’utilisateur faisant tourner le serveur seront utilisées.",
index c0e86f7..7126f90 100644 (file)
@@ -49,7 +49,6 @@
        "config-invalid-db-type": "Type de base de données non valide",
        "config-sqlite-name-help": "Choisir un nom qui identifie ton wiki.\nFait user pas ni d'espaces ni des traits d'union\nIl va user pour fichier de données SQLite.",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Nom du wiki:",
        "config-ns-generic": "Projet",
        "config-ns-other-default": "MonWiki",
index 033692a..bc35fc2 100644 (file)
@@ -67,7 +67,6 @@
        "config-db-web-create": "Féte lo compto s’ègziste p’oncor",
        "config-mysql-engine": "Motor de stocâjo :",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Nom du vouiqui :",
        "config-site-name-blank": "Buchiéd un nom de seto.",
        "config-project-namespace": "Èspâço de noms du projèt :",
index a6aa77c..c75d129 100644 (file)
@@ -7,7 +7,8 @@
                        "Vivaelcelta",
                        "Macofe",
                        "Banjo",
-                       "Seb35"
+                       "Seb35",
+                       "Maria zaos"
                ]
        },
        "config-desc": "O programa de instalación de MediaWiki",
@@ -47,7 +48,7 @@
        "config-help-restart": "Quere eliminar todos os datos gardados e reiniciar o proceso de instalación?",
        "config-restart": "Si, reiniciala",
        "config-welcome": "=== Comprobación da contorna ===\nCómpre realizar agora unhas comprobacións básicas para ver se a contorna é axeitada para a instalación de MediaWiki.\nLembre incluír esta información se necesita axuda para completar a instalación.",
-       "config-welcome-section-copyright": "=== Dereitos de autor e termos de uso ===\n\n$1\n\nEste programa é software libre; pode redistribuílo e/ou modificalo segundo os termos da licenza pública xeral GNU publicada pola Free Software Foundation; versión 2 ou (na súa escolla) calquera outra posterior.\n\nEste programa distribúese coa esperanza de que poida ser útil, pero <strong>sen garantía ningunha</strong>; nin sequera a garantía implícita de <strong>comercialización</strong> ou <strong>adecuación a unha finalidade específica</strong>.\nOlle a licenza pública xeral GNU para obter máis detalles.\n\nDebería recibir [$2 unha copia da licenza pública xeral GNU] xunto ao programa; se non é así, escriba á Free Software Foundation, Inc., rúa Franklin, número 51, quinto andar, Boston, Massachusetts, 02110-1301, Estados Unidos de América ou [https://www.gnu.org/copyleft/gpl.html lea a licenza en liña].",
+       "config-welcome-section-copyright": "=== Dereitos de autoría e termos de uso ===\n\n$1\n\nEste programa é software libre; pode redistribuílo e/ou modificalo segundo os termos da licenza pública xeral GNU publicada pola Free Software Foundation; versión 2 ou (na súa escolla) calquera outra posterior.\n\nEste programa distribúese coa esperanza de que poida ser útil, pero <strong>sen garantía ningunha</strong>; nin sequera a garantía implícita de <strong>comercialización</strong> ou <strong>adecuación a unha finalidade específica</strong>.\nOlle a licenza pública xeral GNU para obter máis detalles.\n\nDebería recibir [$2 unha copia da licenza pública xeral GNU] xunto ao programa; se non é así, escriba á Free Software Foundation, Inc., rúa Franklin, número 51, quinto andar, Boston, Massachusetts, 02110-1301, Estados Unidos de América ou [https://www.gnu.org/copyleft/gpl.html lea a licenza en liña].",
        "config-sidebar": "* [https://www.mediawiki.org/wiki/MediaWiki/gl Páxina principal de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guía de usuario]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Guía de administrador]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Preguntas máis frecuentes]\n----\n* <doclink href=Readme>Léame</doclink>\n* <doclink href=ReleaseNotes>Notas de lanzamento</doclink>\n* <doclink href=Copying>Copia</doclink>\n* <doclink href=UpgradeDoc>Actualizacións</doclink>",
        "config-env-good": "Rematou a comprobación da contorna.\nPode instalar MediaWiki.",
        "config-env-bad": "Rematou a comprobación da contorna.\nNon pode instalar MediaWiki.",
        "config-db-web-no-create-privs": "A conta que especificou para a instalación non ten os privilexios suficientes para crear unha conta.\nA conta que se especifique aquí xa debe existir.",
        "config-mysql-engine": "Motor de almacenamento:",
        "config-mysql-innodb": "InnoDB (recomendado)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Atención:</strong> Seleccionou MyISAM como o motor de almacenamento para MySQL, unha combinación non recomendada para MediaWiki, porque:\n* practicamente non soporta os accesos simultáneos debido ao bloqueo de táboas\n* é máis propenso a corromperse ca outros motores\n* o código base de MediaWiki non sempre manexa o MyISAM como debera\n\nSe a súa instalación MySQL soporta InnoDB, recoméndase elixilo no canto de MyISAM.\nSe a súa instalación MySQL non soporta InnoDB, quizais sexa boa idea realizar unha actualización.",
-       "config-mysql-only-myisam-dep": "<strong>Atención:</strong> MyISAM é o único motor de almacenamento para MySQL nesta máquina, unha combinación non recomendada para MediaWiki, porque:\n* practicamente non soporta os accesos simultáneos debido ao bloqueo de táboas\n* é máis propenso a corromperse ca outros motores\n* o código base de MediaWiki non sempre manexa o MyISAM como debera\n\nA súa instalación MySQL non soporta InnoDB, quizais sexa boa idea realizar unha actualización.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> é case sempre a mellor opción, dado que soporta ben os accesos simultáneos.\n\n<strong>MyISAM</strong> é máis rápido en instalacións de usuario único e de só lectura.\nAs bases de datos MyISAM tenden a se corromper máis a miúdo ca as bases de datos InnoDB.",
        "config-mssql-auth": "Tipo de autenticación:",
        "config-mssql-install-auth": "Seleccione o tipo de autenticación que se utilizará para conectarse á base de datos durante o proceso de instalación.\nSe selecciona \"{{int:config-mssql-windowsauth}}\", usaranse as credenciais do usuario co que se está a executar o servidor web.",
index 5b954c9..7d361bc 100644 (file)
        "config-db-web-no-create-privs": "לחשבון שהקלדת להתקנה אין מספיק הרשאות ליצירת חשבון.\nהחשבון שאתם מקלידים כאן צריך להיות קיים.",
        "config-mysql-engine": "מנוע האחסון:",
        "config-mysql-innodb": "InnoDB (מומלץ)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''אזהרה''': בחרתם ב־MyISAM בתור מנוע אחסון של MySQL, וזה לא מומלץ מהסיבות הבאות:\n* המנוע הזה בקושי תומך בעיבוד מקבילי בגלל נעילת טבלאות\n* הוא פחות עמיד בפני אובדן מידע ממנועים אחרים\n* הקוד של מדיה־ויקי לא תמיד מטפל ב־MyISAM כפי שצריך\n\nאם התקנת MySQL שלכם תומכת ב־InnoDB, מומלץ מאוד שתבחרו באפשרות הזאת.\nאם התקנת MySQL שלכם אינה תומכת ב־InnoDB, אולי זה הזמן לשקול לשדרג אותה.",
-       "config-mysql-only-myisam-dep": "'''אזהרה:''' MyISAM הוא מנוע האחסון היחיד שזמין ל־MySQL במכונה הזאת, וזה לא מומלץ לשימוש עם מדיה־ויקי, כי:\n* הוא כמעט שאינו תומך בחיבורים מרובים בגלל נעילת טבלאות\n* הוא פגיע יותר לקלקול ממנועים אחרים\n* הקוד של מדיה־ויקי לא תמיד מטפל ב־MyISAM כפי שצריך\n\nהתקנת MySQL אינה תומכת ב־InnoDB, ואולי הגיע הזמן לשדרג אותה.",
        "config-mysql-engine-help": "'''InnoDB''' היא כמעט תמיד האפשרות הטובה ביותר, כי במנוע הזה יש תמיכה טובה ביותר בעיבוד מקבילי.\n\n'''MyISAM''' עשוי להיות בהתקנות שמיועדות למשתמש אחד ולהתקנות לקריאה בלבד.\nמסדי נתונים עם MyISAM נוטים להיהרס לעתים קרובות יותר מאשר מסדי נתונים עם InnoDB.",
        "config-mssql-auth": "סוג אימות:",
        "config-mssql-install-auth": "נא לבחור את סוג האימות שישמש להתחברות למסד הנתונים בזמן תהליך ההתקנה. בחירה ב־\"{{int:config-mssql-windowsauth}}\" תשתמש בהרשאות של החשבון שמריץ את השרת הנוכחי.",
index 33e5ec9..1914600 100644 (file)
        "config-db-web-no-create-privs": "Das oongebne und für den Installationsvoargang voargesiehne Datebankkonto verfücht nwt üwer ausreichend Berechtichunge, um en weitres Datebankkonto zu erstelle.\nDas hier oongebne Datebankkonto muss dohear bereits voarhand sin.",
        "config-mysql-engine": "Speicher-Engine:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Warnung:''' Es woard MyISAM als Speicher-Engine für MySQL ausgewählt, die aus follichend Gründe net für den Insatz mit MediaWiki rekommendiert ist:\n* Sie unnerstützt uffgrund von Tabellesperrunge koom die neweloofiche Ausführung von Aktione.\n* Sie ist oonfällicher für Dateprobleme.\n* Sie weard von MediaWiki net immer adäquat unnerstützt.\n\nSoweit die voarhandne MySQL-Installation die Speicher-Engine InnoDB unnerstützt, weard sei Verwennung eindringlich rekommendiert.\nSoweit sie sie net unnerstützt, sollt en entsprechend Aktualisierung nunmeahr Erwächung gezoh sin.",
-       "config-mysql-only-myisam-dep": "'''Warnung:''' MyISAM ist die einziche verfüchbare Speicher-Engine für MySQL uff dem Rechner, und das weard net für die Verwennung mit MediaWiki rekommendiert, weil sie\n* uffgrund von Tabellesperrunge koom die neweloofiche Ausführung von Aktione unnerstützt,\n* oonfällicher für Dateprobleme ist und\n* von MediaWiki net immer adäquat unnerstützt weard.\n\nDein MySQL-Installation unnerstützt net InnoDB. Eventuell muss en Aktualisierung dorrichgeführt werre.",
        "config-mysql-engine-help": "'''InnoDB''' ist nächst immer die bessre Wähl, weil es gleichzeitiche Zugriffe gut unnerstützt.\n\n'''MyISAM''' ist in Enzelnutzerumgebunge sowie bei schreibgeschützte Wikis schneller.\nBei MyISAM-Datebanke treten tendenziell häuficher Fehler uff als bei InnoDB-Datebanke.",
        "config-mssql-auth": "Authentifikationstyp:",
        "config-mssql-install-auth": "Wähl den Authentifikationstyp aus, der zur Verbinnung mit der Datebank während von der Installationsprozesses verwennt weard.\nFalls du „{{int:config-mssql-windowsauth}}“ auswählst, werre die Oonmeldeinformatione von en beliebiche Benutzer verwennt, wo den Webserver ausführt.",
index f2b2a7f..5a5f109 100644 (file)
        "config-db-web-no-create-privs": "Konto, kotrež sy za instalaciju podał, nima dosć woprawnjenjow, zo by konto wutworiło.\nKonto, kotrež tu podawaće, dyrbi hižo eksistować.",
        "config-mysql-engine": "Składowanska mašina:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Mjeno wikija:",
        "config-site-name-help": "To zjewi so w titulowej lejstwje wobhladaka kaž tež na wšelakich druhich městnach.",
        "config-site-name-blank": "Zapodaj sydłowe mjeno.",
index f6bca7b..fed6854 100644 (file)
        "config-db-web-no-create-privs": "A telepítéshez megadott fiók nem rendelkezik megfelelő jogosultságokkal új felhasználó létrehozásához.\nAz itt megadott fióknak léteznie kell.",
        "config-mysql-engine": "Tárolómotor:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Figyelmeztetés''': A MyISAM tárolómotort választottad, ami nem ajánlott a MediaWiki használatánál, mert:\n* nagyon rosszul kezeli a párhuzamos lekéréseket a táblák zárolása miatt\n* sokkal nagyobb az esélye az adatkorrupció kialakulásának\n* a MediaWiki kódbázisa nem mindig úgy kezeli a MyISAM-ot, ahogyan kellene\n\nHa a feltelepített MySQL támogatja az InnoDB-t, erősen ajánlott, hogy inkább azt válaszd.\nHa nem, akkor lehet, hogy itt az ideje a frissítésnek.",
        "config-mysql-engine-help": "A legtöbb esetben az '''InnoDB''' a legjobb választás, mivel megfelelően támogatja a párhuzamosságot.\n\nA '''MyISAM''' gyorsabb megoldás lehet egyfelhasználós vagy csak olvasható környezetekben, azonban a MyISAM-adatbázisok sokkal gyakrabban sérülnek meg, mint az InnoDB-adatbázisok.",
        "config-mssql-auth": "Hitelesítés típusa:",
        "config-mssql-sqlauth": "SQL Server hitelesítés",
index 626d15d..9e08055 100644 (file)
        "config-db-web-no-create-privs": "Le conto que tu specificava pro installation non ha sufficiente privilegios pro crear un conto.\nLe conto que tu specifica hic debe jam exister.",
        "config-mysql-engine": "Motor de immagazinage:",
        "config-mysql-innodb": "InnoDB (recommendate)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "* '''Attention:''' Tu ha seligite MyISAM como motor de immagazinage pro MySQL, lo que non es recommendate pro uso con MediaWiki, perque:\n* illo a pena supporta le processamento simultanee a causa del blocada le tabulas\n* illo es plus susceptibile al corruption que altere motores\n* le base de codice de MediaWiki non sempre manea MyISAM como illo deberea\n\nSi tu installation de MySQL supporta InnoDB, es multo recommendate que tu selige iste in su loco.\nSi tu installation de MySQL non supporta InnoDB, forsan isto es un bon occasion pro actualisar lo.",
-       "config-mysql-only-myisam-dep": "'''Attention:''' MyISAM es le unic motor de immagazinage disponibile pro MySQL in iste machina, ma isto non es recommendate pro le uso con MediaWiki, perque:\n* a pena supporto le accesso simultanee a causa del blocage de tabellas\n* es plus propense a corrumper se que altere motores\n* le codice base de MediaWiki non sempre gere MyISAM como deberea\n\nTu installation de MySQL non supporta InnoDB; forsan il es tempore de actualisar lo.",
        "config-mysql-engine-help": "'''InnoDB''' es quasi sempre le melior option, post que illo ha bon supporto pro simultaneitate.\n\n'''MyISAM''' pote esser plus rapide in installationes a usator singule o a lectura solmente.\nLe bases de datos MyISAM tende a esser corrumpite plus frequentemente que le base de datos InnoDB.",
        "config-mssql-auth": "Typo de authentication:",
        "config-mssql-install-auth": "Selige le typo de authentication a usar pro connecter al base de datos durante le processo de installation.\nSi tu selige \"{{int:config-mssql-windowsauth}}\", le credentiales del usator que executa le servitor web essera usate.",
index 792b7bc..2a98729 100644 (file)
@@ -15,7 +15,8 @@
                        "Macofe",
                        "Rachmat.Wahidi",
                        "Gombang",
-                       "Rachmat04"
+                       "Rachmat04",
+                       "ArlandGa"
                ]
        },
        "config-desc": "Penginstal untuk MediaWiki",
@@ -55,7 +56,7 @@
        "config-help-restart": "Apakah Anda ingin menghapus semua data tersimpan yang telah Anda masukkan dan mengulang proses instalasi?",
        "config-restart": "Ya, nyalakan ulang",
        "config-welcome": "=== Pengecekan lingkungan ===\nPengecekan dasar kini akan dilakukan untuk melihat apakah lingkungan ini memadai untuk instalasi MediaWiki.\nIngatlah untuk menyertakan informasi ini jika Anda mencari bantuan tentang cara menyelesaikan instalasi.",
-       "config-welcome-section-copyright": "=== Hak cipta dan persyaratan ===\n\n$1\n\nProgram ini adalah perangkat lunak bebas; Anda dapat mendistribusikan dan/atau memodifikasi di bawah persyaratan GNU General Public License seperti yang diterbitkan oleh Free Software Foundation; baik versi 2 lisensi, atau (sesuai pilihan Anda) versi yang lebih baru.\n\nProgram ini didistribusikan dengan harapan bahwa itu akan berguna, tetapi <strong>tanpa jaminan apa pun</strong>; bahkan tanpa jaminan tersirat untuk <strong>dapat diperjualbelikan</strong> atau <strong>sesuai untuk tujuan tertentu</strong>.\nLihat GNU General Public License untuk lebih jelasnya.\n\nAnda seharusnya telah menerima [$2 salinan dari GNU General Public License] bersama dengan program ini; jika tidak, kirimkan surat untuk Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, atau [https://www.gnu.org/copyleft/gpl.html baca versi daring].",
+       "config-welcome-section-copyright": "=== Hak cipta dan persyaratan ===\n\n$1\n\nProgram ini adalah perangkat lunak bebas; Anda dapat mendistribusikan dan/atau memodifikasinya di bawah persyaratan GNU General Public License seperti yang diterbitkan oleh Free Software Foundation; baik versi 2 lisensi, atau (sesuai pilihan Anda) versi yang lebih baru.\n\nProgram ini didistribusikan dengan harapan bahwa itu akan berguna, tetapi <strong>tanpa jaminan apa pun</strong>; bahkan tanpa jaminan tersirat untuk <strong>dapat diperjualbelikan</strong> atau <strong>sesuai untuk tujuan tertentu</strong>.\nLihat GNU General Public License untuk lebih jelasnya.\n\nAnda seharusnya telah menerima [$2 salinan dari GNU General Public License] bersama dengan program ini; jika tidak, kirimkan surat untuk Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, atau [https://www.gnu.org/copyleft/gpl.html baca versi daring].",
        "config-sidebar": "* [https://www.mediawiki.org/wiki/MediaWiki/id Situs MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents/id Pedoman Pengguna]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents/id Pedoman Administrator]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/id FAQ]\n----\n* <doclink href=Readme>Read me</doclink>\n* <doclink href=ReleaseNotes>Release notes</doclink>\n* <doclink href=Copying>Copying</doclink>\n* <doclink href=UpgradeDoc>Upgrading</doclink>",
        "config-env-good": "Kondisi telah diperiksa.\nAnda dapat menginstal MediaWiki.",
        "config-env-bad": "Kondisi telah diperiksa.\nAnda tidak dapat menginstal MediaWiki.",
        "config-db-web-no-create-privs": "Akun Anda berikan untuk instalasi tidak memiliki hak yang cukup untuk membuat akun.\nAkun yang Anda berikan harus sudah ada.",
        "config-mysql-engine": "Mesin penyimpanan:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Peringatan:</strong> Anda telah memilih MyISAM sebagai mesin penyimpanan MySQL, yang tidak dianjurkan untuk digunakan dengan MediaWiki, karena:\n * nyaris tidak mendukung operasi bersamaan karena penguncian tabel\n * lebih rentan terhadap korupsi daripada mesin lain\n * basis kode MediaWiki tidak selalu menangani MyISAM sebagaimana mestinya\n\nJika instalasi MySQL Anda mendukung InnoDB, sangat disarankan bagi Anda memilih itu.\nJika instalasi MySQL tidak mendukung InnoDB, mungkin sudah waktunya untuk pemutakhiran.",
-       "config-mysql-only-myisam-dep": "<strong>Peringatan:</strong> MyISAM adalah satu-satunya mesin penyimpanan yang tersedia untuk MySQL pada mesin ini, dan hal ini tidak dianjurkan untuk digunakan dengan MediaWiki, karena:\n* hampir tidak mendukung konkurensi karena penguncian tabel\n* basis kode MediaWiki tidak selalu menangani MyISAM sebagaimana mestinya\n\nInstalasi MySQL Anda tidak mendukung InnoDB, mungkin sudah waktunya untuk peningkatan.",
        "config-mysql-engine-help": "'''InnoDB''' hampir selalu merupakan pilihan terbaik karena memiliki dukungan konkurensi yang baik.\n\n'''MyISAM''' mungkin lebih cepat dalam instalasi pengguna-tunggal atau hanya-baca.\nBasis data MyISAM cenderung lebih sering rusak daripada basis data InnoDB.",
        "config-mssql-auth": "Jenis otentikasi:",
        "config-mssql-install-auth": "Pilih jenis otentikasi yang akan digunakan untuk menyambung ke database selama proses instalasi.\nJika Anda memilih \"{{int:config-mssql-windowsauth}}\", kredensial dari pengguna apapun pada server web yang berjalan akan digunakan.",
index e7688dc..fac0ad7 100644 (file)
@@ -56,7 +56,6 @@
        "config-header-oracle": "Ajusti por Oracle-sistemo:",
        "config-header-mssql": "Ajusti por Microsoft SQL Server",
        "config-invalid-db-type": "Nevalida tipo di datumaro.",
-       "config-mysql-myisam": "MyISAM",
        "config-ns-generic": "Projeto",
        "config-ns-site-name": "Sama kam la wiki-nomo: $1",
        "config-ns-other": "Altra (definez precise)",
index 0ea1522..59c2317 100644 (file)
@@ -62,7 +62,6 @@
        "config-db-web-account": "Gagnagrunnsreikningur fyrir vefaðgang",
        "config-mysql-engine": "Gagnagrunnshýsing:",
        "config-mysql-innodb": "InnoDB (mælt með)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Tegund auðkenningar:",
        "config-mssql-sqlauth": "SQL Server auðkenning",
        "config-mssql-windowsauth": "Windows auðkenning",
index 3d08343..165a057 100644 (file)
        "config-db-web-no-create-privs": "L'account usato per l'installazione non dispone dei privilegi necessari per creare un altro account.\nL'account indicato qui deve già esistere.",
        "config-mysql-engine": "Storage engine:",
        "config-mysql-innodb": "InnoDB (consigliato)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Attenzione:</strong> hai selezionato MyISAM come motore di archiviazione per MySQL, che non è raccomandato per l'uso con  MediaWiki, perché:\n* supporta debolmente la concorrenza per il blocco della tabella\n* è più incline alla corruzione di altri motori\n* il codice di base MediaWiki non gestisce sempre MyISAM come dovrebbe\n\nSe la tua installazione MySQL supporta InnoDB, è altamente raccomandato che lo si scelga al suo posto.\nSe la tua installazione MySQL non supporta InnoDB, forse è il momento per un aggiornamento.",
-       "config-mysql-only-myisam-dep": "<strong>Attenzione:</strong> MyISAM è l'unico motore di archiviazione disponibile per MySQL su questa macchina, e questo non è consigliato per l'uso con MediaWiki, perché:\n* supporta debolmente la concorrenza per il blocco della tabella\n* è più incline alla corruzione di altri motori\n* il codice di base MediaWiki non gestisce sempre MyISAM come dovrebbe\n\nSe la tua installazione MySQL non supporta InnoDB, forse è il momento per un aggiornamento.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> è quasi sempre l'opzione migliore, in quanto ha un buon supporto della concorrenza.\n\n<strong>MyISAM</strong> potrebbe essere più veloce nelle installazioni monoutente o in sola lettura.\nI database MyISAM tendono a danneggiarsi più spesso dei database InnoDB.",
        "config-mssql-auth": "Tipo di autenticazione:",
        "config-mssql-install-auth": "Seleziona il tipo di autenticazione che verrà utilizzato per connettersi al database durante il processo di installazione.\nSe si seleziona \"{{int:config-mssql-windowsauth}}\", saranno utilizzate le credenziali dell'utente con cui viene eseguito il server web, qualunque esso sia.",
index a7bad28..9516433 100644 (file)
        "config-db-web-no-create-privs": "あなたがインストールのために定義したアカウントは、アカウント作成のための特権としては不充分です。\nあなたがここで指定したアカウントは既に存在している必要があります。",
        "config-mysql-engine": "ストレージ エンジン:",
        "config-mysql-innodb": "InnoDB(推奨)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>警告:</strong> MySQLのストレージエンジンとして MyISAM を選択していますが、これをMediaWikiで利用するのは推奨されていません。その理由は: \n* テーブルロックによる並列性をほとんどサポートしていない\n* 他のエンジンに比べて壊れやすい\n* MediaWiki のコードベースは必ずしも MyISAM を本来あるべきほどには扱っていない\n\nあなたがインストールした MySQL が InnoDB をサポートしている場合、代わりにそちらをお使いになることを強くお勧めします。\nあなたがインストールした MySQL が InnoDB をサポートしていない場合、アップグレードした方がいいでしょう。",
-       "config-mysql-only-myisam-dep": "<strong>警告:</strong> MyISAM がこのマシンの MySQL の唯一のストレージエンジンですが、これをMediaWikiで利用するのは推奨されていません。その理由は: \n* テーブルロックによる並列性をほとんどサポートしていない\n* 他のエンジンに比べて壊れやすい\n* MediaWiki のコードベースは必ずしも MyISAM を本来あるべきほどには扱っていない\n\nあなたがインストールした MySQL が InnoDB をサポートしていない場合、アップグレードした方がいいでしょう。",
        "config-mysql-engine-help": "<strong>InnoDB</strong>は、並行処理のサポートに優れているので、ほとんどの場合において最良の選択肢です。\n\n<strong>MyISAM</strong>は、利用者が1人の場合、あるいは読み込み専用でインストールする場合に、より処理が早くなるでしょう。\nただし、MyISAMのデータベースは、InnoDBより高頻度で破損する傾向があります。",
        "config-mssql-auth": "認証の種類:",
        "config-mssql-install-auth": "インストール過程でデータベースに接続するために使用する認証の種類を選択してください。\n「{{int:config-mssql-windowsauth}}」を選択した場合、ウェブサーバーを実行しているユーザーの認証情報が使用されます。",
index 856fa6f..9c4c3fb 100644 (file)
@@ -46,7 +46,6 @@
        "config-invalid-db-type": "არასწორი მონაცემთა ბაზის ტიპი",
        "config-sqlite-readonly": "ფაილი <code>$1</code> ჩასაწერად მიუწვდომელია.",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "ვიკის სახელი:",
        "config-site-name-blank": "შეიყვანეთ ვებ-გვერდის სახელი.",
        "config-project-namespace": "პროექტის სახელთა სივრცე:",
index 9dc815e..a891d19 100644 (file)
        "config-db-web-no-create-privs": "설치를 위해 지정한 계정이 계정을 만들 수 있는 충분한 권한이 없습니다.\n여기서 지정한 계정은 이미 존재해야 합니다.",
        "config-mysql-engine": "저장소 엔진:",
        "config-mysql-innodb": "InnoDB (권장)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>경고:</strong> MySQL을 위한 저장소 엔진으로 MyISAM을 선택하였습니다. MyISAM을 미디어위키에 사용하는 것은 좋지 않습니다.  이유는:\n* 테이블 잠금 때문에 동시 실행을 지원하지 않습니다\n* 다른 엔진보다 더 손상되는 경향이 있습니다\n* 미디어위키 코드베이스가 항상 정상적으로 MyISAM을 처리하지 않습니다\n\nMySQL이 InnoDB를 지원한다면, InnoDB를 선택할 것을 매우 권장합니다.\nMySQL이 InnoDB를 지원하지 않는다면, 업그레이드를 하시는 편이 좋습니다.",
-       "config-mysql-only-myisam-dep": "<strong>경고:</strong> MyISAM은 이 기계에  유일하게 사용할 수 있는 MySQL용 저장소 엔진이며, 미디어위키에 사용하는 것은 좋지 않습니다. 이유는:\n* 테이블 잠금 때문에 동시 실행을 지원하지 않습니다\n* 다른 엔진보다 더 손상시키는 경향이 있습니다\n* 미디어위키 코드베이스가 항상 정상적으로 MyISAM을 처리하지 않습니다\n\n당신의 MySQL은 InnoDB를 지원하지 않으며, 업그레이드를 하는 것이 좋습니다.",
        "config-mysql-engine-help": "<strong>InnoDB</strong>는 동시 실행 지원이 우수하기 때문에 대부분의 경우 최고의 옵션입니다.\n\n<strong>MyISAM</strong>은 단일 사용자나 읽기 전용 설치에서 더 빠를 수 있습니다.\nMyISAM 데이터베이스는 InnoDB 데이터베이스보다 더 자주 손실될 수 있습니다.",
        "config-mssql-auth": "인증 형식:",
        "config-mssql-install-auth": "설치 과정 중 데이터베이스에 연결하는 데 사용할 인증 형식을 선택하세요.\n\"{{int:config-mssql-windowsauth}}\"을 선택하시면 웹서버를 실행 중인 아무 사용자의 자격 증명이 사용됩니다.",
index 7be04d1..2a23c6d 100644 (file)
        "config-db-web-no-create-privs": "Dä Zohjang för et Opsäze es nit berääschtesch, ene ander Zohjan enzereeschte.\nDä aanjejovve Zohjang för der Nomaalbedrief moß dröm schunn enjersht sen!",
        "config-mysql-engine": "De Zoot udder et Fommaat vun de Tabälle:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Opjepaß:''' <i lang=\"en\">MyISAM</i> es als Speicher för <i lang=\"en\">MySQL</i> nit besönders joot för et Zosammeschpell met MediaWiki zo bruche:\n* Dorj_et kumplätte Sperre vun Tabälle, künne koum ens Saache parrallel en dä Daatebangk jedonn wääde.\n* Dat Fomaat es anfällesch för Probleme met de Daate.\n* Et weed vun MediaWiki nit ėmmer zopaß ongerschtöz.\n\nWann Ding <i lang=\"en\">MySQL</i> et Schpeischere en <i lang=\"en\">InnoDB</i>-Datteije ongerschtöze deiht, dom_mer dat nohdröcklesch ämfähle.\nKann dä ẞööver dat nit, künnd et joode jelääjeheit sin, dä ens op der neuste Schtand ze bränge.",
-       "config-mysql-only-myisam-dep": "'''Opjepaß:''' <i lang=\"en\" xml:lang=\"en\">MyISAM</i> es de einzeje Zoot Schpeischerprojramm för <i lang=\"en\" xml:lang=\"en\">MySQL</i> op dä Maschiin. Di es nit för MediaWiki ze ämfähle es, weil:\n* wääje dem Schpärre vun jannze Tabälle sin koum paralleele Axjuhne en dä Daatebangk möjjelesch,\n* ed es aanfällesch för Probleeme met de Daate es, un\n* et weed vun MediaWiki nit emmer jood ongerschtöz.\n\nDing Enschtallazjuhn vum <i lang=\"en\" xml:lang=\"en\">MySQL</i> kann nit met <i lang=\"en\" xml:lang=\"en\">InnoDB</i> ömjonn.\nWi wöhr et med ene neuere Väsjohn vum <i lang=\"en\" xml:lang=\"en\">MySQL</i>?",
        "config-mysql-engine-help": "<strong>InnoDB</strong> es fö jewöhnlesch et beß, weil vill Zohjreffe op eijmohl joot ongershtöz wääde.\n\n<strong>MyISAM</strong> es flöcker op Rääschnere met bloß einem Minsch draan, un bei Wikis, di mer bloß lässe un nit schrieeve kann.\nMyISAM-Daatebangke han em Schnett mih Fähler un jon flöcker kappott, wi InnoDB-Daatebangke.",
        "config-mssql-auth": "De Zoot Aanmäldong:",
        "config-mssql-install-auth": "Söhk us, wi dat Aanmälde aan dä Daatebangk vor sesch jonn sull för de Enschtallazjuhn.\nWann De <em>{{int:Config-mssql-windowsauth}}</em> nemms, weed jenumme, met wat emmer dä Wäbßööver aam loufe es.",
index 11b662e..231271c 100644 (file)
@@ -40,7 +40,6 @@
        "config-sqlite-readonly": "Dosyeya <code>$1</code> ne nivîsbar e.",
        "config-db-web-account": "Hesabê danegehê bô têgihiştina tora înternetê",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Navê wîkiyê:",
        "config-site-name-blank": "Navê malperek têkeve.",
        "config-ns-generic": "Proje",
index 5cd5344..e6e12f1 100644 (file)
        "config-db-web-account-same": "Dee selwechte Kont wéi bei der Installatioun benotzen",
        "config-db-web-create": "De Kont uleeë wann et e net scho gëtt",
        "config-mysql-innodb": "InnoDB (recommandéiert)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Typ vun der Authentifikatioun:",
        "config-mssql-sqlauth": "SOL-Server-Authentifikatioun",
        "config-mssql-windowsauth": "Windows-Authentifikatioun",
index a018ac7..d555bc7 100644 (file)
        "config-db-web-no-create-privs": "L'account doeuviou pe l'installaçion o no dispon-e di privileggi necessai pe creâ un atro account.\nL'account indicou chì o deve za existe.",
        "config-mysql-engine": "Motô d'archiviaçion:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Atençion:</strong> t'hæ seleçionou MyISAM comme motô d'archiviaçion pe MySQL, ch'o no l'è racomandou pe l'uso con  MediaWiki, percose:\n* o supporta debolmente a concorença pe-o blocco da tabella\n* o l'è ciu inclinou a-a corruçion di atri motoî\n* o codiçe de base MediaWiki o no gestisce sempre MyISAM comm'o doviæ\n\nSe a to instalaçion MySQL a supporta InnoDB, l'è atamente racomandou che ti o çerni a-o so posto.\nSe a to installaçion MySQL a no supporta InnoDB, foscia l'è o momento pe 'n agiornamento.",
-       "config-mysql-only-myisam-dep": "<strong>Atençion:</strong> MyISAM o l'è l'unnico motô d'archiviaçion disponibbile pe MySQL insce sta macchina, e questo no l'è consegiou pe doeuviâlo con MediaWiki, percose:\n* o supporta debolmente a concorenza pe-o blocco da tabella\n* o l''è ciu inclinou a-a corruçion di atri motoî\n* o coddiçe de base MediaWiki MyISAM  o no-o gestisce sempre comm'o doviæ\n\nS'a to installaçion MySQL a no supporta InnoDB, foscia l'è o momento pe 'n agiornamento.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> o l'è quæxi sempre a megio opçion, in quante o g'ha 'n bon supporto da concorença.\n\n<strong>MyISAM</strong> o poriæ vese ciu veloçe inte installaçioin mono-utente ò in sola-lettua.\nI database MyISAM tendan a dannezâse ciu soventi di database InnoDB.",
        "config-mssql-auth": "Tipo d'aotenticaçion:",
        "config-mssql-install-auth": "Seleçion-a o tipo d'aotenticaçion ch'o saiâ doeuviou pe conettise a-o database durante o processo de instalaçion.\nSe ti seleçion-i \"{{int:config-mssql-windowsauth}}\", saiâ doeuviou e credençiæ de quæ se segge utente segge aproeuv'a fâ giâ o serviou web.",
index fcb39df..a4c524b 100644 (file)
@@ -99,7 +99,6 @@
        "config-db-web-create": "Sukurti paskyrą, jeigu jos nėra",
        "config-mysql-engine": "Saugojimo variklis:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Autentifikavimo tipas:",
        "config-mssql-sqlauth": "SQL Serverio autentifikavimas",
        "config-mssql-windowsauth": "Windows autentifikavimas",
index e744495..675e3db 100644 (file)
@@ -43,7 +43,6 @@
        "config-header-oracle": "Oracle iestatījumi",
        "config-header-mssql": "Microsoft SQL servera iestatījumi",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-windowsauth": "Windows Autentifikācija",
        "config-ns-generic": "Projekts",
        "config-ns-site-name": "Tāds pats kā viki nosaukums: $1",
index 8d80e21..a3d824b 100644 (file)
@@ -60,7 +60,6 @@
        "config-header-mssql": "Parametatry ny lohamilina Microsoft SQL Server",
        "config-invalid-db-type": "Karazana banky angona tsy ekena.",
        "config-mysql-innodb": "innoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-ns-generic": "Tetikasa",
        "config-ns-other": "Hafa (lazao)",
        "config-admin-name": "Ny anaranao :",
index 446a12d..e652683 100644 (file)
        "config-db-web-no-create-privs": "Сметката што ја назначивте за воспоставка нема доволно привилегии за да може да создаде сметка.\nТука мора да назначите постоечка сметка.",
        "config-mysql-engine": "Складишен погон:",
        "config-mysql-innodb": "InnoDB (препорачано)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Предупредување:''' Го одбравте MyISAM како складишен погон за MySQL. Но тој не се препорачува за МедијаВики бидејќи:\n* одвај поддржува едновременост поради заклучување на табелите\n* поподложен на расипување од другите погони\n* кодната база на МедијаВики не секогаш може да работи со MyISAM како што треба\n\nАко вашата воспоставка на MySQL поддржува InnoDB, тогаш сериозно препорачуваме да го користите него наместо MyISAM.\nАко вашата воспоставка на MySQL не поддржува InnoDB, веројатно дошло време за надградба.",
-       "config-mysql-only-myisam-dep": "'''Предупредување:''' MyISAM е единствениот достапен складишен погон за MySQL на оваа машина, а ова не се препорачува за употреба со МедијаВики, бидејќи:\n* речиси не поддржува истовремено извршување на задачите поради заклучувањето на табелите\n* поподложен е на расипувања од другите погони\n* кодната база на МедијаВИки не секогаш работи исправно со MyISAM\nВашата воспоставка на MySQL не поддржува InnoDB. Можеби е време да ја надградите.",
        "config-mysql-engine-help": "'''InnoDB''' речиси секогаш е најдобар избор, бидејќи има добра поддршка за едновременост.\n\n'''MyISAM''' може да е побрз кај воспоставките наменети за само еден корисник или незаписни воспоставки (само читање).\nБазите на податоци од MyISAM почесто се расипуваат од базите на InnoDB.",
        "config-mssql-auth": "Тип на заверка:",
        "config-mssql-install-auth": "Изберете го типот на заверка што ќе се користи за поврзување со базата на податоци во текот на воспоставката.\nАко изберете „{{int:config-mssql-windowsauth}}“, ќе се користат најавните податоци или корисникот како кој работи мрежниот опслужувач.",
index d466362..1163486 100644 (file)
@@ -96,8 +96,6 @@
        "config-db-web-create": "Ciptakan akaun jika belum wujud",
        "config-mysql-engine": "Enjin storan:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-only-myisam-dep": "<strong>Amaran:</strong> MyISAM ialah satu-satunya enjin storan yang terdapat untuk MySQL di mesin ini, dan penggunaannya dengan MediaWiki tidak digalakkan kerana:\n* ia tidak menyokong keserempakan (''concurrency'') disebabkan penguncian jadual\n* ia lebih terdedah kepada korupsi daripada enjin-enjin lain\n* pangkalan kod MediaWiki tidak sentiasa mengendalikan MyISAM seperti yang diharapkan\n\nPemasangan MySQL anda tidak menyokong InnoDB. Mungkin tiba masanya untuk naik taraf.",
        "config-mssql-auth": "Jenis pengesahan:",
        "config-site-name": "Nama wiki:",
        "config-site-name-help": "Ini akan dipaparkan pada bar tajuk perisian pelayar dan tempat-tempat lain yang berkenaan.",
index c4cd28b..dae1280 100644 (file)
@@ -41,7 +41,6 @@
        "config-db-schema": "Skema għal MediaWiki:",
        "config-db-web-create": "Oħloq il-kont jekk għadu ma jeżistix",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Isem tal-wiki:",
        "config-site-name-help": "Dan se jidher fil-barra tat-titlu tal-browżer u f'diversi postijiet oħra.",
        "config-site-name-blank": "Daħħal isem tas-sit.",
index d4ae472..5379e8d 100644 (file)
        "config-db-web-no-create-privs": "'O cunto ausato pe' ne fà l'installazione nun tene diritte necessarie pe' ne putè crià n'atu cunto.\n'O cunto zegnàto ccà adda esistere già.",
        "config-mysql-engine": "Mutore d'astipo:",
        "config-mysql-innodb": "InnoDB (fosse 'o cunzigliato)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Attenziò:</strong> avite scigliuto MyISAM comm' 'o mutore 'archiviaziona MySQL, ca nun è raccummannato pe' l'ausà cu MediaWiki, pecché:\n* supporta debolmente 'a concorrenza p' 'o blocco d' 'a tabbella\n* è cchiù inchine 'a corruzione 'e l'ati mutore\n* 'o codece 'e base 'e MediaWiki nun gestisce sempe MyISAM comme l'avess'a gistiunà\n\nSi ll'installazione vosta MySQL suppuorta InnoDB, è autamente raccummandato ca si scigliesse a 'o posto suo.\nSi 'a installazione MySQL nun suppurtasse InnoDB, forse è 'o mumento 'e ll'agghiurnà.",
-       "config-mysql-only-myisam-dep": "<strong>Attenziò:</strong> MyISAM è l'uneco mutore p'astipà date ca se trova mo' a disposizione p' 'o MySQL dint'a sta macchina, e nun fosse raccumandato 'e s'ausà cu MediaWiki, pecché:\n* suppurtasse minimamente concorrenza pe' bbìa 'e bluccà tabbelle\n* è cchiù facile ca jesse a se scassà cchiù 'e l'ati mutore\n* 'o codece MediaWiki nun maniasse sempe MyISAM comme l'avesse 'e manià\n\nL'installazione MySQL nun suppurtasse InnoDB, può darse ca chist'è 'o mumento pe' ve ll'agghiurnà.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> è quase sempe 'a meglia opzione, pecché ave nu buono suppuorto concorrente.\n\n<strong>MyISAM</strong> putesse ghì cchiù ampressa int'a na installazione mono-utente e liegge-surtanto.\n'E database MyISAM se scassano cchiù spisso d' 'e database InnoDB.",
        "config-mssql-auth": "Tipo d'autenticazione:",
        "config-mssql-install-auth": "Sceglie 'o tipo d'autenticazziona ca s'ausarrà pe cunnettà â database, durante ll'operazziona d'istallazziona. Si piglie \"{{int:config-mssql-windowsauth}}\", 'e credenziale 'e qualunque fosse ll'utenza ca 'o webserver sta pruciessanno sarranno ausate.",
index 699cd0f..522294f 100644 (file)
        "config-db-web-no-create-privs": "Kontoen du oppga for installasjonen har ikke nok privilegier til å opprette en konto.\nKontoen du oppgir her må finnes allerede.",
        "config-mysql-engine": "Lagringsmotor:",
        "config-mysql-innodb": "InnoDB (anbefalt)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Advarsel:''' Du har valgt MyISAM som lagringsmotor for MySQL, noe som ikke er anbefalt for bruk med MediaWiki, fordi:\n* den knapt støtter samtidighet pga. tabell-låsing\n* den har større tilbøyelighet for å bli korrupt enn andre motorer\n* MediaWiki-koden håndterer ikke alltid MyISAM som den burde\n\nHvis din MySQL-installasjon støtter InnoDB, er det sterkt å anbefale at du i stedet velger den.\nHvis din MySQL-installasjon ikke støtter InnoDB, kan det være på tide med en oppgradering.",
-       "config-mysql-only-myisam-dep": "'''Advarsel:''' MyISAM er den eneste tilgjengelig lagringsmotoren for MySQL på denne maskinen, og det er ikke anbefalt brukt for MediaWiki, fordi:\n* den knapt støtter samtidighet pga. tabell-låsing\n* den har større tilbøyelighet for å bli korrupt enn andre motorer\n* MediaWiki-koden håndterer ikke alltid MyISAM som den burde\n\nHvis din MySQL-installasjon ikke støtter InnoDB, kan det være på tide med en oppgradering.",
        "config-mysql-engine-help": "'''InnoDB''' er nesten alltid det beste alternativet siden den har god støtte for samtidighet («concurrency»).\n\n'''MyISAM''' kan være raskere i enbruker- eller les-bare-installasjoner.\nMyISAM-databaser har en tendens til å bli ødelagt oftere enn InnoDB-databaser.",
        "config-mssql-auth": "Autentiseringstype:",
        "config-mssql-install-auth": "Valg autentiseringstypen som skal brukes for å koble til databasen under installeringsprosessen. Hvis du velger «{{int:config-mssql-windowsauth}}», vil påloggingsinformasjonen for brukeren som kjører webtjeneren blir brukt.",
index 1ef41d2..3450712 100644 (file)
@@ -44,7 +44,6 @@
        "config-upgrade-done": "Het bijwerken is afgerond.\n\nJe kunt [$1 je wiki nu gebruiken].\n\nAls je je <code>LocalSettings.php</code> opnieuw wilt aanmaken, klik dan op de knop hieronder.\nDit is '''niet aan te raden''' tenzij je problemen hebt met je wiki.",
        "config-upgrade-done-no-regenerate": "Het bijwerken is afgerond.\n\nJe kunt nu [$1 je wiki gebruiken].",
        "config-db-web-no-create-privs": "Het account dat je voor installatie hebt opgegeven, heeft niet voldoende rechten om een account aan te maken.\nHet account dat je hier opgeeft, moet al bestaan.",
-       "config-mysql-myisam-dep": "'''Waarschuwing''': je hebt MyISAM geselecteerd als opslagengine voor MySQL. Dit is niet aan te raden voor MediaWiki omdat:\n* het nauwelijks ondersteuning biedt voor gebruik door meerdere gebruikers tegelijkertijd door het locken van tabellen;\n* het meer vatbaar is voor corruptie dan andere engines;\n* de code van MediaWiki niet alstijd omgaat met MyISAM zoals dat zou moeten.\n\nAls je installatie van MySQL InnoDB ondersteunt, gebruik dat dan vooral.\nAls je installatie van MySQL geen ondersteuning heeft voor InnoDB, denk dan na over upgraden.",
        "config-project-namespace-help": "In het kielzog van Wikipedia beheren veel wiki's hun beleidspagina's apart van hun inhoudelijke pagina's in een \"'''projectnaamruimte'''\".\nAlle paginanamen in deze naamruimte beginnen met een bepaald voorvoegsel dat je hier kunt opgeven.\nDit voorvoegsel wordt meestal afgeleid van de naam van de wiki, maar het kan geen bijzondere tekens bevatten als \"#\" of \":\".",
        "config-admin-name": "Je naam:",
        "config-admin-password-mismatch": "De twee door jou ingevoerde wachtwoorden komen niet overeen.",
index a17f6f9..23835cd 100644 (file)
        "config-db-web-no-create-privs": "Het account dat u voor de installatie hebt opgegeven, heeft niet voldoende rechten om een account aan te maken.\nHet account dat u hier opgeeft, moet al bestaan.",
        "config-mysql-engine": "Opslagmethode:",
        "config-mysql-innodb": "InnoDB (aanbevolen)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Waarschuwing''': u hebt MyISAM geselecteerd als opslagengine voor MySQL. Dit is niet aan te raden voor MediaWiki omdat:\n* het nauwelijks ondersteuning biedt voor gebruik door meerdere gebruikers tegelijkertijd door het locken van tabellen;\n* het meer vatbaar is voor corruptie dan andere engines;\n* de code van MediaWiki niet alstijd omgaat met MyISAM zoals dat zou moeten.\n\nAls uw installatie van MySQL InnoDB ondersteunt, gebruik dat dan vooral.\nAls uw installatie van MySQL geen ondersteuning heeft voor InnoDB, denk dan na over upgraden.",
-       "config-mysql-only-myisam-dep": "'''Waarschuwing:''' MyISAM is enige beschikbare opslagmethode voor MySQL in deze omgeving, en deze wordt niet aangeraden voor gebruik met MediaWiki, omdat:\n* er nauwelijks ondersteuning is voor meerdere gelijktijdige transacties omdat tabellen op slot gezet worden;\n* tabellen makkelijker stuk kunnen gaan;\n* de code van MediaWiki niet altijd op de juiste wijze omgaat met MyISAM.\n\nUw installatie van MySQL heeft geen ondersteuning voor InnoDB. We raden u aan om een meer recente versie te gebruiken.",
        "config-mysql-engine-help": "'''InnoDB''' is vrijwel altijd de beste instelling, omdat deze goed omgaat met meerdere verzoeken tegelijkertijd.\n\n'''MyISAM''' is bij een zeer beperkt aantal gebruikers mogelijk sneller, of als de wiki alleen-lezen is.\nMyISAM-databases raken vaker beschadigd dan InnoDB-databases.",
        "config-mssql-auth": "Authenticatietype:",
        "config-mssql-install-auth": "Selecteer de authenticatiemethode die wordt gebruikt om met de database te verbinden tijdens het installatieproces.\nAls u \"{{int:config-mssql-windowsauth}}\" selecteert, dan worden de aanmeldgegevens van de gebruiker waaronder de webserver draait voor authenticatie gebruikt.",
index 7a99bb8..3aaecb5 100644 (file)
@@ -91,7 +91,6 @@
        "config-db-web-create": "Creatz lo compte se existís pas ja",
        "config-mysql-engine": "Motor d'emmagazinatge :",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Tipe d’autentificacion :",
        "config-mssql-sqlauth": "Autentificacion de SQL Server",
        "config-mssql-windowsauth": "Autentificacion Windows",
index 6a518c7..6fdcd82 100644 (file)
@@ -35,7 +35,6 @@
        "config-header-oracle": "Oracle-azetukset",
        "config-header-mssql": "Microsoft SQL Server azetukset",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Wikin nimi:",
        "config-site-name-blank": "Kirjuta sivun nimi.",
        "config-project-namespace": "Projektan nimitila:",
index a65dbe2..feda6b2 100644 (file)
        "config-db-web-no-create-privs": "Konto podane do wykonania instalacji nie ma wystarczających uprawnień, aby utworzyć nowe konto.\nKonto, które wskazałeś tutaj musi już istnieć.",
        "config-mysql-engine": "Silnik przechowywania",
        "config-mysql-innodb": "InnoDB (zalecane)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Ostrzeżenie''': wybrano MyISIAM jako silnik  składowania danych MySQL, co nie jest zalecane do użytku w MediaWiki, ponieważ:\n * ledwo obsługuje współbieżnośći ze względu na blokowanie tabel\n * jest bardziej podatna na uszkodzenie niż inne silniki\n * kod źródłowy MediaWiki nie zawsze obsługuje MyISAM tak, jak powinien\n\nJeśli instalacja MySQL obsługuje InnoDB, jest wysoce zalecane, by to je wybrać.\nJeśli instalacja MySQL nie obsługuje InnoDB, być może nadszedł czas na jej uaktualnienie.",
-       "config-mysql-only-myisam-dep": "'''Ostrzeżenie:''' MyISAM jest jedynym dostępnym na tym komputerze mechanizmem składowania dla MySQL, który jednak nie jest zalecany do używania z MediaWiki, ponieważ:\n* słabo obsługuje współbieżność z powodu blokowania tabel\n* jest bardziej skłonny do uszkodzeń niż inne silniki\n* kod MediaWiki nie zawsze traktuje MyISAM jak powinien\n\nTwoja instalacja MySQL nie obsługuje InnoDB, być może jest to czas na aktualizację.",
        "config-mysql-engine-help": "'''InnoDB''' jest prawie zawsze najlepszą opcją, ponieważ posiada dobrą obsługę współbieżności.\n\n'''MyISAM''' może być szybsze w instalacjach pojedynczego użytkownika lub tylko do odczytu.\nBazy danych MyISAM mają tendencję do ulegania uszkodzeniom częściej niż bazy InnoDB.",
        "config-mssql-auth": "Typ uwierzytelniania:",
        "config-mssql-install-auth": "Wybierz typ uwierzytelniania, który będzie używany do łączenia się z bazą danych w trakcie procesu instalacji.\nJeśli wybierzesz „{{int:config-mssql-windowsauth}}”, będą wykorzystywane dane konta użytkownika, pod którym działa serwer www.",
index 08678ae..b6ab572 100644 (file)
        "config-db-web-no-create-privs": "Ël cont ch'a l'ha specificà për l'instalassion a l'ha pa basta 'd privilegi për creé un cont.\nËl cont ch'a spessìfica ambelessì a dev già esiste.",
        "config-mysql-engine": "Motor ëd memorisassion:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Avis''': A l'ha selessionà MyISAM com motor ëd memorisassion për MySQL, che a l'é pa arcomandà da dovré con MediaWiki, përchè:\n* a sopòrta a pen-a la contemporanità për via ëd saradure ëd tàula\n* a l'é pi soget a la corussion che j'àutri motor\n* ël còdes bas ëd MediaWiki pa sempe a gestiss MyISAM com a dovrìa\n\nSe soa istalassion MySQL a manten InnoDB, a l'é fortement arcomandà ch'a serna pitòst col-lì.\nSe soa istalassion MySQL a manten nen InnoDB, a peul esse ch'a sia ël moment ëd n'agiornament.",
        "config-mysql-engine-help": "'''InnoDB''' a l'é scasi sempe la mej opsion, da già ch'a l'ha un bon manteniment dla concorensa.\n\n'''MyISAM''' a peul esse pi lest an instalassion për n'utent sol o mach an letura.\nLa base ëd dàit MyISAM a tira a corompse pi 'd soens che la base ëd dàit InnoDB.",
        "config-site-name": "Nòm ëd la wiki:",
        "config-site-name-help": "Sòn a comparirà ant la bara dël tìtol dël navigador e an vàire d'àutri pòst.",
index 041e021..5d1cc8f 100644 (file)
        "config-db-web-no-create-privs": "A conta que você especificou para a instalação não possui privilégios suficientes para criar uma conta.\nA conta que for especificada aqui já deve existir.",
        "config-mysql-engine": "Mecanismo de armazenamento:",
        "config-mysql-innodb": "InnoDB (recomendado)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Aviso:</strong> Você selecionou MyISAM como mecanismo de armazenamento para o MySQL, o que não é recomendado para uso com o MediaWiki, porque:\n* dificilmente suporta concorrência devido ao bloqueio da tabela\n* é mais propenso à corrupção do que outros motores\n*a base de código MediaWiki nem sempre lida com o MyISAM como deveria\n\nSe sua instalação MySQL suportar o InnoDB, é altamente recomendável que você escolha ele.\nSe sua instalação MySQL não suportar o InnoDB, talvez seja hora de uma atualização.",
-       "config-mysql-only-myisam-dep": "<strong>Aviso:</strong> O MyISAM é o único mecanismo de armazenamento disponível para o MySQL nesta máquina e isso não é recomendado para uso com o MediaWiki, porque:\n* dificilmente suporta concorrência devido ao bloqueio da tabela\n* é mais propenso à corrupção do que outros motores\n*a base de código MediaWiki nem sempre lida com o MyISAM como deveria\n\nA sua instalação no MySQL não suporta InnoDB, talvez seja hora de uma atualização.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> é quase sempre a melhor opção, uma vez que possui um bom suporte de concorrência.\n\n<strong>MyISAM</strong> pode ser mais rápido em instalações de usuário único ou somente leitura.\\O banco de dados MyISAM tendem a ficar corrompidos mais frequentemente do que os bancos de dados InnoDB.",
        "config-mssql-auth": "Tipo de autenticação:",
        "config-mssql-install-auth": "Selecione o tipo de autenticação que será usado para se conectar ao banco de dados durante o processo de instalação.\nSe você selecionar \"{{int:config-mssql-windowsauth}}\", as credenciais de qualquer usuário que o servidor web esteja executando serão usadas.",
index 2eadc8c..223e26e 100644 (file)
        "config-db-web-no-create-privs": "A conta que especificou para a instalação não tem privilégios suficientes para criar uma conta.\nA conta que especificar aqui já tem de existir.",
        "config-mysql-engine": "Motor de armazenamento:",
        "config-mysql-innodb": "InnoDB (recomendado)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Aviso:</strong>  Selecionou o MyISAM para motor de armazenamento do MySQL, uma combinação desaconselhada para usar com o MediaWiki porque:\n* praticamente não permite acessos simultâneos, porque bloqueia tabelas\n* o MyISAM é mais suscetível a perdas da integridade dos dados do que outros motores\n* o código do MediaWiki não trabalha devidamente com o MyISAM\n\nSe a sua instalação do MySQL suporta InnoDB, é altamente recomendado que o escolha em vez do MyISAM.\nSe não suporta o InnoDB, talvez seja uma boa altura para atualizá-la para a versão mais recente.",
-       "config-mysql-only-myisam-dep": "<strong>Aviso:</strong> O único motor de armazenamento para MySQL nesta máquina é o MyISAM e o seu uso com o MediaWiki não é recomendado porque:\n* praticamente não suporta acessos simultâneos, porque bloqueia tabelas\n* o MyISAM é mais suscetível a perdas da integridade dos dados do que outros motores\n* o código do MediaWiki não trabalha devidamente com o MyISAM\n\nA sua instalação MySQL não suporta InnoDB, talvez seja uma boa altura para atualizá-la para a versão mais recente.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> é quase sempre a melhor opção, porque suporta bem acessos simultâneos <i>(concurrency)</i>.\n\n<strong>MyISAM</strong> pode ser mais rápido no modo de utilizador único ou em instalações somente para leitura.\nAs bases de dados MyISAM tendem a perder integridade de dados com mais frequência do que as bases de dados InnoDB.",
        "config-mssql-auth": "Tipo de autenticação:",
        "config-mssql-install-auth": "Selecione o tipo de autenticação a usar para ligar à base de dados durante o processo de instalação.\nSe selecionar \"{{int:config-mssql-windowsauth}}\", serão usadas as credenciais do utilizador com que o servidor de Internet está a ser executado.",
index 07d9a6c..fb68b30 100644 (file)
        "config-db-web-create": "Creați contul dacă nu există deja",
        "config-mysql-engine": "Motor de stocare:",
        "config-mysql-innodb": "InnoDB (recomandat)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Tip de autentificare:",
        "config-site-name": "Numele wikiului:",
        "config-site-name-blank": "Introduceți un nume pentru sit.",
index 1c0ec86..df1ca1a 100644 (file)
@@ -58,7 +58,6 @@
        "config-header-mssql": "'Mbostaziune de Microsoft SQL Server",
        "config-invalid-db-type": "Tipe de database invalide.",
        "config-mysql-innodb": "InnoDB (conzigliate)",
-       "config-mysql-myisam": "MyISAM",
        "config-ns-generic": "Proggette",
        "config-admin-email": "Indirizze e-mail:",
        "config-install-step-done": "fatte",
index 4346f58..03ef206 100644 (file)
        "config-db-web-no-create-privs": "Учётная запись, указанная вами для установки, не обладает достаточными правами для создания учётной записи.\nУказанная здесь учётная запись уже должна существовать.",
        "config-mysql-engine": "Движок базы данных:",
        "config-mysql-innodb": "InnoDB (рекомендуется)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "''' Внимание.''' Вы выбрали механизм MyISAM для хранения данных MySQL. Он не рекомендуется к использованию по следующим причинам:\n* он слабо поддерживает параллелизм из-за табличных блокировок;\n* более склонен к потере данных, по сравнению с другими механизмами;\n* код MediaWiki не всегда учитывает особенности MyISAM должным образом.\n\nЕсли ваша MySQL поддерживает InnoDB, настоятельно рекомендуется выбрать этот механизм.\nЕсли ваша MySQL не поддерживает InnoDB, возможно, настало время обновиться.",
-       "config-mysql-only-myisam-dep": "<strong>Предупреждение:</strong> MyISAM — единственная доступная система хранения данных для MySQL на этом компьютере, и она не рекомендуется для использования совместно с MediaWiki, потому что:\n* слабо поддерживает параллелизм из-за блокировки таблиц\n* больше других систем подвержена повреждению\n* кодовая база MediaWiki не всегда обрабатывает MyISAM так, как следует\n\nВаша MySQL не поддерживает InnoDB, так что, возможно, настало время для обновления.",
        "config-mysql-engine-help": "'''InnoDB''' почти всегда предпочтительнее, так как он лучше справляется с параллельным доступом.\n\n'''MyISAM''' может оказаться быстрее для вики с одним пользователем или с минимальным количеством поступающих правок, однако базы данных на нём портятся чаще, чем на InnoDB.",
        "config-mssql-auth": "Тип аутентификации:",
        "config-mssql-install-auth": "Выберите тип проверки подлинности, который будет использоваться для подключения к базе данных во время процесса установки.\nЕсли вы выберите «{{int:config-mssql-windowsauth}}», будут использоваться учётные данные пользователя, под которым работает веб-сервер.",
index 6703c8e..3fc52ab 100644 (file)
        "config-db-web-no-create-privs": "The accoont that ye speceefied fer instawation disna hae enooch preevileges tae cræft aen accoont.\nThe accoont that ye speceefie here maun awreadie exeest.",
        "config-mysql-engine": "Storage engine:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Warnishment:</strong> Ye'v selected MyISAM aes storage engine fer MySQL, this isna recommended fer uiss wi MediaWiki, cause:\n* it barelie supports concurrencie cause o buird lockin\n* it's mair prone til rot than ither engines\n* the MediaWiki codebase disna aye haunnle MyISAM aes it shid\n\nGif yer MySQL installâtion supports InnoDB, it is heilie recommended that ye chuise that instead.\nGif yer MySQL installâtion disna support InnoDB, than perhaps it's time fer aen upgrade.",
-       "config-mysql-only-myisam-dep": "<strong>Warnishment:</strong> MyISAM is the yinly available storage engine fer MySQL oan this machine, n this isna recommended fer uiss wi MediaWiki, cause:\n* it barelie supports concurrencie cause o buird lockin\n* it is mair prone til rot than ither engines\n* the MediaWiki codebase disna aye haunnle MyISAM aes it shid\n\nYer MySQL installâtion dina support InnoDB, perhaps it's time fer aen upgrade.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> is awmaist aye the best optie, aes it haes guid concurrencie support.\n\n<strong>MyISAM</strong> micht be faster in single-uiser or read-yinly installâtions.\nMyISAM databases tend tae rot mair aften than InnoDB databases.",
        "config-mssql-auth": "Authentication type:",
        "config-mssql-install-auth": "Select the authentication type that's tae be uised tae connect wi the database durin the installation process.\nGif ye select \"{{int:config-mssql-windowsauth}}\", the credeentials o whitever uiser the wabserver is rinnin aes will be uised.",
index fcad452..06090ca 100644 (file)
@@ -58,7 +58,7 @@
        "config-unicode-pure-php-warning": "'''Upozorenje''': Dodatak [https://pecl.php.net/intl intl PECL] nije dostupan za normalizaciju Unicode, vraćajući se na sporu primjenu čistog PHP-a.\n\nAko imate web-lokaciju s visokim prometom, morat ćete pročitati više o [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode normalizacije].",
        "config-unicode-update-warning": "'''Upozorenje:''' Uspostavljena verzija omotnice Unicode normalizacije koristi stariju verziju biblioteke [http://site.icu-project.org/ projekta ICU].\nDa biste koristili Unicode, trebate napraviti [https://www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations nadogradnju].",
        "config-no-db": "Nisam mogao pronaći odgovarajući upravljački program za bazu podataka! Morat ćete uspostaviti upravljački program za PHP-bazu.\n{{PLURAL:$2|Podržana je sljedeća vrsta|Podržane su sljedeće vrste}} baze: $1.\n\nAko ste sami kompilirali PHP, omogućite bazni klijent u postavkama - npr. s <code>./configure --with-mysqli</code>.\nAko ovaj PHP uspostavite iz Debian ili Ubuntu paketa, tada ćete ga morati uspostaviti, npr., paket <code>php-mysql</code>.",
-       "config-outdated-sqlite": "'''Upozorenje''': imate SQLite $1. Najstarija dopuštena verzija je $2. Stoga će SQLite biti nedostupan.",
+       "config-outdated-sqlite": "<strong>Upozorenje</strong>: imate SQLite $2. Najstarija dopuštena verzija je $1. Stoga, SQLite će biti nedostupan.",
        "config-no-fts3": "'''Upozorenje''': SQLite se kompilira bez modula [//sqlite.org/fts3.html FTS3] - za tu bazu podataka neće biti mogućnosti pretrage.",
        "config-pcre-old": "'''Kobno:''' Potreban je PCRE $1 ili novija verzija.\nVaš PHP-binarni je svezan s PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Više informacija].",
        "config-pcre-no-utf8": "<strong>Kobno</strong>: PCRE modul PHP-a je hitan bez podrške za PCRE_UTF8.\nMediaWiki zahtijeva podršku za UTF-8 kako bi ispravno funkcionirao.",
        "config-db-web-no-create-privs": "Račun koji ste naveli za uspostavu nema dovoljne privilegije za da stvori račun.\nOvdje morate navesti postojeći račun.",
        "config-mysql-engine": "Skladišni pogon:",
        "config-mysql-innodb": "InnoDB (preporučeno)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Upozorenje:</strong> Odabrali ste MyISAM kao skladišni pogon za MySQL. Ali ne preporučuje se za MediaWiki jer:\n* jedva podržava istovremenost iz zaključavanja tabela\n* vjerojatnije je da će ih druge biljke pokvariti\n* kodna baza MediaWikija ne može uvijek ispravno raditi s MyISAM-om\n\nAko vaša uspostava MySQL-a podržava InnoDB, tada seriozno preporučujemo da je koristite umjesto MyISAM.\nAko vaša uspostava MySQL-a ne podržava InnoDB, vjerojatno je vrijeme za nadogradnju.",
-       "config-mysql-only-myisam-dep": "<strong>Upozorenje:</strong> MyISAM je jedini dostupan skladišni pogon za MySQL na ovom stroju, a ovo se ne preporučuje za uporabu s MediaWiki, jer:\n* skoro ne podržava istovremeno izvršavanje zadataka zbog zaključavanja tablica\n* više osjetljiv na kvarenje od drugih pogona \n* kodna baza MediaWIkija ne radi uvijek ispravno s MyISAM-om\nVaša MySQL uspostava ne podržava InnoDB. Možda je vrijeme da ga nadogradimo.",
        "config-mssql-auth": "Tip potvrde identiteta:",
        "config-mssql-sqlauth": "Potvrda identiteta za SQL Server",
        "config-mssql-windowsauth": "Potvrda identiteta za Windows",
        "config-site-name": "Ime wikija:",
        "config-site-name-help": "Ovo će se pojaviti u naslovnoj traci pregledača i na raznim drugim mestima.",
+       "config-project-namespace": "Projektni imenski prostor:",
+       "config-ns-generic": "Projekat",
+       "config-ns-site-name": "Isto ime kao wikija: $1",
+       "config-ns-other": "Drugo (navedite)",
+       "config-ns-other-default": "MyWiki",
+       "config-admin-box": "Administratoski račun",
+       "config-admin-name": "Vaše korisničko ime:",
        "config-admin-password": "Lozinka:",
+       "config-admin-password-confirm": "Ponovite lozinku:",
+       "config-admin-name-blank": "Upišite administratorsko korisničko ime.",
+       "config-admin-password-blank": "Upišite lozinku za administratorski račun",
+       "config-admin-password-mismatch": "Lozinke što ste upisali se ne poklapaju.",
+       "config-admin-email": "E-mail adresa:",
+       "config-profile": "Profil korisničkih prava:",
+       "config-profile-wiki": "Otvoren wiki",
+       "config-profile-no-anon": "Neophodno otvaranje računa",
+       "config-profile-fishbowl": "Samo ovlašteni urednici",
+       "config-profile-private": "Privatan wiki",
+       "config-license": "Autorska prava i licenca:",
+       "config-license-none": "Bez podnožja za licencu",
+       "config-email-settings": "Podešavanja e-pošte",
+       "config-enable-email": "Omogući odlaznu e-poštu",
+       "config-email-user": "Omogući slanje e-poruka među korisnicima",
+       "config-email-user-help": "Dozvoli svim korisnicima da međusobno šalju e-poruke ako imaju omogućeno u podešavanjima.",
+       "config-email-usertalk": "Omogući obaveštenja o promjenama u korisničkim stranicama za razgovor",
+       "config-email-usertalk-help": "Omogući korisnicima da primaju obaveštenja o promenama u njihovim korisničkim razgovornim stranicama ako su ih omogućili u podešavanjima.",
+       "config-email-watchlist": "Omogući obaveštenja o spisku praćenja",
+       "config-email-watchlist-help": "Omogući korisnicima da primaju obaveštenja o svojim nadgledanim stranicama ako su ih omogućili u podešavanjima.",
+       "config-upload-settings": "Otpremanja slika i datoteka",
+       "config-upload-enable": "Omogući postavljanje datoteka",
+       "config-upload-deleted": "Folder za obrisane datoteke:",
+       "config-upload-deleted-help": "Odaberite u kojem folderu će se arhivirati izbrisane datoteke.\nNajbolje bi bilo ako taj nije dostupan putem svemrežja.",
+       "config-logo": "URL za logotipa:",
+       "config-instantcommons": "Omogući Instant Commons",
+       "config-cc-again": "Odaberite ponovo...",
+       "config-cc-not-chosen": "Odaberite željenu licencu Creative Commons i kliknite na „proceed”.",
+       "config-advanced-settings": "Napredna podešavanja",
+       "config-cache-options": "Podešavanja za međuspremanje objekta:",
+       "config-cache-none": "Nema međuspremanja (ne uklanja se nijedna funkcija, ali može uticati na brzinu na veće wiki lokacije)",
+       "config-cache-accel": "Međuspremanje PHP-objekta (APC, APCu ili WinCache)",
+       "config-cache-memcached": "Koristi Memcached (zahtijeva dodatno postavljivanje i podešavanje)",
+       "config-memcached-servers": "Memcached-serveri:",
+       "config-memcached-help": "Lista IP adresa za uporabu u Memcached.\nTreba da se navede jednu u svaki red, kao i port što će se koristiti. Na primer:\n 127.0.0.1:11211\n 192.168.1.25:1234",
+       "config-memcache-needservers": "Odabrali ste Memcached kao vaš tip međuspremnika (keša), ali niste naveli nijedan server.",
        "mainpagetext": "<strong>MediaWiki je uspješno instaliran.</strong>",
        "mainpagedocfooter": "Za informacije o korištenju wiki softvera konzultirajte [https://meta.wikimedia.org/wiki/Help:Contents Vodič za korisnike].\n\n== Uvod u rad ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista konfiguracije postavki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Lista primatelja izdanja MediaWikija]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Lokalizirajte MediaWiki za svoj jezik]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Saznajte kako se boriti protiv spama na svojem wikiju]"
 }
index 363014c..fefe7a2 100644 (file)
@@ -62,7 +62,6 @@
        "config-db-web-account": "ජාල ප්‍රවේශනය සඳහා දත්ත සංචිත ගිණුම",
        "config-mysql-engine": "ආචයන එන්ජිම:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-windowsauth": "windows සහතික කිරීම.",
        "config-site-name": "විකියෙහි නම:",
        "config-site-name-blank": "අඩවි නාමයක් යොදන්න.",
index 9277f74..3dd7038 100644 (file)
        "config-db-web-create": "Ustvari račun, če že ne obstaja",
        "config-mysql-engine": "Pogon skladiščenja:",
        "config-mysql-innodb": "InnoDB (priporočeno)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Tip avtentikacije:",
        "config-site-name": "Ime wikija:",
        "config-site-name-help": "To bo prikazano v naslovni vrstici brskalnika in na drugih različnih mestih.",
index 344bd23..e740511 100644 (file)
        "config-db-web-no-create-privs": "Налог који сте навели за инсталацију нема довољне привилегије да отвори налог.\nНалог који овде наведете већ мора да постоји.",
        "config-mysql-engine": "Механизам складишта:",
        "config-mysql-innodb": "InnoDB (препоручено)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Тип потврде идентитета:",
        "config-mssql-sqlauth": "SQL Server потврда идентитета",
        "config-mssql-windowsauth": "Windows потврда идентитета",
index 0b31bca..26d60f5 100644 (file)
        "config-db-web-no-create-privs": "Nalog koji ste naveli za instalaciju nema dovoljne privilegije da otvori nalog.\nNalog koji ovde navedete već mora da postoji.",
        "config-mysql-engine": "Mehanizam skladišta:",
        "config-mysql-innodb": "InnoDB (preporučeno)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Tip potvrde identiteta:",
        "config-mssql-sqlauth": "SQL Server potvrda identiteta",
        "config-mssql-windowsauth": "Windows potvrda identiteta",
index a3e8a29..45b8545 100644 (file)
        "config-db-web-no-create-privs": "Det konto som du har angett för installation har inte tillräcklig behörighet för att skapa ett konto.\nDet konto du anger här måste redan finnas.",
        "config-mysql-engine": "Lagringsmotor:",
        "config-mysql-innodb": "InnoDB (rekommenderas)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Varning:''' Du har valt MyISAM som lagringsmotor för MySQL, vilket inte rekommenderas för användning med MediaWiki eftersom:\n* den knappt stöder samtidigt exekvering på grund av låsning av tabeller\n* den är mer benägen att korrumpera data än andra motorer\n* MediaWiki-kodbasen hanterar inte alltid MyISAM som den ska\n\nOm din MySQL-installation stöder InnoDB, är det starkt rekommenderat att du väljer det istället.\nOm din MySQL-installation inte stöder InnoDB, kanske det är dags för en uppgradering.",
-       "config-mysql-only-myisam-dep": "'''Varning:''' MyISAM är den enda tillgängliga lagringsmotorn för MySQL på denna maskin, och den är inte rekommenderad att använda med MediaWiki eftersom:\n* den knappt stöder samtidigt exekvering på grund av låsning av tabeller\n* den är mer benägen att korrumpera data än andra motorer\n* MediaWiki-kodbasen hanterar inte alltid MyISAM som den ska\n\nDin MySQL-installation stöder inte InnoDB, det kanske är dags för en uppgradering.",
        "config-mysql-engine-help": "'''InnoDB''' är nästan alltid det bästa valet eftersom den har ett bra system för samtidiga arbeten.\n\n'''MyISAM''' kan vara snabbare i enanvändarläge eller skrivskyddade installationer.\nMyISAM-databaser tenderar att bli korrupta oftare än InnoDB-databaser.",
        "config-mssql-auth": "Autentiseringstyp:",
        "config-mssql-install-auth": "Välj autentiseringstypen som kommer att användas för att ansluta till databasen under installationsprocessen.\nOm du väljer \"{{int:config-mssql-windowsauth}}\", kommer autentiseringsuppgifterna för den användare webbservern körs som att användas.",
index 49bb4f4..e8e9a75 100644 (file)
        "config-db-web-no-create-privs": "స్థాపన కోసం మీరిచ్చిన ఖాతాకు ఓ కొత్త ఖాతాను సృష్టించే అనుమతులు లేవు.\nఇక్కడ మీరిచ్చే ఖాతా తప్పనిసరిగా ఈసరికే ఉనికిలో ఉండాలి.",
        "config-mysql-engine": "స్టోరేజీ ఇంజను:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "ఆథెంటికేషన్ రకం:",
        "config-mssql-sqlauth": "SQL Server ఆథెంటికేషన్",
        "config-mssql-windowsauth": "విండోస్ ఆథెంటికేషన్",
index d4e6731..38aafbe 100644 (file)
        "config-db-web-no-create-privs": "บัญชีที่คุณระบุไว้สำหรับการติดตั้งมีสิทธิ์ไม่เพียงพอที่จะสร้างบัญชี\nบัญชีที่คุณระบุไว้ที่นี่จะต้องมีอยู่แล้ว",
        "config-mysql-engine": "กลไกที่จัดเก็บข้อมูล:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>คำเตือน:</strong> คุณได้เลือก MyISAM เป็นกลไกที่จัดเก็บข้อมูลสำหรับ MySQL ซึ่่งไม่แนะนำให้ใช้กับ MediaWiki เนื่องจาก:\n* ไม่ค่อยสนับสนุนกระบวนการทำงานพร้อมกันเนื่องจากการล็อกตารางข้อมูล\n* มีแนวโน้มที่จะเสียหายมากกว่ากลไกอื่น\n* Codebase ของ MediaWiki ไม่สามารถจัดการ MyISAM ได้ดีเท่าที่ควร\n\nถ้าการติดตั้ง MySQL ของคุณสนับสนุน InnoDB แนะนำอย่างยิ่งว่าให้คุณเลือก InnoDB แทน\nถ้าการติดตั้ง MySQL ของคุณไม่สนับสนุน InnoDB อาจถึงเวลาที่คุณต้องอัปเกรดแล้ว",
-       "config-mysql-only-myisam-dep": "<strong>คำเตือน:</strong> กลไกที่จัดเก็บข้อมูลสำหรับ MySQL ที่พร้อมใช้งานบนเครื่องนี้มีเพียง MyISAM ซึ่่งไม่แนะนำให้ใช้กับ MediaWiki เนื่องจาก:\n* ไม่ค่อยสนับสนุนกระบวนการทำงานพร้อมกันเนื่องจากการล็อกตารางข้อมูล\n* มีแนวโน้มที่จะเสียหายมากกว่ากลไกอื่น\n* Codebase ของ MediaWiki ไม่สามารถจัดการ MyISAM ได้ดีเท่าที่ควร\n\nการติดตั้ง MySQL ของคุณไม่สนับสนุน InnoDB อาจถึงเวลาที่คุณต้องอัปเกรดแล้ว",
        "config-mysql-engine-help": "<strong>InnoDB</strong> เป็นตัวเลือกที่เกือบดีที่สุดเสมอ เนื่องจากมีการสนับสนุนกระบวนการทำงานพร้อมกัน\n\n<strong>MyISAM</strong> อาจทำงานได้เร็วกว่าในการติดตั้งแบบผู้ใช้คนเดียวหรือแบบอ่านอย่างเดียว\nฐานข้อมูล MyISAM มักจะได้รับความเสียหายบ่อยมากกว่าฐานข้อมูล InnoDB",
        "config-mssql-auth": "ชนิดการยืนยันตัวตน:",
        "config-mssql-install-auth": "เลือกชนิดการยืนยันตัวตนที่จะใช้เชื่อมต่อไปยังฐานข้อมูลในระหว่างกระบวนการติดตั้ง\nถ้าคุณเลือก \"{{int:config-mssql-windowsauth}}\" ข้อมูลประจำตัวที่ระบุว่าเว็บเซิร์ฟเวอร์กำลังทำงานในฐานะผู้ใช้ใดจะถูกใช้",
index dc17ddf..6d63409 100644 (file)
        "config-db-web-no-create-privs": "Ang tinukoy mong account na iluluklok ay walang sapat na mga pribilehiyo upang makalikha ng isang account.\nAng account na tutukuyin mo rito ay umiiral na dapat.",
        "config-mysql-engine": "Makinang imbakan:",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Babala''': Pinili mo ang MyISAM bilang makinang imbakan para sa MySQL, na hindi iminumungkahi para gamitin sa MediaWiki, sapagkat:\n* bahagya lamang itong sumusuporta ng pagkakasundu-sundo dahil sa pagkakandado ng talahanayan\n* mas malaki ang pagkakataon na kapitan ng sira kaysa sa ibang mga makina\n* ang himpilang kodigo ng MediaWiki ay hindi palaging humahawak ng MyISAM ayon sa nararapat\n\nKung ang iyong nakaluklok na MySQL ay sumusuporta ng InnoDB, higit na iminumungkahi na piliin mo iyon sa halip.\nKung ang iyong nakaluklok na MySQL ay hindi sumusuporta ng InnoDB, marahil ay panahon na para sa isang pagtataas ng uri.",
        "config-mysql-engine-help": "Ang '''InnoDB''' ay ang halos palaging pinaka mainam na mapipili, dahil mayroon itong mabuting suporta ng pagkakasundu-sundo.\n\nMaaaring mas mabilis ang '''MyISAM''' sa mga pagluluklok na pang-isahang tagagamit o mababasa lamang.\nMay gawi ang mga kalipunan ng dato ng MyISAM na masira nang mas madalas kaysa sa mga kalipunan ng dato ng InnoDB.",
        "config-site-name": "Pangalan ng wiki:",
        "config-site-name-help": "Lilitaw ito sa bareta ng pamagat ng pantingin-tingin at sa samu't saring ibang mga lugar.",
index 95e53ca..e2a4683 100644 (file)
        "config-db-web-no-create-privs": "Kurulum için belirlediğiniz hesap, hesap yaratımı için gerekli izinlere sahip değil.\nBurada belirttiğiniz hesap halihazırda var olmalı.",
        "config-mysql-engine": "Depolama motoru:",
        "config-mysql-innodb": "InnoDB (önerilen)",
-       "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Kimlik doğrulama türü:",
        "config-mssql-install-auth": "Kurulum işlemi sırasında veritabanına bağlanmak için kullanılacak doğrulama türünü seçin.\n\"{{int:config-mssql-windowsauth}}\"'ı seçerseniz,ağ sunucusu olarak çalışan kullanıcının kimlik bilgileri kullanılacaktır.",
        "config-mssql-sqlauth": "SQL Server kimlik doğrulaması",
index 60fa81e..d9c615d 100644 (file)
@@ -7,16 +7,22 @@
                        "Ерней"
                ]
        },
-       "config-desc": "MediaWiki йөкләүче",
-       "config-title": "MediaWiki $1 куелышы",
+       "config-desc": "MediaWiki урнаштыручы",
+       "config-title": "MediaWiki $1 урнаштыруы",
        "config-information": "Мәгълүмат",
+       "config-localsettings-upgrade": "<code>LocalSettings.php</code> файлы табылды.\nБу урнаштыру яңартырга өчен, түбәндәге кырда <code>$wgUpgradeKey</code> кыйммәтен кертегез әле.\nСез аны <code>LocalSettings.php</code> файлында табасыз.",
+       "config-localsettings-cli-upgrade": "<code>LocalSettings.php</code> файлы табылды.\nБу урнаштыру яңартыга өчен, <code>update.php</code> җибәрегез әле",
        "config-localsettings-key": "Яңарту ачкычы:",
+       "config-localsettings-badkey": "Сез ялгыш яңарту ачкычы бирдегез.",
        "config-your-language": "Телегез:",
        "config-wiki-language": "Вики теле:",
-       "config-back": "â\86\90 Ð\90Ñ\80Ñ\82ка",
-       "config-continue": "Ð\9aилÓ\99Ñ\81е →",
+       "config-back": "â\86\90 Ð\9aиÑ\80егÓ\99",
+       "config-continue": "Ð\94Ó\99вам Ð¸Ñ\82Ò¯ →",
        "config-page-language": "Тел",
        "config-page-welcome": "MediaWiki проектына рәхим итегез!",
+       "config-page-dbconnect": "Мәгълүматлар базасына тоташтыру",
+       "config-page-upgrade": "Булган урнаштыруны яңарту",
+       "config-page-dbsettings": "Мәгълүматлар базасы көйләнмәләре",
        "config-page-name": "Исем",
        "config-page-options": "Көйләнмәләр",
        "config-page-install": "Урнаштыру",
        "config-page-copying": "Лицензия",
        "config-page-upgradedoc": "Яңарту",
        "config-page-existingwiki": "Хәзерге вики",
-       "config-restart": "Әйе, яңадан башларга",
+       "config-restart": "Әйе, яңадан башлау",
+       "config-sidebar-readme": "Укып чык",
+       "config-sidebar-relnotes": "Чыгарыш турында мәгълүмат",
+       "config-sidebar-license": "Күчермә алу",
+       "config-sidebar-upgrade": "Яңарту",
        "config-env-php": "PHP $1 куелды.",
        "config-env-hhvm": "HHVM $1 куелды.",
        "config-apc": "[https://www.php.net/apc APC] куелды",
+       "config-apcu": "[https://www.php.net/apcu APCu] куелды",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] куелды",
        "config-diff3-bad": "GNU diff3 табылмады.",
        "config-git": "Git юрамалар идарә итү системасы табылды: <code>$1</code>.",
        "config-using-server": "«<nowiki>$1</nowiki>» сервер исеме файдаланыла.",
        "config-using-uri": "«<nowiki>$1$2</nowiki>» URL исемле сервер файдаланыла.",
-       "config-db-type": "Мәгълүмат базасы төре:",
-       "config-db-host": "Мәгълүмат базасы хосты:",
+       "config-db-type": "Мәгълүматлар базасы төре:",
+       "config-db-host": "Мәгълүматлар базасы хосты:",
        "config-db-host-oracle": "TNS мәгълүмат базасы:",
-       "config-db-wiki-settings": "Бу вики идентификациясе",
+       "config-db-wiki-settings": "Бу вики тәңгәлләштерү",
        "config-db-name": "Мәгълүматлар базасы исеме (сызыкчасыз):",
-       "config-db-name-oracle": "Мәгълүмат базасы төзелеше:",
+       "config-db-name-oracle": "Мәгълүматлар базасы төзелеше:",
        "config-db-username": "Мәгълүмат базасын кулланучы исеме:",
        "config-db-password": "Мәгълүмат базасының серсүзе:",
-       "config-db-port": "Мәгълүмат базасы порты:",
+       "config-db-port": "Мәгълүматлар базасы порты:",
        "config-db-schema": "MediaWiki өчен (сызыкчасыз) төзелеш:",
-       "config-type-mysql": "MariaDB, MySQL Ñ\8fиÑ\81Ó\99 ярашлы",
+       "config-type-mysql": "MariaDB, MySQL Ñ\8fки ярашлы",
        "config-type-mssql": "Microsoft SQL Server",
        "config-header-mysql": "MariaDB/MySQL көйләнмәләре",
        "config-header-postgres": "PostgreSQL көйләнмәләре",
        "config-header-sqlite": "SQLite көйләнмәләре",
        "config-header-oracle": "Oracle көйләнмәләре",
        "config-header-mssql": "Microsoft SQL Server көйләнмәләре",
-       "config-invalid-db-type": "Ялган Ð±Ð¸Ñ\80елмÓ\99лÓ\99Ñ\80 Ð±Ð°Ð·Ð°Ñ\81Ñ\8b Ñ\82Ó©Ñ\80е",
+       "config-invalid-db-type": "Ð\9cÓ\99гÑ\8aлүмаÑ\82лаÑ\80 Ð±Ð°Ð·Ð°Ñ\81Ñ\8b Ñ\8fлгÑ\8bÑ\88 Ñ\82Ó©Ñ\80е.",
        "config-upgrade-done-no-regenerate": "Яңартү тәмамланды.\n\nХәзер сез [$1 вики] белән эшли аласыз.",
        "config-regenerate": "LocalSettings.php яңадан төзү →",
        "config-show-table-status": "«<code>SHOW TABLE STATUS</code>» таләбе эшләнмәде!",
        "config-mysql-engine": "Саклау системасы:",
-       "config-mysql-innodb": "InnoDB (тәкъдим ителә)",
-       "config-mysql-myisam": "MyISAM",
+       "config-mysql-innodb": "InnoDB (киңәш ителә)",
        "config-mssql-auth": "Аутентификация төре:",
        "config-mssql-sqlauth": "SQL Server чынлыгын раслау",
        "config-mssql-windowsauth": "Windows чынлыгын раслау",
        "config-admin-password": "Серсүз:",
        "config-admin-password-confirm": "Серсүзне кабатлагыз:",
        "config-admin-email": "Электрон почта адресы:",
+       "config-profile": "Кулланучы хокуклары профиле:",
        "config-profile-wiki": "Ачык вики",
        "config-profile-private": "Ябык вики",
-       "config-license": "Автор хокуклары һәм лицензияләр:",
+       "config-license": "Авторлык хокукы һәм рөхсәтнамә:",
        "config-license-cc-by-sa": "Creative Commons Attribution Share Alike",
        "config-license-cc-by": "Creative Commons Attribution",
        "config-license-cc-by-nc-sa": "Creative Commons Attribution Non-Commercial Share Alike",
        "config-license-cc-0": "Creative Commons Zero (җәмгыять мирасы)",
        "config-license-gfdl": "GNU Free Documentation License 1.3 яки яңарагы",
        "config-license-pd": "Җәмгыять мирасы",
+       "config-email-settings": "E-mail көйләнмәләре",
        "config-logo": "Логотип URL:",
-       "config-cc-again": "Кабат сайлагыз...",
+       "config-cc-again": "Кабат сайлагыз",
        "config-advanced-settings": "Өстәмә көйләнмәләр",
        "config-memcached-servers": "Memcached серверлары:",
        "config-extensions": "Киңәйтүләр",
        "config-skins": "Бизәлеш",
-       "config-install-step-done": "әзер",
+       "config-install-step-done": "тәмам",
        "config-install-step-failed": "булмады",
+       "config-install-database": "Мәгълүматлар базасы көйләве",
        "config-install-schema": "Схема төзү",
-       "config-install-tables": "Табын төзү",
+       "config-install-user-alreadyexists": "Кулланучы «$1» бар инде",
+       "config-install-user-create-failed": "«$1» кулланучыны китереп булмады: $2",
+       "config-install-tables": "Җәдвәлләр төзү",
        "config-install-stats": "Инициализация статистикасы",
        "config-download-localsettings": "<code>LocalSettings.php</code> йөкләү",
-       "config-help": "ярдәм",
+       "config-help": "белешмә",
        "config-help-tooltip": "ачу өчен басыгыз",
        "config-skins-screenshots": "$1 (скриншотлар: $2)",
        "config-extensions-requires": "$1 ($2 кирәк)",
index b92e58d..3ae74e7 100644 (file)
        "config-db-web-no-create-privs": "Обліковий запис, вказаний Вами для встановлення, не має достатніх повноважень для створення облікового запису.\nОбліковий запис, який Ви вказуєте тут, уже повинен існувати.",
        "config-mysql-engine": "Двигун бази даних:",
        "config-mysql-innodb": "InnoDB (рекомендовано)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "'''Увага''': Ви обрали MyISAM для зберігання даних MySQL, що не рекомендовано для роботи з MediaWiki, оскільки:\n* він слабко підтримує паралелізм через блокування таблиць\n* він більш схильний до ушкоджень, ніж інші двигуни\n* база коду MediaWiki не завжди працює з MyISAM так, як мала б.\n\nЯкщо Ваша інсталяція MySQL підтримує InnoDB, дуже рекомендується вибрати цей двигун.\nЯкщо Ваша інсталяція MySQL не підтримує InnoDB, можливо настав час її оновити.",
-       "config-mysql-only-myisam-dep": "\"'Зауваження:\"' MyISAM є єдиним механізмом для зберігання MySQL на цій машині, який не рекомендується для використання з MediaWiki, оскільки:\n* слабо підтримує паралелізм через блокування таблиць\n* більш схильний до пошкоджень, ніж інші двигуни\n* код MediaWiki не завжди розглядає MyISAM, як повинен\n\nТвоє встановлення MySQL не підтримує InnoDB, можливо, потрібно оновити.",
        "config-mysql-engine-help": "'''InnoDB''' є завжди кращим вибором, оскільки краще підтримує паралельний доступ.\n\n'''MyISAM''' може бути швидшим для одного користувача або в інсталяціях read-only.\nБази даних MyISAM схильні псуватись частіше, ніж бази InnoDB.",
        "config-mssql-auth": "Тип автентифікації:",
        "config-mssql-install-auth": "Виберіть тип перевірки автентичності, який буде використовуватися для підключення до бази даних під час процесу установки. \nЯкщо ви оберете \"{{int:config-mssql-windowsauth}}\", будуть використовуватися облікові дані користувача, під яким працює веб-сервер.",
index f71cbfc..0929c1b 100644 (file)
        "config-db-web-no-create-privs": "Tài khoản mà bạn xác định để cài đặt không có đủ quyền để tạo một tài khoản. Tài khoản mà bạn chỉ ra ở đây phải thực sự tồn tại trước đó.",
        "config-mysql-engine": "Máy lưu trữ:",
        "config-mysql-innodb": "InnoDB (khuyến khích)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>Cảnh báo:</strong> Bạn đã chọn MyISAM làm động cơ lưu trữ cho MySQL, điều này không được khuyến khích sử dụng với MediaWiki, bởi vì:\n* Nó ít hỗ trợ đồng thời do việc khóa bảng\n* Nó dễ bị lỗi hơn so với các động cơ khác\n* Kho mã nguồn của MediaWiki không phải khi nào cũng xử lý MyISAM như mong muốn\n\nNếu cài đặt MySQL của bạn hỗ trợ InnoDB, đặc biệt khuyến cáo bạn nên chọn để thay thế.\nNếu cài đặt MySQL của bạn không hỗ trợ InnoDB, có lẽ đã đến lúc để nâng cấp.",
-       "config-mysql-only-myisam-dep": "<strong>Cảnh báo:</strong> MyISAM chỉ là công cụ lưu trữ có sẵn cho MySQL trên máy tính này, và điều này không được khuyến khích sử dụng với MediaWiki, bởi vì:\n* Nó ít hỗ trợ đồng thời do việc khóa khóa\n* Nó là dễ bị hư hỏng hơn các engine khác\n* Codebase MediaWiki không phải khi nào cũng xử lý MyISAM như mong muốn\n\nCài đặt MySQL của bạn không hỗ trợ InnoDB, có lẽ đã đến lúc để nâng cấp.",
        "config-mysql-engine-help": "<strong>InnoDB</strong> hầu như luôn là tùy chọn tốt nhất, vì nó có hỗ trợ đồng thời rất tốt.\n\n<strong>MyISAM</strong> có thể nhanh hơn trong chế độ một người dùng hoặc các cài đặt chỉ-đọc (read-only).\nCơ sở dữ liệu MyISAM có xu hướng thường xuyên bị hỏng hóc hơn so với cơ sở dữ liệu InnoDB.",
        "config-mssql-auth": "Kiểu xác thực:",
        "config-mssql-install-auth": "Chọn loại xác thực sẽ được sử dụng để kết nối với cơ sở dữ liệu trong quá trình cài đặt.\nNếu bạn chọn “{{int:config-mssql-windowsauth}}”, thông tin của bất cứ người sử dụng nào mà máy chủ web đang chạy sẽ được sử dụng.",
index dca707f..f53d856 100644 (file)
@@ -60,7 +60,6 @@
        "config-sqlite-cant-create-db": "Diri nakakahimo hin database file nga <code>$1</code>.",
        "config-db-web-account": "Database account para han web access",
        "config-mysql-innodb": "InnoDB",
-       "config-mysql-myisam": "MyISAM",
        "config-site-name": "Ngaran han wiki:",
        "config-ns-generic": "Proyekto",
        "config-ns-site-name": "Kapareho han wiki nga ngaran: $1",
index 47a593a..ecbfe02 100644 (file)
        "config-db-web-no-create-privs": "您指定给安装程序的帐号缺少创建帐号的权限,因此您指定的帐号必须已经存在。",
        "config-mysql-engine": "存储引擎:",
        "config-mysql-innodb": "InnoDB(推荐)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>警告:</strong>您选择了MyISAM作为MySQL的存储引擎,MediaWiki并不推荐您这么做,因为:\n* 它仅能通过表锁定来勉强支持并发\n* 与其他引擎相比,它更容易被损坏\n* MediaWiki代码库并不总会去处理MyISAM\n\n如果您的MySQL程序支持InnoDB,我们高度推荐您使用该引擎替代MyISAM。\n如果您的MySQL程序不支持InnoDB,请考虑升级。",
-       "config-mysql-only-myisam-dep": "<strong>警告:</strong>MyISAM是MySQL在此机器上唯一可用的存储引擎,但它不适合用于MediaWiki,因为:\n*因为表级锁定,它几乎不支持并发。\n*它相比其他引擎更容易损坏。\n*MediaWiki代码不能总是按照预期操作MyISAM。\n\n你的MySQL不支持InnoDB,是时候升级了。",
        "config-mysql-engine-help": "<strong>InnoDB</strong>通常是最佳选项,因为它对并发操作有着良好的支持。\n\n<strong>MyISAM</strong>在单用户或只读环境下可能会有更快的性能表现。但MyISAM数据库出错的概率一般要大于InnoDB数据库。",
        "config-mssql-auth": "身份验证类型:",
        "config-mssql-install-auth": "选择安装过程中链接数据库时将采用的身份验证方式。如果您选择“{{int:config-mssql-windowsauth}}”,将使用运行服务器的用户的身份凭据。",
index 743118c..28774f8 100644 (file)
@@ -21,7 +21,8 @@
                        "Wehwei",
                        "Wwycheuk",
                        "蘭斯特",
-                       "Kly"
+                       "Kly",
+                       "Winston Sung"
                ]
        },
        "config-desc": "MediaWiki 安裝程式",
        "config-db-web-no-create-privs": "您指定給安裝程序使用的帳號沒有足夠的權限建立新帳號。\n在此處必須指定已經存在的帳號。",
        "config-mysql-engine": "儲存引擎:",
        "config-mysql-innodb": "InnoDB(推薦)",
-       "config-mysql-myisam": "MyISAM",
-       "config-mysql-myisam-dep": "<strong>警告:</strong>您選擇用來做為 MySQL 的儲存引撆 MyISAM 並不建議使用在 MediaWiki,主要原因為:\n* MyISAM 使用的資料表鎖定較無法承受多人同時連線\n* 比起其他儲存引擎相,它較容易損壞\n* MediaWiki 程式碼並沒有針對 MyISAM 做特別的處理\n\n若您安裝的 MySQL 支援 InnoDB,我們強烈建議您改用 InnoDB。\n若您安裝的 MySQL 不支援 InnoDB,則應考慮升級 MySQL。",
-       "config-mysql-only-myisam-dep": "<strong>警告:</strong>您的伺服器上的 MySQL 唯一可用的儲存引擎是 MyISAM,但並不建議使用,主要原因為:\n* MyISAM 使用的資料表鎖定較無法承受多人同時連線\n* 比起其他儲存引擎相,它較容易損壞\n* MediaWiki 程式碼並沒有針對 MyISAM 做特別的處理\n\n若您安裝的 MySQL 不支援 InnoDB,則應考慮升級 MySQL。",
        "config-mysql-engine-help": "由於對同時連線有較好的處理能力,<strong>InnoDB</strong> 通常是最佳的選項。\n\n<strong>MyISAM</strong> 只在單人使用或者唯讀作業的情況之下才可能有較快的處理能力。\n相較於 InnoDB,MyISAM 也較容易出現資料損毀的情況。",
        "config-mssql-auth": "身份驗證類型:",
        "config-mssql-install-auth": "請選擇安裝程序中要用來連線資料庫使用的身份驗證類型。\n若您選擇 \"{{int:config-mssql-windowsauth}}\",不論網頁伺服器是使用何種身份執行都會使用這組驗證資料。",
        "config-memcache-badport": "Memcached 埠號應介於 $1 到 $2 之間。",
        "config-extensions": "擴充套件",
        "config-extensions-help": "已在您的 <code>./extensions</code> 目錄中發現下列擴充套件。\n\n這些擴充套件可能需要做額外的設定,但您可以現在先開啟功能。",
-       "config-skins": "外觀",
+       "config-skins": "佈景主題",
        "config-skins-help": "系統偵測到您於 <code>./skins</code> 資料夾中含有外觀如上清單。 您必須開啟其中一項並設為預設值。",
        "config-skins-use-as-default": "使用此外觀作為預設",
        "config-skins-missing": "沒有發現任何外觀;MediaWiki 在您安裝一些恰當的外觀前將會使用備用外觀。",
index e2914be..9519b7f 100644 (file)
@@ -76,7 +76,9 @@ class AssembleUploadChunksJob extends Job {
 
                        // We can only get warnings like 'duplicate' after concatenating the chunks
                        $status = Status::newGood();
-                       $status->value = [ 'warnings' => $upload->checkWarnings() ];
+                       $status->value = [
+                               'warnings' => UploadBase::makeWarningsSerializable( $upload->checkWarnings() )
+                       ];
 
                        // We have a new filekey for the fully concatenated file
                        $newFileKey = $upload->getStashFile()->getFileKey();
index 2462174..bafe5e3 100644 (file)
@@ -806,10 +806,10 @@ EOT;
 
                // Check for ZIP variants (before getimagesize)
                $eocdrPos = strpos( $tail, "PK\x05\x06" );
-               if ( $eocdrPos !== false ) {
+               if ( $eocdrPos !== false && $eocdrPos <= strlen( $tail ) - 22 ) {
                        $this->logger->info( __METHOD__ . ": ZIP signature present in $file\n" );
                        // Check if it really is a ZIP file, make sure the EOCDR is at the end (T40432)
-                       $commentLength = unpack( "n", substr( $tail, $eocdrPos + 20 ) )[0];
+                       $commentLength = unpack( "n", substr( $tail, $eocdrPos + 20 ) )[1];
                        if ( $eocdrPos + 22 + $commentLength !== strlen( $tail ) ) {
                                $this->logger->info( __METHOD__ . ": ZIP EOCDR not at end. Not a ZIP file." );
                        } else {
index 8c99532..e9fd7d9 100644 (file)
@@ -115,7 +115,8 @@ abstract class BagOStuff implements IExpiringStore, IStoreKeyEncoder, LoggerAwar
        /**
         * Get an item with the given key, regenerating and setting it if not found
         *
-        * Nothing is stored nor deleted if the callback returns false
+        * The callback can take $ttl as argument by reference and modify it.
+        * Nothing is stored nor deleted if the callback returns false.
         *
         * @param string $key
         * @param int $ttl Time-to-live (seconds)
@@ -128,10 +129,7 @@ abstract class BagOStuff implements IExpiringStore, IStoreKeyEncoder, LoggerAwar
                $value = $this->get( $key, $flags );
 
                if ( $value === false ) {
-                       if ( !is_callable( $callback ) ) {
-                               throw new InvalidArgumentException( "Invalid cache miss callback provided." );
-                       }
-                       $value = call_user_func( $callback );
+                       $value = $callback( $ttl );
                        if ( $value !== false ) {
                                $this->set( $key, $value, $ttl, $flags );
                        }
index e742432..23cf607 100644 (file)
@@ -798,8 +798,8 @@ abstract class MediumSpecificBagOStuff extends BagOStuff {
         *   - positive (< 10 years): relative TTL; return UNIX timestamp offset by this value
         *   - positive (>= 10 years): absolute UNIX timestamp; return this value
         *
-        * @param int $exptime Absolute TTL or 0 for indefinite
-        * @return int
+        * @param int $exptime
+        * @return int Absolute TTL or 0 for indefinite
         */
        final protected function convertToExpiry( $exptime ) {
                return $this->expiryIsRelative( $exptime )
@@ -811,11 +811,17 @@ abstract class MediumSpecificBagOStuff extends BagOStuff {
         * Convert an optionally absolute expiry time to a relative time. If an
         * absolute time is specified which is in the past, use a short expiry time.
         *
+        * The input value will be cast to an integer and interpreted as follows:
+        *   - zero: no expiry; return zero (e.g. TTL_INDEFINITE)
+        *   - negative: relative TTL; return a short expiry time (1 second)
+        *   - positive (< 10 years): relative TTL; return this value
+        *   - positive (>= 10 years): absolute UNIX timestamp; return offset to current time
+        *
         * @param int $exptime
-        * @return int
+        * @return int Relative TTL or 0 for indefinite
         */
        final protected function convertToRelative( $exptime ) {
-               return $this->expiryIsRelative( $exptime )
+               return $this->expiryIsRelative( $exptime ) || !$exptime
                        ? (int)$exptime
                        : max( $exptime - (int)$this->getCurrentTime(), 1 );
        }
index 69edb11..1852685 100644 (file)
@@ -1182,10 +1182,11 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         *      being no stale value available until after a thread completes the callback.
         *      Use WANObjectCache::TSE_NONE to disable this logic.
         *      Default: WANObjectCache::TSE_NONE.
-        *   - busyValue: If no value exists and another thread is currently regenerating it, use this
-        *      as a fallback value (or a callback to generate such a value). This assures that cache
-        *      stampedes cannot happen if the value falls out of cache. This can be used as insurance
-        *      against cache regeneration becoming very slow for some reason (greater than the TTL).
+        *   - busyValue: Specify a placeholder value to use when no value exists and another thread
+        *      is currently regenerating it. This assures that cache stampedes cannot happen if the
+        *      value falls out of cache. This also mitigates stampedes when value regeneration
+        *      becomes very slow (greater than $ttl/"lowTTL"). If this is a closure, then it will
+        *      be invoked to get the placeholder when needed.
         *      Default: null.
         *   - pcTTL: Process cache the value in this PHP instance for this many seconds. This avoids
         *      network I/O when a key is read several times. This will not cache when the callback
@@ -1301,7 +1302,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
         * @return array Ordered list of the following:
         *   - Cached or regenerated value
         *   - Cached or regenerated value version number or null if not versioned
-        *   - Timestamp of the cached value or null if there is no value
+        *   - Timestamp of the current cached value at the key or null if there is no value
         * @note Callable type hints are not used to avoid class-autoloading
         */
        private function fetchOrRegenerate( $key, $ttl, $callback, array $opts ) {
@@ -1399,11 +1400,7 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                                $miss = is_infinite( $minAsOf ) ? 'renew' : 'miss';
                                $this->stats->increment( "wanobjectcache.$kClass.$miss.busy" );
 
-                               return [
-                                       is_callable( $busyValue ) ? $busyValue() : $busyValue,
-                                       $version,
-                                       $curInfo['asOf']
-                               ];
+                               return [ $this->resolveBusyValue( $busyValue ), $version, $curInfo['asOf'] ];
                        }
                }
 
@@ -1604,6 +1601,14 @@ class WANObjectCache implements IExpiringStore, IStoreKeyEncoder, LoggerAwareInt
                );
        }
 
+       /**
+        * @param mixed $busyValue
+        * @return mixed
+        */
+       private function resolveBusyValue( $busyValue ) {
+               return ( $busyValue instanceof Closure ) ? $busyValue() : $busyValue;
+       }
+
        /**
         * Method to fetch multiple cache keys at once with regeneration
         *
index 2c9858a..f27d042 100644 (file)
@@ -140,10 +140,6 @@ class DBConnRef implements IDatabase {
                throw new DBUnexpectedError( $this, "Database injection is disallowed to enable reuse." );
        }
 
-       public function implicitGroupby() {
-               return $this->__call( __FUNCTION__, func_get_args() );
-       }
-
        public function implicitOrderby() {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -152,10 +148,6 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function doneWrites() {
-               return $this->__call( __FUNCTION__, func_get_args() );
-       }
-
        public function lastDoneWrites() {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -218,13 +210,6 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       /**
-        * @codeCoverageIgnore
-        */
-       public function getWikiID() {
-               return $this->getDomainID();
-       }
-
        public function getType() {
                if ( $this->conn === null ) {
                        // Avoid triggering a database connection
index 60062fb..8b65397 100644 (file)
@@ -61,7 +61,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        protected $cliMode;
        /** @var string Agent name for query profiling */
        protected $agent;
-       /** @var int Bitfield of class DBO_* constants */
+       /** @var int Bit field of class DBO_* constants */
        protected $flags;
        /** @var array LoadBalancer tracking information */
        protected $lbInfo = [];
@@ -217,6 +217,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        /** @var float Assume an insert of this many rows or less should be fast to replicate */
        private static $SMALL_WRITE_ROWS = 100;
 
+       /** @var string[] List of DBO_* flags that can be changed after connection */
+       protected static $MUTABLE_FLAGS = [
+               'DBO_DEBUG',
+               'DBO_NOBUFFER',
+               'DBO_TRX',
+               'DBO_DDLMODE',
+       ];
+       /** @var int Bit field of all DBO_* flags that can be changed after connection */
+       protected static $DBO_MUTABLE = (
+               self::DBO_DEBUG | self::DBO_NOBUFFER | self::DBO_TRX | self::DBO_DDLMODE
+       );
+
        /**
         * @note exceptions for missing libraries/drivers should be thrown in initConnection()
         * @param array $params Parameters passed from Database::factory()
@@ -283,23 +295,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        /**
         * Actually connect to the database over the wire (or to local files)
         *
-        * @throws InvalidArgumentException
         * @throws DBConnectionError
         * @since 1.31
         */
        protected function doInitConnection() {
-               if ( strlen( $this->connectionParams['user'] ) ) {
-                       $this->open(
-                               $this->connectionParams['host'],
-                               $this->connectionParams['user'],
-                               $this->connectionParams['password'],
-                               $this->connectionParams['dbname'],
-                               $this->connectionParams['schema'],
-                               $this->connectionParams['tablePrefix']
-                       );
-               } else {
-                       throw new InvalidArgumentException( "No database user provided" );
-               }
+               $this->open(
+                       $this->connectionParams['host'],
+                       $this->connectionParams['user'],
+                       $this->connectionParams['password'],
+                       $this->connectionParams['dbname'],
+                       $this->connectionParams['schema'],
+                       $this->connectionParams['tablePrefix']
+               );
        }
 
        /**
@@ -335,7 +342,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         *      equivalent to a "database" in MySQL. Note that MySQL and SQLite do not use schemas.
         *   - tablePrefix : Optional table prefix that is implicitly added on to all table names
         *      recognized in queries. This can be used in place of schemas for handle site farms.
-        *   - flags : Optional bitfield of DBO_* constants that define connection, protocol,
+        *   - flags : Optional bit field of DBO_* constants that define connection, protocol,
         *      buffering, and transaction behavior. It is STRONGLY adviced to leave the DBO_DEFAULT
         *      flag in place UNLESS this this database simply acts as a key/value store.
         *   - driver: Optional name of a specific DB client driver. For MySQL, there is only the
@@ -613,10 +620,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return $this->lazyMasterHandle;
        }
 
-       public function implicitGroupby() {
-               return true;
-       }
-
        public function implicitOrderby() {
                return true;
        }
@@ -625,10 +628,6 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return $this->lastQuery;
        }
 
-       public function doneWrites() {
-               return (bool)$this->lastWriteTime;
-       }
-
        public function lastDoneWrites() {
                return $this->lastWriteTime ?: false;
        }
@@ -741,24 +740,32 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function setFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
-               if ( ( $flag & self::DBO_IGNORE ) ) {
-                       throw new UnexpectedValueException( "Modifying DBO_IGNORE is not allowed" );
+               if ( $flag & ~static::$DBO_MUTABLE ) {
+                       throw new DBUnexpectedError(
+                               $this,
+                               "Got $flag (allowed: " . implode( ', ', static::$MUTABLE_FLAGS ) . ')'
+                       );
                }
 
                if ( $remember === self::REMEMBER_PRIOR ) {
                        array_push( $this->priorFlags, $this->flags );
                }
+
                $this->flags |= $flag;
        }
 
        public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
-               if ( ( $flag & self::DBO_IGNORE ) ) {
-                       throw new UnexpectedValueException( "Modifying DBO_IGNORE is not allowed" );
+               if ( $flag & ~static::$DBO_MUTABLE ) {
+                       throw new DBUnexpectedError(
+                               $this,
+                               "Got $flag (allowed: " . implode( ', ', static::$MUTABLE_FLAGS ) . ')'
+                       );
                }
 
                if ( $remember === self::REMEMBER_PRIOR ) {
                        array_push( $this->priorFlags, $this->flags );
                }
+
                $this->flags &= ~$flag;
        }
 
@@ -776,26 +783,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        public function getFlag( $flag ) {
-               return (bool)( $this->flags & $flag );
-       }
-
-       /**
-        * @param string $name Class field name
-        * @return mixed
-        * @deprecated Since 1.28
-        */
-       public function getProperty( $name ) {
-               return $this->$name;
+               return ( ( $this->flags & $flag ) === $flag );
        }
 
        public function getDomainID() {
                return $this->currentDomain->getId();
        }
 
-       final public function getWikiID() {
-               return $this->getDomainID();
-       }
-
        /**
         * Get information about an index into an object
         * @param string $table Table name
@@ -929,7 +923,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $closed = true; // already closed; nothing to do
                }
 
-               $this->conn = false;
+               $this->conn = null;
 
                // Throw any unexpected errors after having disconnected
                if ( $exception instanceof Exception ) {
@@ -1177,7 +1171,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         *
         * @param string $sql Original SQL query
         * @param string $fname Name of the calling function
-        * @param int $flags Bitfield of class QUERY_* constants
+        * @param int $flags Bit field of class QUERY_* constants
         * @return array An n-tuple of:
         *   - mixed|bool: An object, resource, or true on success; false on failure
         *   - string: The result of calling lastError()
@@ -1265,7 +1259,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @param string $commentedSql SQL query with debugging/trace comment
         * @param bool $isPermWrite Whether the query is a (non-temporary table) write
         * @param string $fname Name of the calling function
-        * @param int $flags Bitfield of class QUERY_* constants
+        * @param int $flags Bit field of class QUERY_* constants
         * @return array An n-tuple of:
         *   - mixed|bool: An object, resource, or true on success; false on failure
         *   - string: The result of calling lastError()
@@ -1570,9 +1564,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $ignore ) {
                        $this->queryLogger->debug( "SQL ERROR (ignored): $error" );
                } else {
-                       $exception = $this->getQueryExceptionAndLog( $error, $errno, $sql, $fname );
-
-                       throw $exception;
+                       throw $this->getQueryExceptionAndLog( $error, $errno, $sql, $fname );
                }
        }
 
@@ -1584,19 +1576,18 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * @return DBError
         */
        private function getQueryExceptionAndLog( $error, $errno, $sql, $fname ) {
-               $sql1line = mb_substr( str_replace( "\n", "\\n", $sql ), 0, 5 * 1024 );
                $this->queryLogger->error(
                        "{fname}\t{db_server}\t{errno}\t{error}\t{sql1line}",
                        $this->getLogContext( [
                                'method' => __METHOD__,
                                'errno' => $errno,
                                'error' => $error,
-                               'sql1line' => $sql1line,
+                               'sql1line' => mb_substr( str_replace( "\n", "\\n", $sql ), 0, 5 * 1024 ),
                                'fname' => $fname,
                                'trace' => ( new RuntimeException() )->getTraceAsString()
                        ] )
                );
-               $this->queryLogger->debug( "SQL ERROR: " . $error . "" );
+
                if ( $this->wasQueryTimeout( $error, $errno ) ) {
                        $e = new DBQueryTimeoutError( $this, $error, $errno, $sql, $fname );
                } elseif ( $this->wasConnectionError( $errno ) ) {
@@ -1608,6 +1599,25 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return $e;
        }
 
+       /**
+        * @param string $error
+        * @return DBConnectionError
+        */
+       final protected function newExceptionAfterConnectError( $error ) {
+               // Connection was not fully initialized and is not safe for use
+               $this->conn = null;
+
+               $this->connLogger->error(
+                       "Error connecting to {db_server} as user {db_user}: {error}",
+                       $this->getLogContext( [
+                               'error' => $error,
+                               'trace' => ( new RuntimeException() )->getTraceAsString()
+                       ] )
+               );
+
+               return new DBConnectionError( $this, $error );
+       }
+
        public function freeResult( $res ) {
        }
 
@@ -4297,7 +4307,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        protected function replaceLostConnection( $fname ) {
                $this->closeConnection();
-               $this->conn = false;
+               $this->conn = null;
 
                $this->handleSessionLossPreconnect();
 
@@ -4876,7 +4886,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                if ( $this->isOpen() ) {
                        // Open a new connection resource without messing with the old one
-                       $this->conn = false;
+                       $this->conn = null;
                        $this->trxEndCallbacks = []; // don't copy
                        $this->trxSectionCancelCallbacks = []; // don't copy
                        $this->handleSessionLossPreconnect(); // no trx or locks anymore
index d06bcb9..db029a3 100644 (file)
@@ -59,10 +59,6 @@ class DatabaseMssql extends Database {
        /** @var string[] */
        protected $ignoreErrors = [];
 
-       public function implicitGroupby() {
-               return false;
-       }
-
        public function implicitOrderby() {
                return false;
        }
@@ -79,53 +75,50 @@ class DatabaseMssql extends Database {
        }
 
        protected function open( $server, $user, $password, $dbName, $schema, $tablePrefix ) {
-               // Test for driver support, to avoid suppressed fatal error
                if ( !function_exists( 'sqlsrv_connect' ) ) {
                        throw new DBConnectionError(
                                $this,
-                               "Microsoft SQL Server Native (sqlsrv) functions missing.
-                               You can download the driver from: http://go.microsoft.com/fwlink/?LinkId=123470\n"
+                               "Microsoft SQL Server Native (sqlsrv) functions missing.\n
+                               You can download the driver from: http://go.microsoft.com/fwlink/?LinkId=123470"
                        );
                }
 
                $this->close();
+
+               if ( $schema !== null ) {
+                       throw $this->newExceptionAfterConnectError( "Got schema '$schema'; not supported." );
+               }
+
                $this->server = $server;
                $this->user = $user;
                $this->password = $password;
 
                $connectionInfo = [];
-
-               if ( $dbName != '' ) {
+               if ( strlen( $dbName ) ) {
                        $connectionInfo['Database'] = $dbName;
                }
-
-               // Decide which auth scenerio to use
-               // if we are using Windows auth, then don't add credentials to $connectionInfo
                if ( !$this->useWindowsAuth ) {
                        $connectionInfo['UID'] = $user;
                        $connectionInfo['PWD'] = $password;
                }
 
                AtEase::suppressWarnings();
-               $this->conn = sqlsrv_connect( $server, $connectionInfo );
+               $this->conn = sqlsrv_connect( $server, $connectionInfo ) ?: null;
                AtEase::restoreWarnings();
 
-               if ( $this->conn === false ) {
-                       $error = $this->lastError();
-                       $this->connLogger->error(
-                               "Error connecting to {db_server}: {error}",
-                               $this->getLogContext( [ 'method' => __METHOD__, 'error' => $error ] )
-                       );
-                       throw new DBConnectionError( $this, $error );
+               if ( !$this->conn ) {
+                       throw $this->newExceptionAfterConnectError( $this->lastError() );
                }
 
-               $this->currentDomain = new DatabaseDomain(
-                       ( $dbName != '' ) ? $dbName : null,
-                       null,
-                       $tablePrefix
-               );
-
-               return (bool)$this->conn;
+               try {
+                       $this->currentDomain = new DatabaseDomain(
+                               strlen( $dbName ) ? $dbName : null,
+                               null,
+                               $tablePrefix
+                       );
+               } catch ( Exception $e ) {
+                       throw $this->newExceptionAfterConnectError( $e->getMessage() );
+               }
        }
 
        /**
index 1e3fa84..b1a88ed 100644 (file)
@@ -125,7 +125,7 @@ abstract class DatabaseMysqlBase extends Database {
                $this->close();
 
                if ( $schema !== null ) {
-                       throw new DBExpectedError( $this, __CLASS__ . ": cannot use schemas ('$schema')" );
+                       throw $this->newExceptionAfterConnectError( "Got schema '$schema'; not supported." );
                }
 
                $this->server = $server;
@@ -135,23 +135,14 @@ abstract class DatabaseMysqlBase extends Database {
                $this->installErrorHandler();
                try {
                        $this->conn = $this->mysqlConnect( $this->server, $dbName );
-               } catch ( Exception $ex ) {
+               } catch ( Exception $e ) {
                        $this->restoreErrorHandler();
-                       throw $ex;
+                       throw $this->newExceptionAfterConnectError( $e->getMessage() );
                }
                $error = $this->restoreErrorHandler();
 
-               # Always log connection errors
                if ( !$this->conn ) {
-                       $error = $error ?: $this->lastError();
-                       $this->connLogger->error(
-                               "Error connecting to {db_server}: {error}",
-                               $this->getLogContext( [ 'method' => __METHOD__, 'error' => $error ] )
-                       );
-                       $this->connLogger->debug( "DB connection error\n" .
-                               "Server: $server, User: $user, Password: " .
-                               substr( $password, 0, 3 ) . "..., error: " . $error . "\n" );
-                       throw new DBConnectionError( $this, $error );
+                       throw $this->newExceptionAfterConnectError( $error ?: $this->lastError() );
                }
 
                try {
@@ -160,7 +151,6 @@ abstract class DatabaseMysqlBase extends Database {
                                null,
                                $tablePrefix
                        );
-
                        // Abstract over any insane MySQL defaults
                        $set = [ 'group_concat_max_len = 262144' ];
                        // Set SQL mode, default is turning them all off, can be overridden or skipped with null
@@ -185,11 +175,8 @@ abstract class DatabaseMysqlBase extends Database {
                                );
                        }
                } catch ( Exception $e ) {
-                       // Connection was not fully initialized and is not safe for use
-                       $this->conn = false;
+                       throw $this->newExceptionAfterConnectError( $e->getMessage() );
                }
-
-               return true;
        }
 
        protected function doSelectDomain( DatabaseDomain $domain ) {
@@ -234,7 +221,7 @@ abstract class DatabaseMysqlBase extends Database {
         *
         * @param string $realServer
         * @param string|null $dbName
-        * @return mixed Raw connection
+        * @return mixed|null Driver connection handle
         * @throws DBConnectionError
         */
        abstract protected function mysqlConnect( $realServer, $dbName );
index 0f444cd..ddb3944 100644 (file)
@@ -54,14 +54,14 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        /**
         * @param string $realServer
         * @param string|null $dbName
-        * @return bool|mysqli
+        * @return mysqli|null
         * @throws DBConnectionError
         */
        protected function mysqlConnect( $realServer, $dbName ) {
-               # Avoid suppressed fatal error, which is very hard to track down
                if ( !function_exists( 'mysqli_init' ) ) {
-                       throw new DBConnectionError( $this, "MySQLi functions missing,"
-                               . " have you compiled PHP with the --with-mysqli option?\n" );
+                       throw $this->newExceptionAfterConnectError(
+                               "MySQLi functions missing, have you compiled PHP with the --with-mysqli option?"
+                       );
                }
 
                // Other than mysql_connect, mysqli_real_connect expects an explicit port
@@ -84,7 +84,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                $mysqli = mysqli_init();
 
                $connFlags = 0;
-               if ( $this->flags & self::DBO_SSL ) {
+               if ( $this->getFlag( self::DBO_SSL ) ) {
                        $connFlags |= MYSQLI_CLIENT_SSL;
                        $mysqli->ssl_set(
                                $this->sslKeyPath,
@@ -94,10 +94,10 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                                $this->sslCiphers
                        );
                }
-               if ( $this->flags & self::DBO_COMPRESS ) {
+               if ( $this->getFlag( self::DBO_COMPRESS ) ) {
                        $connFlags |= MYSQLI_CLIENT_COMPRESS;
                }
-               if ( $this->flags & self::DBO_PERSISTENT ) {
+               if ( $this->getFlag( self::DBO_PERSISTENT ) ) {
                        $realServer = 'p:' . $realServer;
                }
 
@@ -122,7 +122,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                        return $mysqli;
                }
 
-               return false;
+               return null;
        }
 
        /**
index 840b428..a7ebc86 100644 (file)
@@ -31,22 +31,19 @@ use Exception;
  * @ingroup Database
  */
 class DatabasePostgres extends Database {
-       /** @var int|bool */
-       protected $port;
-
-       /** @var resource */
-       protected $lastResultHandle = null;
-
-       /** @var float|string */
-       private $numericVersion = null;
-       /** @var string Connect string to open a PostgreSQL connection */
-       private $connectString;
+       /** @var int|null */
+       private $port;
        /** @var string */
        private $coreSchema;
        /** @var string */
        private $tempSchema;
        /** @var string[] Map of (reserved table name => alternate table name) */
        private $keywordTableMap = [];
+       /** @var float|string */
+       private $numericVersion;
+
+       /** @var resource|null */
+       private $lastResultHandle;
 
        /**
         * @see Database::__construct()
@@ -54,7 +51,7 @@ class DatabasePostgres extends Database {
         *   - keywordTableMap : Map of reserved table names to alternative table names to use
         */
        public function __construct( array $params ) {
-               $this->port = $params['port'] ?? false;
+               $this->port = intval( $params['port'] ?? null );
                $this->keywordTableMap = $params['keywordTableMap'] ?? [];
 
                parent::__construct( $params );
@@ -64,10 +61,6 @@ class DatabasePostgres extends Database {
                return 'postgres';
        }
 
-       public function implicitGroupby() {
-               return false;
-       }
-
        public function implicitOrderby() {
                return false;
        }
@@ -87,13 +80,11 @@ class DatabasePostgres extends Database {
        }
 
        protected function open( $server, $user, $password, $dbName, $schema, $tablePrefix ) {
-               // Test for Postgres support, to avoid suppressed fatal error
                if ( !function_exists( 'pg_connect' ) ) {
-                       throw new DBConnectionError(
-                               $this,
+                       throw $this->newExceptionAfterConnectError(
                                "Postgres functions missing, have you compiled PHP with the --with-pgsql\n" .
                                "option? (Note: if you recently installed PHP, you may need to restart your\n" .
-                               "webserver and database)\n"
+                               "webserver and database)"
                        );
                }
 
@@ -104,60 +95,47 @@ class DatabasePostgres extends Database {
                $this->password = $password;
 
                $connectVars = [
-                       // pg_connect() user $user as the default database. Since a database is *required*,
-                       // at least pick a "don't care" database that is more likely to exist. This case
-                       // arrises when LoadBalancer::getConnection( $i, [], '' ) is used.
+                       // pg_connect() user $user as the default database. Since a database is required,
+                       // then pick a "don't care" database that is more likely to exist than that one.
                        'dbname' => strlen( $dbName ) ? $dbName : 'postgres',
                        'user' => $user,
                        'password' => $password
                ];
-               if ( $server != false && $server != '' ) {
+               if ( strlen( $server ) ) {
                        $connectVars['host'] = $server;
                }
-               if ( (int)$this->port > 0 ) {
-                       $connectVars['port'] = (int)$this->port;
+               if ( $this->port > 0 ) {
+                       $connectVars['port'] = $this->port;
                }
-               if ( $this->flags & self::DBO_SSL ) {
+               if ( $this->getFlag( self::DBO_SSL ) ) {
                        $connectVars['sslmode'] = 'require';
                }
-
-               $this->connectString = $this->makeConnectionString( $connectVars );
+               $connectString = $this->makeConnectionString( $connectVars );
 
                $this->installErrorHandler();
                try {
-                       // Use new connections to let LoadBalancer/LBFactory handle reuse
-                       $this->conn = pg_connect( $this->connectString, PGSQL_CONNECT_FORCE_NEW );
-               } catch ( Exception $ex ) {
+                       $this->conn = pg_connect( $connectString, PGSQL_CONNECT_FORCE_NEW ) ?: null;
+               } catch ( Exception $e ) {
                        $this->restoreErrorHandler();
-                       throw $ex;
+                       throw $this->newExceptionAfterConnectError( $e->getMessage() );
                }
-               $phpError = $this->restoreErrorHandler();
+               $error = $this->restoreErrorHandler();
 
                if ( !$this->conn ) {
-                       $this->queryLogger->debug(
-                               "DB connection error\n" .
-                               "Server: $server, Database: $dbName, User: $user, Password: " .
-                               substr( $password, 0, 3 ) . "...\n"
-                       );
-                       $this->queryLogger->debug( $this->lastError() . "\n" );
-                       throw new DBConnectionError( $this, str_replace( "\n", ' ', $phpError ) );
+                       throw $this->newExceptionAfterConnectError( $error ?: $this->lastError() );
                }
 
                try {
-                       // If called from the command-line (e.g. importDump), only show errors.
-                       // No transaction should be open at this point, so the problem of the SET
-                       // effects being rolled back should not be an issue.
+                       // Since no transaction is active at this point, any SET commands should apply
+                       // for the entire session (e.g. will not be reverted on transaction rollback).
                        // See https://www.postgresql.org/docs/8.3/sql-set.html
-                       $variables = [];
-                       if ( $this->cliMode ) {
-                               $variables['client_min_messages'] = 'ERROR';
-                       }
-                       $variables += [
+                       $variables = [
                                'client_encoding' => 'UTF8',
                                'datestyle' => 'ISO, YMD',
                                'timezone' => 'GMT',
                                'standard_conforming_strings' => 'on',
-                               'bytea_output' => 'escape'
+                               'bytea_output' => 'escape',
+                               'client_min_messages' => 'ERROR'
                        ];
                        foreach ( $variables as $var => $val ) {
                                $this->query(
@@ -166,12 +144,10 @@ class DatabasePostgres extends Database {
                                        self::QUERY_IGNORE_DBO_TRX | self::QUERY_NO_RETRY
                                );
                        }
-
                        $this->determineCoreSchema( $schema );
                        $this->currentDomain = new DatabaseDomain( $dbName, $schema, $tablePrefix );
                } catch ( Exception $e ) {
-                       // Connection was not fully initialized and is not safe for use
-                       $this->conn = false;
+                       throw $this->newExceptionAfterConnectError( $e->getMessage() );
                }
        }
 
@@ -1026,7 +1002,7 @@ __INDEXATTR__;
         * Values may contain magic keywords like "$user"
         * @since 1.19
         *
-        * @param array $search_path List of schemas to be searched by default
+        * @param string[] $search_path List of schemas to be searched by default
         */
        private function setSearchPath( $search_path ) {
                $this->query(
@@ -1066,11 +1042,7 @@ __INDEXATTR__;
                                $this->queryLogger->debug(
                                        "Schema \"" . $desiredSchema . "\" already in the search path\n" );
                        } else {
-                               /**
-                                * Prepend our schema (e.g. 'mediawiki') in front
-                                * of the search path
-                                * Fixes T17816
-                                */
+                               // Prepend the desired schema to the search path (T17816)
                                $search_path = $this->getSearchPath();
                                array_unshift( $search_path, $this->addIdentifierQuotes( $desiredSchema ) );
                                $this->setSearchPath( $search_path );
index 11dda2f..cb1b842 100644 (file)
@@ -60,6 +60,9 @@ class DatabaseSqlite extends Database {
        /** @var bool Whether full text is enabled */
        private static $fulltextEnabled = null;
 
+       /** @var string[] See https://www.sqlite.org/lang_transaction.html */
+       private static $VALID_TRX_MODES = [ '', 'DEFERRED', 'IMMEDIATE', 'EXCLUSIVE' ];
+
        /**
         * Additional params include:
         *   - dbDirectory : directory containing the DB and the lock file directory
@@ -77,8 +80,7 @@ class DatabaseSqlite extends Database {
                        $this->dbDir = $p['dbDirectory'];
                }
 
-               // Set a dummy user to make initConnection() trigger open()
-               parent::__construct( [ 'user' => '@' ] + $p );
+               parent::__construct( $p );
 
                $this->trxMode = strtoupper( $p['trxMode'] ?? '' );
 
@@ -123,22 +125,13 @@ class DatabaseSqlite extends Database {
                return 'sqlite';
        }
 
-       /**
-        * @todo Check if it should be true like parent class
-        *
-        * @return bool
-        */
-       public function implicitGroupby() {
-               return false;
-       }
-
        protected function open( $server, $user, $pass, $dbName, $schema, $tablePrefix ) {
                $this->close();
 
                // Note that for SQLite, $server, $user, and $pass are ignored
 
                if ( $schema !== null ) {
-                       throw new DBExpectedError( $this, __CLASS__ . ": cannot use schemas ('$schema')" );
+                       throw $this->newExceptionAfterConnectError( "Got schema '$schema'; not supported." );
                }
 
                if ( $this->dbPath !== null ) {
@@ -146,59 +139,48 @@ class DatabaseSqlite extends Database {
                } elseif ( $this->dbDir !== null ) {
                        $path = self::generateFileName( $this->dbDir, $dbName );
                } else {
-                       throw new DBExpectedError( $this, __CLASS__ . ": DB path or directory required" );
+                       throw $this->newExceptionAfterConnectError( "DB path or directory required" );
                }
 
-               if ( !in_array( $this->trxMode, [ '', 'DEFERRED', 'IMMEDIATE', 'EXCLUSIVE' ], true ) ) {
-                       throw new DBExpectedError(
-                               $this,
-                               __CLASS__ . ": invalid transaction mode '{$this->trxMode}'"
-                       );
+               if ( !self::isProcessMemoryPath( $path ) && !is_readable( $path ) ) {
+                       throw $this->newExceptionAfterConnectError( 'SQLite database file is not readable' );
+               } elseif ( !in_array( $this->trxMode, self::$VALID_TRX_MODES, true ) ) {
+                       throw $this->newExceptionAfterConnectError( "Got mode '{$this->trxMode}' for BEGIN" );
                }
 
-               if ( !self::isProcessMemoryPath( $path ) && !is_readable( $path ) ) {
-                       $error = "SQLite database file not readable";
-                       $this->connLogger->error(
-                               "Error connecting to {db_server}: {error}",
-                               $this->getLogContext( [ 'method' => __METHOD__, 'error' => $error ] )
-                       );
-                       throw new DBConnectionError( $this, $error );
+               $attributes = [];
+               if ( $this->getFlag( self::DBO_PERSISTENT ) ) {
+                       // Persistent connections can avoid some schema index reading overhead.
+                       // On the other hand, they can cause horrible contention with DBO_TRX.
+                       if ( $this->getFlag( self::DBO_TRX ) || $this->getFlag( self::DBO_DEFAULT ) ) {
+                               $this->connLogger->warning(
+                                       __METHOD__ . ": ignoring DBO_PERSISTENT due to DBO_TRX or DBO_DEFAULT",
+                                       $this->getLogContext()
+                               );
+                       } else {
+                               $attributes[PDO::ATTR_PERSISTENT] = true;
+                       }
                }
 
                try {
-                       $conn = new PDO(
-                               "sqlite:$path",
-                               '',
-                               '',
-                               [ PDO::ATTR_PERSISTENT => (bool)( $this->flags & self::DBO_PERSISTENT ) ]
-                       );
-                       // Set error codes only, don't raise exceptions
-                       $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
+                       $this->conn = new PDO( "sqlite:$path", null, null, $attributes );
                } catch ( PDOException $e ) {
-                       $error = $e->getMessage();
-                       $this->connLogger->error(
-                               "Error connecting to {db_server}: {error}",
-                               $this->getLogContext( [ 'method' => __METHOD__, 'error' => $error ] )
-                       );
-                       throw new DBConnectionError( $this, $error );
+                       throw $this->newExceptionAfterConnectError( $e->getMessage() );
                }
 
-               $this->conn = $conn;
                $this->currentDomain = new DatabaseDomain( $dbName, null, $tablePrefix );
 
                try {
                        $flags = self::QUERY_IGNORE_DBO_TRX | self::QUERY_NO_RETRY;
                        // Enforce LIKE to be case sensitive, just like MySQL
                        $this->query( 'PRAGMA case_sensitive_like = 1', __METHOD__, $flags );
-                       // Apply an optimizations or requirements regarding fsync() usage
+                       // Apply optimizations or requirements regarding fsync() usage
                        $sync = $this->connectionVariables['synchronous'] ?? null;
                        if ( in_array( $sync, [ 'EXTRA', 'FULL', 'NORMAL', 'OFF' ], true ) ) {
                                $this->query( "PRAGMA synchronous = $sync", __METHOD__, $flags );
                        }
                } catch ( Exception $e ) {
-                       // Connection was not fully initialized and is not safe for use
-                       $this->conn = false;
-                       throw $e;
+                       throw $this->newExceptionAfterConnectError( $e->getMessage() );
                }
        }
 
index ef7f1e2..7e54221 100644 (file)
@@ -87,7 +87,7 @@ interface IDatabase {
        /** @var int Combine list with OR clauses */
        const LIST_OR = 4;
 
-       /** @var int Enable debug logging */
+       /** @var int Enable debug logging of all SQL queries */
        const DBO_DEBUG = 1;
        /** @var int Disable query buffering (only one result set can be iterated at a time) */
        const DBO_NOBUFFER = 2;
@@ -238,14 +238,6 @@ interface IDatabase {
         */
        public function setLazyMasterHandle( IDatabase $conn );
 
-       /**
-        * Returns true if this database does an implicit sort when doing GROUP BY
-        *
-        * @return bool
-        * @deprecated Since 1.30; only use grouped or aggregated fields in the SELECT
-        */
-       public function implicitGroupby();
-
        /**
         * Returns true if this database does an implicit order by when the column has an index
         * For example: SELECT page_title FROM page LIMIT 1
@@ -260,15 +252,6 @@ interface IDatabase {
         */
        public function lastQuery();
 
-       /**
-        * Returns true if the connection may have been used for write queries.
-        * Should return true if unsure.
-        *
-        * @return bool
-        * @deprecated Since 1.31; use lastDoneWrites()
-        */
-       public function doneWrites();
-
        /**
         * Returns the last time the connection may have been used for write queries.
         * Should return a timestamp if unsure.
@@ -336,13 +319,7 @@ interface IDatabase {
        /**
         * Set a flag for this connection
         *
-        * @param int $flag DBO_* constants from Defines.php:
-        *   - DBO_DEBUG: output some debug info (same as debug())
-        *   - DBO_NOBUFFER: don't buffer results (inverse of bufferResults())
-        *   - DBO_TRX: automatically start transactions
-        *   - DBO_DEFAULT: automatically sets DBO_TRX if not in command line mode
-        *       and removes it in command line mode
-        *   - DBO_PERSISTENT: use persistant database connection
+        * @param int $flag IDatabase::DBO_DEBUG, IDatabase::DBO_NOBUFFER, or IDatabase::DBO_TRX
         * @param string $remember IDatabase::REMEMBER_* constant [default: REMEMBER_NOTHING]
         */
        public function setFlag( $flag, $remember = self::REMEMBER_NOTHING );
@@ -350,13 +327,7 @@ interface IDatabase {
        /**
         * Clear a flag for this connection
         *
-        * @param int $flag DBO_* constants from Defines.php:
-        *   - DBO_DEBUG: output some debug info (same as debug())
-        *   - DBO_NOBUFFER: don't buffer results (inverse of bufferResults())
-        *   - DBO_TRX: automatically start transactions
-        *   - DBO_DEFAULT: automatically sets DBO_TRX if not in command line mode
-        *       and removes it in command line mode
-        *   - DBO_PERSISTENT: use persistant database connection
+        * @param int $flag IDatabase::DBO_DEBUG, IDatabase::DBO_NOBUFFER, or IDatabase::DBO_TRX
         * @param string $remember IDatabase::REMEMBER_* constant [default: REMEMBER_NOTHING]
         */
        public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING );
@@ -372,11 +343,7 @@ interface IDatabase {
        /**
         * Returns a boolean whether the flag $flag is set for this connection
         *
-        * @param int $flag DBO_* constants from Defines.php:
-        *   - DBO_DEBUG: output some debug info (same as debug())
-        *   - DBO_NOBUFFER: don't buffer results (inverse of bufferResults())
-        *   - DBO_TRX: automatically start transactions
-        *   - DBO_PERSISTENT: use persistant database connection
+        * @param int $flag One of the class IDatabase::DBO_* constants
         * @return bool
         */
        public function getFlag( $flag );
@@ -390,14 +357,6 @@ interface IDatabase {
         */
        public function getDomainID();
 
-       /**
-        * Alias for getDomainID()
-        *
-        * @return string
-        * @deprecated 1.30
-        */
-       public function getWikiID();
-
        /**
         * Get the type of the DBMS, as it appears in $wgDBtype.
         *
index a85e1e5..4426654 100644 (file)
@@ -651,14 +651,6 @@ abstract class LBFactory implements ILBFactory {
                $this->indexAliases = $aliases;
        }
 
-       /**
-        * @param string $prefix
-        * @deprecated Since 1.33
-        */
-       public function setDomainPrefix( $prefix ) {
-               $this->setLocalDomainPrefix( $prefix );
-       }
-
        public function setLocalDomainPrefix( $prefix ) {
                $this->localDomain = new DatabaseDomain(
                        $this->localDomain->getDatabase(),
index 1ef1d09..46d8c06 100644 (file)
@@ -656,7 +656,7 @@ class LoadBalancer implements ILoadBalancer {
                                $ok = true; // no applicable loads
                        }
                } finally {
-                       # Restore the old position, as this is not used for lag-protection but for throttling
+                       // Restore the old position; this is used for throttling, not lag-protection
                        $this->waitForPos = $oldPos;
                }
 
@@ -673,7 +673,7 @@ class LoadBalancer implements ILoadBalancer {
 
                        $ok = true;
                        for ( $i = 1; $i < $serverCount; $i++ ) {
-                               if ( $this->groupLoads[self::GROUP_GENERIC][$i] > 0 ) {
+                               if ( $this->serverHasLoadInAnyGroup( $i ) ) {
                                        $start = microtime( true );
                                        $ok = $this->doWait( $i, true, $timeout ) && $ok;
                                        $timeout -= intval( microtime( true ) - $start );
@@ -683,13 +683,27 @@ class LoadBalancer implements ILoadBalancer {
                                }
                        }
                } finally {
-                       # Restore the old position, as this is not used for lag-protection but for throttling
+                       // Restore the old position; this is used for throttling, not lag-protection
                        $this->waitForPos = $oldPos;
                }
 
                return $ok;
        }
 
+       /**
+        * @param int $i Specific server index
+        * @return bool
+        */
+       private function serverHasLoadInAnyGroup( $i ) {
+               foreach ( $this->groupLoads as $loadsByIndex ) {
+                       if ( ( $loadsByIndex[$i] ?? 0 ) > 0 ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
        /**
         * @param DBMasterPos|bool $pos
         */
@@ -1922,15 +1936,6 @@ class LoadBalancer implements ILoadBalancer {
                return $this->laggedReplicaMode;
        }
 
-       /**
-        * @return bool
-        * @since 1.27
-        * @deprecated Since 1.28; use laggedReplicaUsed()
-        */
-       public function laggedSlaveUsed() {
-               return $this->laggedReplicaUsed();
-       }
-
        public function getReadOnlyReason( $domain = false, IDatabase $conn = null ) {
                if ( $this->readOnlyReason !== false ) {
                        return $this->readOnlyReason;
@@ -2203,14 +2208,6 @@ class LoadBalancer implements ILoadBalancer {
                $this->indexAliases = $aliases;
        }
 
-       /**
-        * @param string $prefix
-        * @deprecated Since 1.33
-        */
-       public function setDomainPrefix( $prefix ) {
-               $this->setLocalDomainPrefix( $prefix );
-       }
-
        public function setLocalDomainPrefix( $prefix ) {
                // Find connections to explicit foreign domains still marked as in-use...
                $domainsInUse = [];
index e8dd898..9e63ffe 100644 (file)
@@ -153,6 +153,19 @@ class LogFormatter {
                        : self::FOR_PUBLIC;
        }
 
+       /**
+        * Check if a log item type can be displayed
+        * @return bool
+        */
+       public function canViewLogType() {
+               // If the user doesn't have the right permission to view the specific
+               // log type, return false
+               $logRestrictions = $this->context->getConfig()->get( 'LogRestrictions' );
+               $type = $this->entry->getType();
+               return !isset( $logRestrictions[$type] )
+                       || $this->context->getUser()->isAllowed( $logRestrictions[$type] );
+       }
+
        /**
         * Check if a log item can be displayed
         * @param int $field LogPage::DELETED_* constant
@@ -161,9 +174,10 @@ class LogFormatter {
        protected function canView( $field ) {
                if ( $this->audience == self::FOR_THIS_USER ) {
                        return LogEventsList::userCanBitfield(
-                               $this->entry->getDeleted(), $field, $this->context->getUser() );
+                               $this->entry->getDeleted(), $field, $this->context->getUser() ) &&
+                               self::canViewLogType();
                } else {
-                       return !$this->entry->isDeleted( $field );
+                       return !$this->entry->isDeleted( $field ) && self::canViewLogType();
                }
        }
 
index e07b166..f7fc46f 100644 (file)
@@ -131,7 +131,7 @@ class BitmapHandler extends TransformationalImageHandler {
         * @param File $image File associated with this thumbnail
         * @param array $params Array with scaler params
         *
-        * @return MediaTransformError|bool Error object if error occurred, false (=no error) otherwise
+        * @return MediaTransformError|false Error object if error occurred, false (=no error) otherwise
         */
        protected function transformImageMagick( $image, $params ) {
                # use ImageMagick
@@ -275,7 +275,7 @@ class BitmapHandler extends TransformationalImageHandler {
         * @param File $image File associated with this thumbnail
         * @param array $params Array with scaler params
         *
-        * @return MediaTransformError Error|bool object if error occurred, false (=no error) otherwise
+        * @return MediaTransformError|false Error object if error occurred, false (=no error) otherwise
         */
        protected function transformImageMagickExt( $image, $params ) {
                global $wgSharpenReductionThreshold, $wgSharpenParameter, $wgMaxAnimatedGifArea,
@@ -368,7 +368,7 @@ class BitmapHandler extends TransformationalImageHandler {
         * @param File $image File associated with this thumbnail
         * @param array $params Array with scaler params
         *
-        * @return MediaTransformError Error|bool object if error occurred, false (=no error) otherwise
+        * @return MediaTransformError|false Error object if error occurred, false (=no error) otherwise
         */
        protected function transformCustom( $image, $params ) {
                # Use a custom convert command
index 9a9c0a6..2f5fa90 100644 (file)
@@ -53,7 +53,7 @@ class BmpHandler extends BitmapHandler {
         *
         * @param File|FSFile $image
         * @param string $filename
-        * @return array
+        * @return array|false
         */
        function getImageSize( $image, $filename ) {
                $f = fopen( $filename, 'rb' );
index 13a39ed..92fad52 100644 (file)
@@ -61,7 +61,7 @@ class DjVuImage {
 
        /**
         * Return data in the style of getimagesize()
-        * @return array|bool Array or false on failure
+        * @return array|false Array or false on failure
         */
        public function getImageSize() {
                $data = $this->getInfo();
index 1760eb8..fa9e1dc 100644 (file)
@@ -166,7 +166,7 @@ class ExifBitmapHandler extends BitmapHandler {
         *
         * @param File|FSFile $image
         * @param string $path
-        * @return array
+        * @return array|false
         */
        function getImageSize( $image, $path ) {
                $gis = parent::getImageSize( $image, $path );
index 7dd0491..3abc6b7 100644 (file)
@@ -103,7 +103,7 @@ abstract class MediaHandler {
         * @param File|FSFile $image The image object, or false if there isn't one.
         *   Warning, FSFile::getPropsFromPath might pass an FSFile instead of File (!)
         * @param string $path The filename
-        * @return array|bool Follow the format of PHP getimagesize() internal function.
+        * @return array|false Follow the format of PHP getimagesize() internal function.
         *   See https://www.php.net/getimagesize. MediaWiki will only ever use the
         *   first two array keys (the width and height), and the 'bits' associative
         *   key. All other array keys are ignored. Returning a 'bits' key is optional
index ac332b7..6ae6426 100644 (file)
 
 /**
  * @ingroup Media
+ * @deprecated since 1.34
  */
 class SVGMetadataExtractor {
-       static function getMetadata( $filename ) {
+       /**
+        * @param string $filename
+        * @return array
+        * @deprecated since 1.34, use SVGReader->getMetadata() directly
+        */
+       public static function getMetadata( $filename ) {
+               wfDeprecated( __METHOD__, '1.34' );
+
                $svg = new SVGReader( $filename );
 
                return $svg->getMetadata();
index bdda674..98c22a3 100644 (file)
@@ -381,7 +381,7 @@ class SvgHandler extends ImageHandler {
         * @param File|FSFile $file
         * @param string $path Unused
         * @param bool|array $metadata
-        * @return array
+        * @return array|false
         */
        function getImageSize( $file, $path, $metadata = false ) {
                if ( $metadata === false && $file instanceof File ) {
@@ -438,8 +438,10 @@ class SvgHandler extends ImageHandler {
         */
        public function getMetadata( $file, $filename ) {
                $metadata = [ 'version' => self::SVG_METADATA_VERSION ];
+
                try {
-                       $metadata += SVGMetadataExtractor::getMetadata( $filename );
+                       $svgReader = new SVGReader( $filename );
+                       $metadata += $svgReader->getMetadata();
                } catch ( Exception $e ) { // @todo SVG specific exceptions
                        // File not found, broken, etc.
                        $metadata['error'] = [
index e2cc1b2..5294530 100644 (file)
@@ -58,7 +58,7 @@ class XCFHandler extends BitmapHandler {
         *
         * @param File|FSFile $image
         * @param string $filename
-        * @return array
+        * @return array|false
         */
        function getImageSize( $image, $filename ) {
                $header = self::getXCFMetaData( $filename );
index 9226875..6cc63bf 100644 (file)
@@ -27,6 +27,7 @@ use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\DBError;
 use Wikimedia\Rdbms\DBQueryError;
 use Wikimedia\Rdbms\DBConnectionError;
+use Wikimedia\Rdbms\IMaintainableDatabase;
 use Wikimedia\Rdbms\LoadBalancer;
 use Wikimedia\ScopedCallback;
 use Wikimedia\WaitConditionLoop;
@@ -165,7 +166,7 @@ class SqlBagOStuff extends MediumSpecificBagOStuff {
         * Get a connection to the specified database
         *
         * @param int $serverIndex
-        * @return Database
+        * @return IMaintainableDatabase
         * @throws MWException
         */
        protected function getDB( $serverIndex ) {
@@ -199,11 +200,11 @@ class SqlBagOStuff extends MediumSpecificBagOStuff {
                        $index = $this->replicaOnly ? DB_REPLICA : DB_MASTER;
                        if ( $lb->getServerType( $lb->getWriterIndex() ) !== 'sqlite' ) {
                                // Keep a separate connection to avoid contention and deadlocks
-                               $db = $lb->getConnection( $index, [], false, $lb::CONN_TRX_AUTOCOMMIT );
+                               $db = $lb->getConnectionRef( $index, [], false, $lb::CONN_TRX_AUTOCOMMIT );
                        } else {
                                // However, SQLite has the opposite behavior due to DB-level locking.
                                // Stock sqlite MediaWiki installs use a separate sqlite cache DB instead.
-                               $db = $lb->getConnection( $index );
+                               $db = $lb->getConnectionRef( $index );
                        }
                }
 
index 54036eb..9426dce 100644 (file)
@@ -33,7 +33,7 @@ abstract class AlphabeticPager extends IndexPager {
         *
         * @return string HTML
         */
-       function getNavigationBar() {
+       public function getNavigationBar() {
                if ( !$this->isNavigationBarShown() ) {
                        return '';
                }
index 9cfbfbf..45c310a 100644 (file)
@@ -30,7 +30,7 @@
  * @ingroup Pager
  */
 interface Pager {
-       function getNavigationBar();
+       public function getNavigationBar();
 
-       function getBody();
+       public function getBody();
 }
index 5aa1a69..a7916c5 100644 (file)
@@ -1187,39 +1187,44 @@ class CoreParserFunctions {
         */
        public static function pageid( $parser, $title = null ) {
                $t = Title::newFromText( $title );
-               if ( is_null( $t ) ) {
+               if ( !$t ) {
                        return '';
+               } elseif ( !$t->canExist() || $t->isExternal() ) {
+                       return 0; // e.g. special page or interwiki link
                }
-               // Use title from parser to have correct pageid after edit
+
+               $parserOutput = $parser->getOutput();
+
                if ( $t->equals( $parser->getTitle() ) ) {
-                       $t = $parser->getTitle();
-                       return $t->getArticleID();
-               }
+                       // Revision is for the same title that is currently being parsed.
+                       // Use the title from Parser in case a new page ID was injected into it.
+                       $parserOutput->setFlag( 'vary-page-id' );
+                       $id = $parser->getTitle()->getArticleID();
+                       if ( $id ) {
+                               $parserOutput->setSpeculativePageIdUsed( $id );
+                       }
 
-               // These can't have ids
-               if ( !$t->canExist() || $t->isExternal() ) {
-                       return 0;
+                       return $id;
                }
 
-               // Check the link cache, maybe something already looked it up.
+               // Check the link cache for the title
                $linkCache = MediaWikiServices::getInstance()->getLinkCache();
                $pdbk = $t->getPrefixedDBkey();
                $id = $linkCache->getGoodLinkID( $pdbk );
-               if ( $id != 0 ) {
-                       $parser->mOutput->addLink( $t, $id );
-                       return $id;
-               }
-               if ( $linkCache->isBadLink( $pdbk ) ) {
-                       $parser->mOutput->addLink( $t, 0 );
+               if ( $id != 0 || $linkCache->isBadLink( $pdbk ) ) {
+                       $parserOutput->addLink( $t, $id );
+
                        return $id;
                }
 
                // We need to load it from the DB, so mark expensive
                if ( $parser->incrementExpensiveFunctionCount() ) {
                        $id = $t->getArticleID();
-                       $parser->mOutput->addLink( $t, $id );
+                       $parserOutput->addLink( $t, $id );
+
                        return $id;
                }
+
                return null;
        }
 
index 5821d3f..e5bf94a 100644 (file)
@@ -26,7 +26,9 @@ use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Special\SpecialPageFactory;
+use Psr\Log\NullLogger;
 use Wikimedia\ScopedCallback;
+use Psr\Log\LoggerInterface;
 
 /**
  * @defgroup Parser Parser
@@ -294,6 +296,9 @@ class Parser {
        /** @var NamespaceInfo */
        private $nsInfo;
 
+       /** @var LoggerInterface */
+       private $logger;
+
        /**
         * TODO Make this a const when HHVM support is dropped (T192166)
         *
@@ -333,11 +338,18 @@ class Parser {
         * @param SpecialPageFactory|null $spFactory
         * @param LinkRendererFactory|null $linkRendererFactory
         * @param NamespaceInfo|null $nsInfo
+        * @param LoggerInterface|null $logger
         */
        public function __construct(
-               $svcOptions = null, MagicWordFactory $magicWordFactory = null,
-               Language $contLang = null, ParserFactory $factory = null, $urlProtocols = null,
-               SpecialPageFactory $spFactory = null, $linkRendererFactory = null, $nsInfo = null
+               $svcOptions = null,
+               MagicWordFactory $magicWordFactory = null,
+               Language $contLang = null,
+               ParserFactory $factory = null,
+               $urlProtocols = null,
+               SpecialPageFactory $spFactory = null,
+               $linkRendererFactory = null,
+               $nsInfo = null,
+               $logger = null
        ) {
                $services = MediaWikiServices::getInstance();
                if ( !$svcOptions || is_array( $svcOptions ) ) {
@@ -382,6 +394,7 @@ class Parser {
                $this->specialPageFactory = $spFactory ?? $services->getSpecialPageFactory();
                $this->linkRendererFactory = $linkRendererFactory ?? $services->getLinkRendererFactory();
                $this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
+               $this->logger = $logger ?: new NullLogger();
        }
 
        /**
@@ -2770,16 +2783,16 @@ class Parser {
                                $value = wfEscapeWikiText( $subjPage->getPrefixedURL() );
                                break;
                        case 'pageid': // requested in T25427
-                               $pageid = $this->getTitle()->getArticleID();
-                               if ( $pageid == 0 ) {
-                                       # 0 means the page doesn't exist in the database,
-                                       # which means the user is previewing a new page.
-                                       # The vary-revision flag must be set, because the magic word
-                                       # will have a different value once the page is saved.
-                                       $this->mOutput->setFlag( 'vary-revision' );
-                                       wfDebug( __METHOD__ . ": {{PAGEID}} used in a new page, setting vary-revision" );
+                               # Inform the edit saving system that getting the canonical output
+                               # after page insertion requires a parse that used that exact page ID
+                               $this->setOutputFlag( 'vary-page-id', '{{PAGEID}} used' );
+                               $value = $this->mTitle->getArticleID();
+                               if ( !$value ) {
+                                       $value = $this->mOptions->getSpeculativePageId();
+                                       if ( $value ) {
+                                               $this->mOutput->setSpeculativePageIdUsed( $value );
+                                       }
                                }
-                               $value = $pageid ?: null;
                                break;
                        case 'revisionid':
                                if (
@@ -2793,15 +2806,13 @@ class Parser {
                                        if ( $this->getRevisionId() || $this->mOptions->getSpeculativeRevId() ) {
                                                $value = '-';
                                        } else {
-                                               $this->mOutput->setFlag( 'vary-revision-exists' );
-                                               wfDebug( __METHOD__ . ": {{REVISIONID}} used, setting vary-revision-exists" );
+                                               $this->setOutputFlag( 'vary-revision-exists', '{{REVISIONID}} used' );
                                                $value = '';
                                        }
                                } else {
                                        # Inform the edit saving system that getting the canonical output after
-                                       # revision insertion requires another parse using the actual revision ID
-                                       $this->mOutput->setFlag( 'vary-revision-id' );
-                                       wfDebug( __METHOD__ . ": {{REVISIONID}} used, setting vary-revision-id" );
+                                       # revision insertion requires a parse that used that exact revision ID
+                                       $this->setOutputFlag( 'vary-revision-id', '{{REVISIONID}} used' );
                                        $value = $this->getRevisionId();
                                        if ( $value === 0 ) {
                                                $rev = $this->getRevisionObject();
@@ -2836,8 +2847,7 @@ class Parser {
                        case 'revisionuser':
                                # Inform the edit saving system that getting the canonical output after
                                # revision insertion requires a parse that used the actual user ID
-                               $this->mOutput->setFlag( 'vary-user' );
-                               wfDebug( __METHOD__ . ": {{REVISIONUSER}} used, setting vary-user" );
+                               $this->setOutputFlag( 'vary-user', '{{REVISIONUSER}} used' );
                                $value = $this->getRevisionUser();
                                break;
                        case 'revisionsize':
@@ -3007,8 +3017,7 @@ class Parser {
                        if ( $resNow !== $resThen ) {
                                # Inform the edit saving system that getting the canonical output after
                                # revision insertion requires a parse that used an actual revision timestamp
-                               $this->mOutput->setFlag( 'vary-revision-timestamp' );
-                               wfDebug( __METHOD__ . ": $variable used, setting vary-revision-timestamp" );
+                               $this->setOutputFlag( 'vary-revision-timestamp', "$variable used" );
                        }
                }
 
@@ -3105,8 +3114,10 @@ class Parser {
                if ( $frame === false ) {
                        $frame = $this->getPreprocessor()->newFrame();
                } elseif ( !( $frame instanceof PPFrame ) ) {
-                       wfDebug( __METHOD__ . " called using plain parameters instead of "
-                               . "a PPFrame instance. Creating custom frame.\n" );
+                       $this->logger->debug(
+                               __METHOD__ . " called using plain parameters instead of " .
+                               "a PPFrame instance. Creating custom frame."
+                       );
                        $frame = $this->getPreprocessor()->newCustomFrame( $frame );
                }
 
@@ -3407,8 +3418,10 @@ class Parser {
                                        }
                                } elseif ( $this->nsInfo->isNonincludable( $title->getNamespace() ) ) {
                                        $found = false; # access denied
-                                       wfDebug( __METHOD__ . ": template inclusion denied for " .
-                                               $title->getPrefixedDBkey() . "\n" );
+                                       $this->logger->debug(
+                                               __METHOD__ .
+                                               ": template inclusion denied for " . $title->getPrefixedDBkey()
+                                       );
                                } else {
                                        list( $text, $title ) = $this->getTemplateDom( $title );
                                        if ( $text !== false ) {
@@ -3446,7 +3459,7 @@ class Parser {
                                $this->addTrackingCategory( 'template-loop-category' );
                                $this->mOutput->addWarning( wfMessage( 'template-loop-warning',
                                        wfEscapeWikiText( $titleText ) )->text() );
-                               wfDebug( __METHOD__ . ": template loop broken at '$titleText'\n" );
+                               $this->logger->debug( __METHOD__ . ": template loop broken at '$titleText'" );
                        }
                }
 
@@ -3740,8 +3753,7 @@ class Parser {
                                $this->mOutput->addTemplate( $dep['title'], $dep['page_id'], $dep['rev_id'] );
                                if ( $dep['title']->equals( $this->getTitle() ) ) {
                                        // Self-transclusion; final result may change based on the new page version
-                                       $this->mOutput->setFlag( 'vary-revision' );
-                                       wfDebug( __METHOD__ . ": self transclusion, setting vary-revision" );
+                                       $this->setOutputFlag( 'vary-revision', 'Self transclusion' );
                                }
                        }
                }
@@ -4685,7 +4697,7 @@ class Parser {
                                '~~~' => $sigText
                        ] );
                        # The main two signature forms used above are time-sensitive
-                       $this->mOutput->setFlag( 'user-signature' );
+                       $this->setOutputFlag( 'user-signature', 'User signature detected' );
                }
 
                # Context links ("pipe tricks"): [[|name]] and [[name (context)|]]
@@ -4750,7 +4762,7 @@ class Parser {
 
                if ( mb_strlen( $nickname ) > $this->svcOptions->get( 'MaxSigChars' ) ) {
                        $nickname = $username;
-                       wfDebug( __METHOD__ . ": $username has overlong signature.\n" );
+                       $this->logger->debug( __METHOD__ . ": $username has overlong signature." );
                } elseif ( $fancySig !== false ) {
                        # Sig. might contain markup; validate this
                        if ( $this->validateSig( $nickname ) !== false ) {
@@ -4759,7 +4771,7 @@ class Parser {
                        } else {
                                # Failed to validate; fall back to the default
                                $nickname = $username;
-                               wfDebug( __METHOD__ . ": $username has bad XML tags in signature.\n" );
+                               $this->logger->debug( __METHOD__ . ": $username has bad XML tags in signature." );
                        }
                }
 
@@ -5256,7 +5268,8 @@ class Parser {
                                                                        $handlerOptions[$paramName] = $match;
                                                                } else {
                                                                        // Guess not, consider it as caption.
-                                                                       wfDebug( "$parameterMatch failed parameter validation\n" );
+                                                                       $this->logger->debug(
+                                                                               "$parameterMatch failed parameter validation" );
                                                                        $label = $parameterMatch;
                                                                }
                                                }
@@ -5642,7 +5655,7 @@ class Parser {
         * @deprecated since 1.28; use getOutput()->updateCacheExpiry()
         */
        public function disableCache() {
-               wfDebug( "Parser output marked as uncacheable.\n" );
+               $this->logger->debug( "Parser output marked as uncacheable." );
                if ( !$this->mOutput ) {
                        throw new MWException( __METHOD__ .
                                " can only be called when actually parsing something" );
@@ -5922,19 +5935,21 @@ class Parser {
         * @since 1.23 (public since 1.23)
         */
        public function getRevisionObject() {
-               if ( !is_null( $this->mRevisionObject ) ) {
+               if ( $this->mRevisionObject ) {
                        return $this->mRevisionObject;
                }
 
                // NOTE: try to get the RevisionObject even if mRevisionId is null.
-               // This is useful when parsing revision that has not yet been saved.
+               // This is useful when parsing revision that has not yet been saved.
                // However, if we get back a saved revision even though we are in
                // preview mode, we'll have to ignore it, see below.
                // NOTE: This callback may be used to inject an OLD revision that was
                // already loaded, so "current" is a bit of a misnomer. We can't just
                // skip it if mRevisionId is set.
                $rev = call_user_func(
-                       $this->mOptions->getCurrentRevisionCallback(), $this->getTitle(), $this
+                       $this->mOptions->getCurrentRevisionCallback(),
+                       $this->getTitle(),
+                       $this
                );
 
                if ( $this->mRevisionId === null && $rev && $rev->getId() ) {
@@ -6448,4 +6463,14 @@ class Parser {
                OutputPage::setupOOUI();
                $this->mOutput->setEnableOOUI( true );
        }
+
+       /**
+        * @param string $flag
+        * @param string $reason
+        */
+       protected function setOutputFlag( $flag, $reason ) {
+               $this->mOutput->setFlag( $flag );
+               $name = $this->mTitle->getPrefixedText();
+               $this->logger->debug( __METHOD__ . ": set $flag flag on '$name'; $reason" );
+       }
 }
index 0446d9c..3d15e86 100644 (file)
@@ -23,6 +23,8 @@ use MediaWiki\Config\ServiceOptions;
 use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Special\SpecialPageFactory;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
 
 /**
  * @since 1.32
@@ -49,6 +51,9 @@ class ParserFactory {
        /** @var NamespaceInfo */
        private $nsInfo;
 
+       /** @var LoggerInterface */
+       private $logger;
+
        /**
         * Old parameter list, which we support for backwards compatibility, were:
         *   array $parserConf See $wgParserConf documentation
@@ -71,12 +76,18 @@ class ParserFactory {
         * @param SpecialPageFactory $spFactory
         * @param LinkRendererFactory $linkRendererFactory
         * @param NamespaceInfo|LinkRendererFactory|null $nsInfo
+        * @param LoggerInterface|null $logger
         * @since 1.32
         */
        public function __construct(
-               $svcOptions, MagicWordFactory $magicWordFactory, Language $contLang,
-               $urlProtocols, SpecialPageFactory $spFactory, $linkRendererFactory,
-               $nsInfo = null
+               $svcOptions,
+               MagicWordFactory $magicWordFactory,
+               Language $contLang,
+               $urlProtocols,
+               SpecialPageFactory $spFactory,
+               $linkRendererFactory,
+               $nsInfo = null,
+               $logger = null
        ) {
                // @todo Do we need to retain compat for constructing this class directly?
                if ( !$nsInfo ) {
@@ -107,6 +118,7 @@ class ParserFactory {
                $this->specialPageFactory = $spFactory;
                $this->linkRendererFactory = $linkRendererFactory;
                $this->nsInfo = $nsInfo;
+               $this->logger = $logger ?: new NullLogger();
        }
 
        /**
@@ -114,8 +126,16 @@ class ParserFactory {
         * @since 1.32
         */
        public function create() : Parser {
-               return new Parser( $this->svcOptions, $this->magicWordFactory, $this->contLang, $this,
-                       $this->urlProtocols, $this->specialPageFactory, $this->linkRendererFactory,
-                       $this->nsInfo );
+               return new Parser(
+                       $this->svcOptions,
+                       $this->magicWordFactory,
+                       $this->contLang,
+                       $this,
+                       $this->urlProtocols,
+                       $this->specialPageFactory,
+                       $this->linkRendererFactory,
+                       $this->nsInfo,
+                       $this->logger
+               );
        }
 }
index 709f159..5a159fb 100644 (file)
@@ -62,6 +62,7 @@ class ParserOptions {
        private static $lazyOptions = [
                'dateformat' => [ __CLASS__, 'initDateFormat' ],
                'speculativeRevId' => [ __CLASS__, 'initSpeculativeRevId' ],
+               'speculativePageId' => [ __CLASS__, 'initSpeculativePageId' ],
        ];
 
        /**
@@ -117,11 +118,6 @@ class ParserOptions {
         */
        private $mExtraKey = '';
 
-       /**
-        * @name Option accessors
-        * @{
-        */
-
        /**
         * Fetch an option and track that is was accessed
         * @since 1.30
@@ -856,11 +852,25 @@ class ParserOptions {
                return $this->getOption( 'speculativeRevId' );
        }
 
+       /**
+        * A guess for {{PAGEID}}, calculated using the callback provided via
+        * setSpeculativeRevPageCallback(). For consistency, the value will be calculated upon the
+        * first call of this method, and re-used for subsequent calls.
+        *
+        * If no callback was defined via setSpeculativePageIdCallback(), this method will return false.
+        *
+        * @since 1.34
+        * @return int|false
+        */
+       public function getSpeculativePageId() {
+               return $this->getOption( 'speculativePageId' );
+       }
+
        /**
         * Callback registered with ParserOptions::$lazyOptions, triggered by getSpeculativeRevId().
         *
         * @param ParserOptions $popt
-        * @return bool|false
+        * @return int|false
         */
        private static function initSpeculativeRevId( ParserOptions $popt ) {
                $cb = $popt->getOption( 'speculativeRevIdCallback' );
@@ -871,27 +881,40 @@ class ParserOptions {
        }
 
        /**
-        * Callback to generate a guess for {{REVISIONID}}
-        * @since 1.28
-        * @deprecated since 1.32, use getSpeculativeRevId() instead!
-        * @return callable|null
+        * Callback registered with ParserOptions::$lazyOptions, triggered by getSpeculativePageId().
+        *
+        * @param ParserOptions $popt
+        * @return int|false
         */
-       public function getSpeculativeRevIdCallback() {
-               return $this->getOption( 'speculativeRevIdCallback' );
+       private static function initSpeculativePageId( ParserOptions $popt ) {
+               $cb = $popt->getOption( 'speculativePageIdCallback' );
+               $id = $cb ? $cb() : null;
+
+               // returning null would result in this being re-called every access
+               return $id ?? false;
        }
 
        /**
         * Callback to generate a guess for {{REVISIONID}}
-        * @since 1.28
-        * @param callable|null $x New value (null is no change)
+        * @param callable|null $x New value
         * @return callable|null Old value
+        * @since 1.28
         */
        public function setSpeculativeRevIdCallback( $x ) {
                $this->setOption( 'speculativeRevId', null ); // reset
-               return $this->setOptionLegacy( 'speculativeRevIdCallback', $x );
+               return $this->setOption( 'speculativeRevIdCallback', $x );
        }
 
-       /**@}*/
+       /**
+        * Callback to generate a guess for {{PAGEID}}
+        * @param callable|null $x New value
+        * @return callable|null Old value
+        * @since 1.34
+        */
+       public function setSpeculativePageIdCallback( $x ) {
+               $this->setOption( 'speculativePageId', null ); // reset
+               return $this->setOption( 'speculativePageIdCallback', $x );
+       }
 
        /**
         * Timestamp used for {{CURRENTDAY}} etc.
@@ -1102,6 +1125,8 @@ class ParserOptions {
                                'templateCallback' => [ Parser::class, 'statelessFetchTemplate' ],
                                'speculativeRevIdCallback' => null,
                                'speculativeRevId' => null,
+                               'speculativePageIdCallback' => null,
+                               'speculativePageId' => null,
                        ];
 
                        Hooks::run( 'ParserOptionsRegister', [
index 23e5911..cbba80a 100644 (file)
@@ -210,9 +210,17 @@ class ParserOutput extends CacheTime {
         */
        private $mFlags = [];
 
+       /** @var string[] */
+       private static $speculativeFields = [
+               'speculativePageIdUsed',
+               'mSpeculativeRevId',
+               'revisionTimestampUsed'
+       ];
+
        /** @var int|null Assumed rev ID for {{REVISIONID}} if no revision is set */
        private $mSpeculativeRevId;
-
+       /** @var int|null Assumed page ID for {{PAGEID}} if no revision is set */
+       private $speculativePageIdUsed;
        /** @var int|null Assumed rev timestamp for {{REVISIONTIMESTAMP}} if no revision is set */
        private $revisionTimestampUsed;
 
@@ -451,6 +459,22 @@ class ParserOutput extends CacheTime {
                return $this->mSpeculativeRevId;
        }
 
+       /**
+        * @param int $id
+        * @since 1.34
+        */
+       public function setSpeculativePageIdUsed( $id ) {
+               $this->speculativePageIdUsed = $id;
+       }
+
+       /**
+        * @return int|null
+        * @since 1.34
+        */
+       public function getSpeculativePageIdUsed() {
+               return $this->speculativePageIdUsed;
+       }
+
        /**
         * @param string $timestamp TS_MW timestamp
         * @since 1.34
@@ -1320,18 +1344,13 @@ class ParserOutput extends CacheTime {
                $this->mWarnings = self::mergeMap( $this->mWarnings, $source->mWarnings ); // don't use getter
                $this->mTimestamp = $this->useMaxValue( $this->mTimestamp, $source->getTimestamp() );
 
-               if ( $this->mSpeculativeRevId && $source->mSpeculativeRevId
-                       && $this->mSpeculativeRevId !== $source->mSpeculativeRevId
-               ) {
-                       wfLogWarning(
-                               'Inconsistent speculative revision ID encountered while merging parser output!'
-                       );
+               foreach ( self::$speculativeFields as $field ) {
+                       if ( $this->$field && $source->$field && $this->$field !== $source->$field ) {
+                               wfLogWarning( __METHOD__ . ": inconsistent '$field' properties!" );
+                       }
+                       $this->$field = $this->useMaxValue( $this->$field, $source->$field );
                }
 
-               $this->mSpeculativeRevId = $this->useMaxValue(
-                       $this->mSpeculativeRevId,
-                       $source->getSpeculativeRevIdUsed()
-               );
                $this->mParseStartTime = $this->useEachMinValue(
                        $this->mParseStartTime,
                        $source->mParseStartTime
index 671fe86..7e623b5 100644 (file)
@@ -480,7 +480,6 @@ class ResourceLoader implements LoggerAwareInterface {
         * @return array
         */
        public function getTestModuleNames( $framework = 'all' ) {
-               /** @todo api siteinfo prop testmodulenames modulenames */
                if ( $framework == 'all' ) {
                        return $this->testModuleNames;
                } elseif ( isset( $this->testModuleNames[$framework] )
index 9003951..6497543 100644 (file)
@@ -437,7 +437,8 @@ class ResourceLoaderImage {
 
                        file_put_contents( $tempFilenameSvg, $svg );
 
-                       $metadata = SVGMetadataExtractor::getMetadata( $tempFilenameSvg );
+                       $svgReader = new SVGReader( $tempFilenameSvg );
+                       $metadata = $svgReader->getMetadata();
                        if ( !isset( $metadata['width'] ) || !isset( $metadata['height'] ) ) {
                                unlink( $tempFilenameSvg );
                                return false;
index 7880f6f..6b38ee4 100644 (file)
@@ -105,7 +105,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces,
                        'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass( Title::legalChars() ),
                        'wgIllegalFileChars' => Title::convertByteClassToUnicodeClass( $illegalFileChars ),
-                       'wgResourceLoaderStorageEnabled' => $conf->get( 'ResourceLoaderStorageEnabled' ),
                        'wgForeignUploadTargets' => $conf->get( 'ForeignUploadTargets' ),
                        'wgEnableUploads' => $conf->get( 'EnableUploads' ),
                        'wgCommentByteLimit' => null,
@@ -422,6 +421,14 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        '$VARS.maxQueryLength' => ResourceLoader::encodeJsonForScript(
                                $conf->get( 'ResourceLoaderMaxQueryLength' )
                        ),
+                       // The client-side module cache can be disabled by site configuration.
+                       // It is also always disabled in debug mode.
+                       '$VARS.storeEnabled' => ResourceLoader::encodeJsonForScript(
+                               $conf->get( 'ResourceLoaderStorageEnabled' ) && !$context->getDebug()
+                       ),
+                       '$VARS.wgLegacyJavaScriptGlobals' => ResourceLoader::encodeJsonForScript(
+                               $conf->get( 'LegacyJavaScriptGlobals' )
+                       ),
                        '$VARS.storeKey' => ResourceLoader::encodeJsonForScript( $this->getStoreKey() ),
                        '$VARS.storeVary' => ResourceLoader::encodeJsonForScript( $this->getStoreVary( $context ) ),
                ];
@@ -442,9 +449,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
 
                // Perform string replacements for startup.js
                $pairs = [
-                       '$VARS.wgLegacyJavaScriptGlobals' => ResourceLoader::encodeJsonForScript(
-                               $conf->get( 'LegacyJavaScriptGlobals' )
-                       ),
                        '$VARS.configuration' => ResourceLoader::encodeJsonForScript(
                                $this->getConfigSettings( $context )
                        ),
index b104073..a2501c4 100644 (file)
@@ -412,6 +412,7 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                return $titleInfo;
        }
 
+       /** @return array */
        protected static function fetchTitleInfo( IDatabase $db, array $pages, $fname = __METHOD__ ) {
                $titleInfo = [];
                $batch = new LinkBatch;
diff --git a/includes/search/BaseSearchResultSet.php b/includes/search/BaseSearchResultSet.php
new file mode 100644 (file)
index 0000000..d8aed0e
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * BaseSearchResultSet is the base class that must be extended by SearchEngine
+ * search result set implementations.
+ *
+ * This base class is meant to hold B/C behaviors and to be useful it must never:
+ * - be used as type hints (ISearchResultSet must be used for this)
+ * - implement a constructor
+ * - declare utility methods
+ *
+ * @ingroup Search
+ */
+abstract class BaseSearchResultSet implements ISearchResultSet {
+
+       /**
+        * @var ArrayIterator|null Iterator supporting BC iteration methods
+        */
+       private $bcIterator;
+
+       /**
+        * Fetches next search result, or false.
+        * @deprecated since 1.32; Use self::extractResults() or foreach
+        * @return SearchResult|false
+        */
+       public function next() {
+               wfDeprecated( __METHOD__, '1.32' );
+               $it = $this->bcIterator();
+               $searchResult = $it->current();
+               $it->next();
+               return $searchResult ?? false;
+       }
+
+       /**
+        * Rewind result set back to beginning
+        * @deprecated since 1.32; Use self::extractResults() or foreach
+        */
+       public function rewind() {
+               wfDeprecated( __METHOD__, '1.32' );
+               $this->bcIterator()->rewind();
+       }
+
+       private function bcIterator() {
+               if ( $this->bcIterator === null ) {
+                       $this->bcIterator = 'RECURSION';
+                       $this->bcIterator = $this->getIterator();
+               } elseif ( $this->bcIterator === 'RECURSION' ) {
+                       // Either next/rewind or extractResults must be implemented.  This
+                       // class was potentially instantiated directly. It should be
+                       // abstract with abstract methods to enforce this but that's a
+                       // breaking change...
+                       wfDeprecated( static::class . ' without implementing extractResults', '1.32' );
+                       $this->bcIterator = new ArrayIterator( [] );
+               }
+               return $this->bcIterator;
+       }
+
+       /**
+        * Fetch an array of regular expression fragments for matching
+        * the search terms as parsed by this engine in a text extract.
+        * STUB
+        *
+        * @return string[]
+        * @deprecated since 1.34 (use SqlSearchResult)
+        */
+       public function termMatches() {
+               return [];
+       }
+
+       /**
+        * Frees the result set, if applicable.
+        * @deprecated noop since 1.34
+        */
+       public function free() {
+       }
+}
index 1b30f5a..5faa445 100644 (file)
@@ -1,6 +1,11 @@
 <?php
 
 /**
+ * A set of SearchEngine results.
+ * Must not be directly implemented by extension, please extend BaseSearchResultSet instead.
+ * This interface must only be used for type hinting.
+ *
+ * @see BaseSearchResultSet
  * @ingroup Search
  */
 interface ISearchResultSet extends \Countable, \IteratorAggregate {
@@ -19,7 +24,7 @@ interface ISearchResultSet extends \Countable, \IteratorAggregate {
        /**
         * @return int
         */
-       function numRows();
+       public function numRows();
 
        /**
         * Some search modes return a total hit count for the query
@@ -31,7 +36,7 @@ interface ISearchResultSet extends \Countable, \IteratorAggregate {
         *
         * @return int|null
         */
-       function getTotalHits();
+       public function getTotalHits();
 
        /**
         * Some search modes will run an alternative query that it thinks gives
@@ -40,19 +45,19 @@ interface ISearchResultSet extends \Countable, \IteratorAggregate {
         *
         * @return bool
         */
-       function hasRewrittenQuery();
+       public function hasRewrittenQuery();
 
        /**
         * @return string|null The search the query was internally rewritten to,
         *  or null when the result of the original query was returned.
         */
-       function getQueryAfterRewrite();
+       public function getQueryAfterRewrite();
 
        /**
         * @return string|null Same as self::getQueryAfterRewrite(), but in HTML
         *  and with changes highlighted. Null when the query was not rewritten.
         */
-       function getQueryAfterRewriteSnippet();
+       public function getQueryAfterRewriteSnippet();
 
        /**
         * Some search modes return a suggested alternate term if there are
@@ -60,17 +65,17 @@ interface ISearchResultSet extends \Countable, \IteratorAggregate {
         *
         * @return bool
         */
-       function hasSuggestion();
+       public function hasSuggestion();
 
        /**
         * @return string|null Suggested query, null if none
         */
-       function getSuggestionQuery();
+       public function getSuggestionQuery();
 
        /**
         * @return string HTML highlighted suggested query, '' if none
         */
-       function getSuggestionSnippet();
+       public function getSuggestionSnippet();
 
        /**
         * Return a result set of hits on other (multiple) wikis associated with this one
@@ -78,7 +83,7 @@ interface ISearchResultSet extends \Countable, \IteratorAggregate {
         * @param int $type
         * @return ISearchResultSet[]
         */
-       function getInterwikiResults( $type = self::SECONDARY_RESULTS );
+       public function getInterwikiResults( $type = self::SECONDARY_RESULTS );
 
        /**
         * Check if there are results on other wikis
@@ -86,7 +91,7 @@ interface ISearchResultSet extends \Countable, \IteratorAggregate {
         * @param int $type
         * @return bool
         */
-       function hasInterwikiResults( $type = self::SECONDARY_RESULTS );
+       public function hasInterwikiResults( $type = self::SECONDARY_RESULTS );
 
        /**
         * Did the search contain search syntax?  If so, Special:Search won't offer
index 32b0f06..31af13d 100644 (file)
@@ -803,6 +803,10 @@ abstract class SearchEngine {
                        $setAugmentors[$name] = new PerRowAugmentor( $row );
                }
 
+               /**
+                * @var string $name
+                * @var ResultSetAugmentor $augmentor
+                */
                foreach ( $setAugmentors as $name => $augmentor ) {
                        $data = $augmentor->augmentAll( $resultSet );
                        if ( $data ) {
index a862e17..1d71c87 100644 (file)
@@ -104,7 +104,7 @@ class SearchResult {
         *
         * @return bool
         */
-       function isBrokenTitle() {
+       public function isBrokenTitle() {
                return is_null( $this->mTitle );
        }
 
@@ -113,14 +113,14 @@ class SearchResult {
         *
         * @return bool
         */
-       function isMissingRevision() {
+       public function isMissingRevision() {
                return !$this->mRevision && !$this->mImage;
        }
 
        /**
         * @return Title
         */
-       function getTitle() {
+       public function getTitle() {
                return $this->mTitle;
        }
 
@@ -128,7 +128,7 @@ class SearchResult {
         * Get the file for this page, if one exists
         * @return File|null
         */
-       function getFile() {
+       public function getFile() {
                return $this->mImage;
        }
 
@@ -150,35 +150,35 @@ class SearchResult {
         * @param string[] $terms Terms to highlight (this parameter is deprecated and ignored)
         * @return string Highlighted text snippet, null (and not '') if not supported
         */
-       function getTextSnippet( $terms = [] ) {
+       public function getTextSnippet( $terms = [] ) {
                return '';
        }
 
        /**
         * @return string Highlighted title, '' if not supported
         */
-       function getTitleSnippet() {
+       public function getTitleSnippet() {
                return '';
        }
 
        /**
         * @return string Highlighted redirect name (redirect to this page), '' if none or not supported
         */
-       function getRedirectSnippet() {
+       public function getRedirectSnippet() {
                return '';
        }
 
        /**
         * @return Title|null Title object for the redirect to this page, null if none or not supported
         */
-       function getRedirectTitle() {
+       public function getRedirectTitle() {
                return null;
        }
 
        /**
         * @return string Highlighted relevant section name, null if none or not supported
         */
-       function getSectionSnippet() {
+       public function getSectionSnippet() {
                return '';
        }
 
@@ -186,7 +186,7 @@ class SearchResult {
         * @return Title|null Title object (pagename+fragment) for the section,
         *  null if none or not supported
         */
-       function getSectionTitle() {
+       public function getSectionTitle() {
                return null;
        }
 
@@ -200,7 +200,7 @@ class SearchResult {
        /**
         * @return string Timestamp
         */
-       function getTimestamp() {
+       public function getTimestamp() {
                if ( $this->mRevision ) {
                        return $this->mRevision->getTimestamp();
                } elseif ( $this->mImage ) {
@@ -212,7 +212,7 @@ class SearchResult {
        /**
         * @return int Number of words
         */
-       function getWordCount() {
+       public function getWordCount() {
                $this->initText();
                return str_word_count( $this->mText );
        }
@@ -220,7 +220,7 @@ class SearchResult {
        /**
         * @return int Size in bytes
         */
-       function getByteSize() {
+       public function getByteSize() {
                $this->initText();
                return strlen( $this->mText );
        }
@@ -228,14 +228,14 @@ class SearchResult {
        /**
         * @return string Interwiki prefix of the title (return iw even if title is broken)
         */
-       function getInterwikiPrefix() {
+       public function getInterwikiPrefix() {
                return '';
        }
 
        /**
         * @return string Interwiki namespace of the title (since we likely can't resolve it locally)
         */
-       function getInterwikiNamespaceText() {
+       public function getInterwikiNamespaceText() {
                return '';
        }
 
@@ -243,7 +243,7 @@ class SearchResult {
         * Did this match file contents (eg: PDF/DJVU)?
         * @return bool
         */
-       function isFileMatch() {
+       public function isFileMatch() {
                return false;
        }
 
index 84f8bcf..73e33a2 100644 (file)
@@ -24,7 +24,8 @@
 /**
  * @ingroup Search
  */
-class SearchResultSet implements ISearchResultSet {
+class SearchResultSet extends BaseSearchResultSet {
+       use SearchResultSetTrait;
 
        protected $containedSyntax = false;
 
@@ -42,25 +43,11 @@ class SearchResultSet implements ISearchResultSet {
         */
        protected $results;
 
-       /**
-        * Set of result's extra data, indexed per result id
-        * and then per data item name.
-        * The structure is:
-        * PAGE_ID => [ augmentor name => data, ... ]
-        * @var array[]
-        */
-       protected $extraData = [];
-
        /**
         * @var boolean True when there are more pages of search results available.
         */
        private $hasMoreResults;
 
-       /**
-        * @var ArrayIterator|null Iterator supporting BC iteration methods
-        */
-       private $bcIterator;
-
        /**
         * @param bool $containedSyntax True when query is not requesting a simple
         *  term match
@@ -78,19 +65,7 @@ class SearchResultSet implements ISearchResultSet {
                $this->hasMoreResults = $hasMoreResults;
        }
 
-       /**
-        * Fetch an array of regular expression fragments for matching
-        * the search terms as parsed by this engine in a text extract.
-        * STUB
-        *
-        * @return string[]
-        * @deprecated since 1.34 (use SqlSearchResult)
-        */
-       function termMatches() {
-               return [];
-       }
-
-       function numRows() {
+       public function numRows() {
                return $this->count();
        }
 
@@ -108,7 +83,7 @@ class SearchResultSet implements ISearchResultSet {
         *
         * @return int
         */
-       function getTotalHits() {
+       public function getTotalHits() {
                return null;
        }
 
@@ -119,7 +94,7 @@ class SearchResultSet implements ISearchResultSet {
         *
         * @return bool
         */
-       function hasRewrittenQuery() {
+       public function hasRewrittenQuery() {
                return false;
        }
 
@@ -127,7 +102,7 @@ class SearchResultSet implements ISearchResultSet {
         * @return string|null The search the query was internally rewritten to,
         *  or null when the result of the original query was returned.
         */
-       function getQueryAfterRewrite() {
+       public function getQueryAfterRewrite() {
                return null;
        }
 
@@ -135,7 +110,7 @@ class SearchResultSet implements ISearchResultSet {
         * @return string|null Same as self::getQueryAfterRewrite(), but in HTML
         *  and with changes highlighted. Null when the query was not rewritten.
         */
-       function getQueryAfterRewriteSnippet() {
+       public function getQueryAfterRewriteSnippet() {
                return null;
        }
 
@@ -145,21 +120,21 @@ class SearchResultSet implements ISearchResultSet {
         *
         * @return bool
         */
-       function hasSuggestion() {
+       public function hasSuggestion() {
                return false;
        }
 
        /**
         * @return string|null Suggested query, null if none
         */
-       function getSuggestionQuery() {
+       public function getSuggestionQuery() {
                return null;
        }
 
        /**
         * @return string HTML highlighted suggested query, '' if none
         */
-       function getSuggestionSnippet() {
+       public function getSuggestionSnippet() {
                return '';
        }
 
@@ -169,7 +144,7 @@ class SearchResultSet implements ISearchResultSet {
         * @param int $type
         * @return ISearchResultSet[]
         */
-       function getInterwikiResults( $type = self::SECONDARY_RESULTS ) {
+       public function getInterwikiResults( $type = self::SECONDARY_RESULTS ) {
                return null;
        }
 
@@ -179,54 +154,10 @@ class SearchResultSet implements ISearchResultSet {
         * @param int $type
         * @return bool
         */
-       function hasInterwikiResults( $type = self::SECONDARY_RESULTS ) {
+       public function hasInterwikiResults( $type = self::SECONDARY_RESULTS ) {
                return false;
        }
 
-       /**
-        * Fetches next search result, or false.
-        * @deprecated since 1.32; Use self::extractResults() or foreach
-        * @return SearchResult|false
-        */
-       public function next() {
-               wfDeprecated( __METHOD__, '1.32' );
-               $it = $this->bcIterator();
-               $searchResult = $it->current();
-               $it->next();
-               return $searchResult ?? false;
-       }
-
-       /**
-        * Rewind result set back to beginning
-        * @deprecated since 1.32; Use self::extractResults() or foreach
-        */
-       public function rewind() {
-               wfDeprecated( __METHOD__, '1.32' );
-               $this->bcIterator()->rewind();
-       }
-
-       private function bcIterator() {
-               if ( $this->bcIterator === null ) {
-                       $this->bcIterator = 'RECURSION';
-                       $this->bcIterator = $this->getIterator();
-               } elseif ( $this->bcIterator === 'RECURSION' ) {
-                       // Either next/rewind or extractResults must be implemented.  This
-                       // class was potentially instantiated directly. It should be
-                       // abstract with abstract methods to enforce this but that's a
-                       // breaking change...
-                       wfDeprecated( static::class . ' without implementing extractResults', '1.32' );
-                       $this->bcIterator = new ArrayIterator( [] );
-               }
-               return $this->bcIterator;
-       }
-
-       /**
-        * Frees the result set, if applicable.
-        * @deprecated noop since 1.34
-        */
-       function free() {
-       }
-
        /**
         * Did the search contain search syntax?  If so, Special:Search won't offer
         * the user a link to a create a page named by the search string because the
@@ -304,43 +235,4 @@ class SearchResultSet implements ISearchResultSet {
                }
                return $this->titles;
        }
-
-       /**
-        * Sets augmented data for result set.
-        * @param string $name Extra data item name
-        * @param array[] $data Extra data as PAGEID => data
-        */
-       public function setAugmentedData( $name, $data ) {
-               foreach ( $data as $id => $resultData ) {
-                       $this->extraData[$id][$name] = $resultData;
-               }
-       }
-
-       /**
-        * Returns extra data for specific result and store it in SearchResult object.
-        * @param SearchResult $result
-        */
-       public function augmentResult( SearchResult $result ) {
-               $id = $result->getTitle()->getArticleID();
-               if ( $id === -1 ) {
-                       return;
-               }
-               $result->setExtensionData( function () use ( $id ) {
-                       return $this->extraData[$id] ?? [];
-               } );
-       }
-
-       /**
-        * @return int|null The offset the current page starts at. Typically
-        *  this should be null to allow the UI to decide on its own, but in
-        *  special cases like interleaved AB tests specifying explicitly is
-        *  necessary.
-        */
-       public function getOffset() {
-               return null;
-       }
-
-       final public function getIterator() {
-               return new ArrayIterator( $this->extractResults() );
-       }
 }
diff --git a/includes/search/SearchResultSetTrait.php b/includes/search/SearchResultSetTrait.php
new file mode 100644 (file)
index 0000000..f36a7b5
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * Trait useful for SearchResultSet implementations.
+ * It holds the functions that are rarely needed to be overridden.
+ *
+ * This trait can be used directly by extensions providing a SearchEngine.
+ *
+ * @ingroup Search
+ */
+trait SearchResultSetTrait {
+       /**
+        * Set of result's extra data, indexed per result id
+        * and then per data item name.
+        * The structure is:
+        * PAGE_ID => [ augmentor name => data, ... ]
+        * @var array[]
+        */
+       private $extraData = [];
+
+       /**
+        * Sets augmented data for result set.
+        * @param string $name Extra data item name
+        * @param array[] $data Extra data as PAGEID => data
+        */
+       public function setAugmentedData( $name, $data ) {
+               foreach ( $data as $id => $resultData ) {
+                       $this->extraData[$id][$name] = $resultData;
+               }
+       }
+
+       /**
+        * Returns extra data for specific result and store it in SearchResult object.
+        * @param SearchResult $result
+        */
+       public function augmentResult( SearchResult $result ) {
+               $id = $result->getTitle()->getArticleID();
+               if ( $id === -1 ) {
+                       return;
+               }
+               $result->setExtensionData( function () use ( $id ) {
+                       return $this->extraData[$id] ?? [];
+               } );
+       }
+
+       /**
+        * @return int|null The offset the current page starts at. Typically
+        *  this should be null to allow the UI to decide on its own, but in
+        *  special cases like interleaved AB tests specifying explicitly is
+        *  necessary.
+        */
+       public function getOffset() {
+               return null;
+       }
+
+       final public function getIterator() {
+               return new ArrayIterator( $this->extractResults() );
+       }
+}
index 918c761..bbad648 100644 (file)
@@ -275,7 +275,7 @@ abstract class Skin extends ContextSource {
 
                // Check, if the page can hold some kind of content, otherwise do nothing
                $title = $this->getRelevantTitle();
-               if ( $title->canExist() ) {
+               if ( $title->canExist() && $title->canHaveTalkPage() ) {
                        if ( $title->isTalkPage() ) {
                                $titles[] = $title->getSubjectPage();
                        } else {
index eb179bf..223f799 100644 (file)
@@ -312,7 +312,7 @@ abstract class QueryPage extends SpecialPage {
                                $num = $res->numRows();
                                # Fetch results
                                $vals = [];
-                               foreach ( $res as $row ) {
+                               foreach ( $res as $i => $row ) {
                                        if ( isset( $row->value ) ) {
                                                if ( $this->usesTimestamps() ) {
                                                        $value = wfTimestamp( TS_UNIX,
@@ -321,7 +321,7 @@ abstract class QueryPage extends SpecialPage {
                                                        $value = intval( $row->value ); // T16414
                                                }
                                        } else {
-                                               $value = 0;
+                                               $value = $i;
                                        }
 
                                        $vals[] = [
index a55a9c8..b2161db 100644 (file)
@@ -1138,8 +1138,6 @@ class SpecialBlock extends FormSpecialPage {
                if ( $performer->getBlock() ) {
                        if ( $target instanceof User && $target->getId() == $performer->getId() ) {
                                # User is trying to unblock themselves
-                               // @TODO Ensure that the block does not apply to the `unblockself`
-                               //       right.
                                if ( $performer->isAllowed( 'unblockself' ) ) {
                                        return true;
                                        # User blocked themselves and is now trying to reverse it
index 9564d53..72afb03 100644 (file)
@@ -38,6 +38,21 @@ class SpecialUnlinkAccounts extends AuthManagerSpecialPage {
        public function execute( $subPage ) {
                $this->setHeaders();
                $this->loadAuth( $subPage );
+
+               if ( !$this->isActionAllowed( $this->authAction ) ) {
+                       if ( $this->authAction === AuthManager::ACTION_UNLINK ) {
+                               // Looks like there are no linked accounts to unlink
+                               $titleMessage = $this->msg( 'cannotunlink-no-provider-title' );
+                               $errorMessage = $this->msg( 'cannotunlink-no-provider' );
+                               throw new ErrorPageError( $titleMessage, $errorMessage );
+                       } else {
+                               // user probably back-button-navigated into an auth session that no longer exists
+                               // FIXME would be nice to show a message
+                               $this->getOutput()->redirect( $this->getPageTitle()->getFullURL( '', false, PROTO_HTTPS ) );
+                               return;
+                       }
+               }
+
                $this->outputHeader();
 
                $status = $this->trySubmit();
index f20afdb..9e94233 100644 (file)
@@ -18,8 +18,8 @@
                <td class="mw-changeslist-line-inner">{{!
                        }}{{# rev-deleted-event }}<span class="history-deleted">{{{ . }}}</span>{{/ rev-deleted-event }}{{!
                        }}{{{ articleLink }}}{{{ languageDirMark }}}{{{ logText }}}{{!
-                       }}<span class="mw-changeslist-separator"></span>{{!
-                       }}{{# charDifference }}{{{ . }}} <span class="mw-changeslist-separator"></span>{{/ charDifference }}{{!
+                       }} <span class="mw-changeslist-separator"></span> {{!
+                       }}{{# charDifference }}{{{ . }}} <span class="mw-changeslist-separator"></span> {{/ charDifference }}{{!
                        }}<span class="changedby">{{{ users }}}</span>{{!
                        }}{{ numberofWatchingusers }}{{!
                }}</td>
index 5b15e82..fb9dcf5 100644 (file)
@@ -704,6 +704,33 @@ abstract class UploadBase {
                return $warnings;
        }
 
+       /**
+        * Convert the warnings array returned by checkWarnings() to something that
+        * can be serialized. File objects will be converted to an associative array
+        * with the following keys:
+        *
+        *   - fileName: The name of the file
+        *   - timestamp: The upload timestamp
+        *
+        * @param mixed[] $warnings
+        * @return mixed[]
+        */
+       public static function makeWarningsSerializable( $warnings ) {
+               array_walk_recursive( $warnings, function ( &$param, $key ) {
+                       if ( $param instanceof File ) {
+                               $param = [
+                                       'fileName' => $param->getName(),
+                                       'timestamp' => $param->getTimestamp()
+                               ];
+                       } elseif ( is_object( $param ) ) {
+                               throw new InvalidArgumentException(
+                                       'UploadBase::makeWarningsSerializable: ' .
+                                       'Unexpected object of class ' . get_class( $param ) );
+                       }
+               } );
+               return $warnings;
+       }
+
        /**
         * Check whether the resulting filename is different from the desired one,
         * but ignore things like ucfirst() and spaces/underscore things
index d33b6ae..c363029 100644 (file)
@@ -383,7 +383,7 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac
 
        /**
         * @param UserIdentity $user
-        * @param TitleValue[] $titles
+        * @param LinkTarget[] $titles
         * @return bool
         * @throws MWException
         */
index 1b5aa79..f1d27d2 100644 (file)
@@ -77,7 +77,8 @@
                        "Elbasyouny",
                        "Omar Ghrida",
                        "AHmed Khaled",
-                       "البراء صالح"
+                       "البراء صالح",
+                       "Dyolf77 (WMF)"
                ]
        },
        "tog-underline": "سطر تحت الوصلات:",
        "password-change-forbidden": "لا يمكنك تغيير كلمات السر على هذا الويكي.",
        "externaldberror": "هناك إما خطأ في دخول قاعدة البيانات الخارجية أو أنه غير مسموح لك بتحديث حسابك الخارجي.",
        "login": "تسجيل الدخول",
-       "login-security": "توكيد هويتك",
+       "login-security": "تأكيد هويتك",
        "nav-login-createaccount": "دخول / إنشاء حساب",
        "logout": "تسجيل الخروج",
        "userlogout": "خروج",
        "passwordreset-invalidemail": "عنوان بريد إلكتروني غير صالح",
        "passwordreset-nodata": "لا اسم مستخدم ولا عنوان بريد الإلكتروي تم توفيره",
        "changeemail": "تغيير أو إزالة عنوان البريد الإلكتروني",
-       "changeemail-header": "Ø¥Ù\83Ù\85اÙ\84 Ù\87ذا Ø§Ù\84Ù\86Ù\85Ù\88ذج Ù\84تغÙ\8aÙ\8aر Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ø§Ù\84خاص Ø¨Ù\83. Ø¥Ø°Ø§ Ù\83Ù\86ت ØªØ±ØºØ¨ Ù\81Ù\8a Ø¥Ø²Ø§Ù\84Ø© Ø¬Ù\85عÙ\8aØ© Ø£Ù\8a Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\85Ù\86 Ø­Ø³Ø§Ø¨Ù\83Ø\8c Ù\88ترÙ\83 Ø§Ù\84Ù\81راغ Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ø§Ù\84جدÙ\8aد Ø¹Ù\86د ØªÙ\82دÙ\8aÙ\85 Ø§Ù\84Ù\86Ù\85Ù\88ذج",
+       "changeemail-header": "Ø£Ù\83Ù\85Ù\84 Ù\87Ø°Ù\87 Ø§Ù\84استÙ\85ارة Ù\84تغÙ\8aÙ\8aر Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ø§Ù\84خاص Ø¨Ù\83. Ø¥Ø°Ø§ Ù\83Ù\86ت ØªØ±ØºØ¨ Ù\81Ù\8a Ø¥Ø²Ø§Ù\84Ø© Ø£Ù\8a Ø¹Ù\86Ù\88اÙ\86 Ø¨Ø±Ù\8aد Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ù\85Ù\82ترÙ\86 Ù\85ع Ø­Ø³Ø§Ø¨Ù\83Ø\8c Ø§ØªØ±Ù\83 Ø­Ù\82Ù\84 Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ø§Ù\84جدÙ\8aد Ù\81ارغا Ø¹Ù\86د ØªÙ\82دÙ\8aÙ\85 Ø§Ù\84استÙ\85ارة.",
        "changeemail-no-info": "يجب تسجيل الدخول للوصول إلى هذه الصفحة مباشرة.",
        "changeemail-oldemail": "عنوان البريد الإلكتروني الحالي:",
        "changeemail-newemail": "عنوان البريد الإلكتروني الجديد:",
-       "changeemail-newemail-help": "هذا الحقل ينبغي أن يترك فارغا في حالة لو كنت تريد إزالة عنوان البريد الإلكتروني الخاص بك. أنت لن تكون قادرا على إعادة ضبط كلمة سر ضائعة ولن تتلقى رسئل بريد إلكتروني من هذه الويكي لو أزيل عنوان البريد الإلكتروني.",
+       "changeemail-newemail-help": "هذا الحقل يجب أن يترك فارغا لو كنت تريد إزالة عنوان البريد الإلكتروني الخاص بك. لو أزيل عنوان البريد الإلكتروني لن تكون قادرا على إعادة ضبط كلمة سر ضائعة ولن تتلقى رسائل بريد إلكتروني من هذه الويكي.",
        "changeemail-none": "(لا شيء)",
        "changeemail-password": "كلمة سر {{SITENAME}} الخاصة بك:",
        "changeemail-submit": "غيّر البريد الإلكتروني",
        "search-interwiki-more": "(المزيد)",
        "search-interwiki-more-results": "المزيد من النتائج",
        "search-relatedarticle": "مرتبطة",
+       "search-invalid-sort-order": "ترتيب فرز $1 غير معروفP سيتم تطبيق الفرز الافتراضي، ترتيبات الفرز الصالحة هي: $2",
+       "search-unknown-profile": "لم يتم التعرف على ملف تعريف البحث $1؛ سيتم تطبيق ملف تعريف البحث الافتراضي.",
        "searchrelated": "مرتبطة",
        "searchall": "الكل",
        "showingresults": "معروض بالأسفل {{PLURAL:$1|<strong>1</strong> نتيجة}} بدءا من رقم <strong>$2</strong>.",
        "linkaccounts": "ربط الحسابات",
        "linkaccounts-success-text": "الحساب تم وصله.",
        "linkaccounts-submit": "اربط الحسابات",
+       "cannotunlink-no-provider-title": "لا توجد حسابات مرتبطة لإلغاء الربط",
+       "cannotunlink-no-provider": "لا توجد حسابات مرتبطة يمكن إلغاء ربطها.",
        "unlinkaccounts": "إزالة ربط الحسابات",
        "unlinkaccounts-success": "الحساب تم فك وصله.",
        "authenticationdatachange-ignored": "تغيير بيانات التحقق لم يتم التعامل معه. ربما لم يتم ضبط موفر؟",
index 0a3d39e..0fd9873 100644 (file)
        "accmailtext": "[[User talk:$1|$1]]-ৰ কাৰণে যাদৃচ্ছিকভাৱে উৎপন্ন কৰা গুপ্তশব্দ $2লৈ পঠোৱা হ'ল । \nএই নতুন একাউন্টত প্ৰৱেশ কৰি ''[[Special:ChangePassword|গুপ্তশব্দ সলনি কৰক]]'' পৃষ্ঠাখনত শব্দতো সলনি কৰি ল’ব পাৰিব ।",
        "newarticle": "(নতুন)",
        "newarticletext": "আপুনি বিচৰা প্ৰবন্ধটো বিচাৰি পোৱা নগ'ল।\n\nইচ্ছা কৰিলে আপুনিয়েই এই প্ৰবন্ধটো লিখা আৰম্ভ কৰিব পাৰে। [$1 ইয়াত] সহায় পাব।\n\nআপুনি যদি ইয়ালৈ ভুলতে আহিছে, তেনেহলে আপোনাৰ ব্ৰাওজাৰৰ '''BACK''' বুটামত টিপা মাৰক।",
-       "anontalkpagetext": "----''এইখন আলোচনা পৃষ্ঠা বেনামী সদস্যৰ বাবে, যিয়ে নিজা একাউণ্ট  সৃষ্টি কৰা নাই বা যিয়ে সেই একাউণ্ট ব্যৱহাৰ নকৰে।\nএতেকে আমি তেখেতসকলক আই-পি ঠিকনাৰে চিনাক্ত কৰিবলৈ বাধ্য।\nসেই একেই আই-পি ঠিকনা অনেকেই ব্যৱহাৰ কৰিব পাৰে।\nআপুনি যদি এজন বেনামী সদস্য আৰু যদি আপুনি অনুভৱ কৰে যে আপোনাৰ প্ৰতি অপ্ৰাসঙ্গিক মন্তব্য কৰা হৈছে, তেনেহলে আন বেনামী সদস্যৰ পৰা পৃথক কৰিবলৈ \n[[Special:CreateAccount|একাউণ্ট সৃষ্টি কৰক]] বা [[Special:UserLogin|প্ৰৱেশ কৰক]] ।''",
+       "anontalkpagetext": "----\n<em>এইখন আলোচনা পৃষ্ঠা বেনামী সদস্যৰ বাবে, যিয়ে নিজা একাউণ্ট  সৃষ্টি কৰা নাই বা যিয়ে সেই একাউণ্ট ব্যৱহাৰ নকৰে।</em>\nএতেকে আমি তেখেতসকলক আই-পি ঠিকনাৰে চিনাক্ত কৰিবলৈ বাধ্য।\nসেই একেই আই-পি ঠিকনা অনেকেই ব্যৱহাৰ কৰিব পাৰে।\nআপুনি যদি এজন বেনামী সদস্য আৰু যদি আপুনি অনুভৱ কৰে যে আপোনাৰ প্ৰতি অপ্ৰাসঙ্গিক মন্তব্য কৰা হৈছে, তেনেহলে আন বেনামী সদস্যৰ পৰা পৃথক কৰিবলৈ [[Special:CreateAccount|এ টাএকাউণ্ট সৃষ্টি কৰক]] বা [[Special:UserLogin|প্ৰৱেশ কৰক]]।",
        "noarticletext": "এই পৃষ্ঠাত বৰ্তমান কোনো পাঠ্য নাই ।\nআপুনি আন পৃষ্ঠাত [[Special:Search/{{PAGENAME}}|এই শিৰোনামা সন্ধান কৰিব পাৰে]],\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} সম্পৰ্কীয় অভিলেখ সন্ধান কৰিব পাৰে],\nবা [{{fullurl:{{FULLPAGENAME}}|action=edit}} এই পৃষ্ঠা সৃষ্টি কৰিব পাৰে]</span>",
        "noarticletext-nopermission": "এই পৃষ্ঠাত বৰ্তমান কোনো পাঠ্য নাই।\nআপুনি আন পৃষ্ঠাত [[Special:Search/{{PAGENAME}}|এই শিৰোনামা সন্ধান কৰিব পাৰে]],\nবা <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} সম্পৰ্কীয় অভিলেখ সন্ধান কৰিব পাৰে]</span>, কিন্তু এই পৃষ্ঠা সৃষ্টি কৰিবলৈ আপোনাৰ অনুমতি নাই।",
        "missing-revision": "\"{{FULLPAGENAME}}\" নামৰ পৃষ্ঠাৰ #$1 সংশোধনৰ অস্তিত্ব নাই।\n\nসাধাৰণতে বিলোপ কৰা এখন পৃষ্ঠাৰ পুৰণা ইতিহাস লিংক অনুসৰণ কৰিলে এনে হয়।\n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} বিলোপন ল'গ]ত অধিক তথ্য পাব।",
        "page_first": "প্ৰথম",
        "page_last": "অন্তিম",
        "histlegend": "পাৰ্থক্য বাছনি: পাৰ্থক্য চাবলৈ সংকলনবোৰৰ সম্মুখত থকা ৰেডিঅ' বুটামবোৰ বাচনী কৰি এণ্টাৰ টিপক অথবা একেবাৰে তলত দিয়া বুটামতো ক্লিক কৰক <br />\nলিজেণ্ড: '''({{int:cur}})''' = বৰ্তমানৰ সংকলনৰ লগত পাৰ্থক্য,\n'''({{int:last}})''' = আগৰ সংকলনৰ লগত পাৰ্থক্য, '''{{int:minoreditletter}}'' = অগুৰুত্বপূৰ্ণ সম্পাদনা।",
-       "history-fieldset-title": "সংশোধিত সংস্কৰণ সন্ধান কৰক",
+       "history-fieldset-title": "সংশোধিত সংস্কৰণ",
        "history-show-deleted": "মাথোঁ বিলোপ কৰা",
        "histfirst": "আটাইতকৈ পুৰণি",
        "histlast": "শেহতীয়া",
        "editundo": "পূৰ্ববত কৰক",
        "diff-empty": "(কোনো পাৰ্থক্য নাই)",
        "diff-multi-sameuser": "একেজন সদস্যই কৰা ({{PLURAL:$1|এটা মধ্যৱৰ্তী সংশোধন|$1 মধ্যৱৰ্তী সংশোধন}} দেখুওৱা হোৱা নাই)",
-       "diff-multi-otherusers": "({{PLURAL:$2|আন এজন সদস্যই|$2জন সদস্যই}} কৰা ({{PLURAL:$1|এটা মধ্যৱৰ্তী সংশোধন|$1টা মধ্যৱৰ্তী সংশোধন}} দেখুওৱা হোৱা নাই)",
+       "diff-multi-otherusers": "({{PLURAL:$2|আন এজন সদস্য|$2জন সদস্য}}ই কৰা {{PLURAL:$1|এটা মধ্যৱৰ্তী সংশোধন|$1টা মধ্যৱৰ্তী সংশোধন}} দেখুওৱা হোৱা নাই)",
        "diff-multi-manyusers": "({{PLURAL:$2|এজনতকৈ|$2-জনতকৈ}} অধিক সদস্যৰ দ্বাৰা {{PLURAL:$1|এটা মধ্যৱৰ্তী সংশোধন|$1-টা মধ্যৱৰ্তী সংশোধন}} দেখুওৱা হোৱা নাই)",
        "difference-missing-revision": "{{PLURAL:$2|এটা সংস্কৰণ|$2 সংস্কৰণসমূহৰ}} সংশোধনৰ পাৰ্থক্য  ($1) {{PLURAL:$2| পোৱা নগ’ল}}।\n\n\nসাধাৰণতে বিলোপ কৰা এখন পৃষ্ঠাৰ পুৰণা ইতিহাস লিংক অনুসৰণ কৰিলে এনে হয়।\n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} বিলোপন অভিলেখ] চালে অধিক তথ্য পাব।",
        "searchresults": "অনুসন্ধানৰ ফলাফল",
        "filehist-comment": "মন্তব্য",
        "imagelinks": "ফাইল ব্যৱহাৰ",
        "linkstoimage": "তলত দিয়া {{PLURAL:$1|পৃষ্ঠাটোৱে|$1 পৃষ্ঠাবোৰে}} এই ফাইলটো ব্যৱহাৰ কৰে:",
-       "linkstoimage-more": "à¦\8fà¦\87 à¦«à¦¾à¦\87লৰ à¦²à¦\97ত $1ৰà§\8b à¦¬à§\87à¦\9bি {{PLURAL:$1|পà§\83ষà§\8dঠা à¦¸à¦\82যà§\8bà¦\97|পà§\83ষà§\8dঠা à¦¸à¦\82যà§\8bà¦\97}} à¦¹à§\88 à¦\86à¦\9bà§\87 à¥¤\nতলৰ à¦¤à¦¾à¦²à¦¿à¦\95াত {{PLURAL:$1|পà§\8dৰথম à¦ªà§\83ষà§\8dঠা à¦¸à¦\82যà§\8bà¦\97|পà§\8dৰথম $1 à¦ªà§\83ষà§\8dঠা à¦¸à¦\82যà§\8bà¦\97}} à¦¦à§\87à¦\96à§\81à¦\93ৱা à¦¹à§\88à¦\9bà§\87 à¥¤\nà¦\8fà¦\96ন [[Special:WhatLinksHere/$2|সমà§\8dপà§\82ৰà§\8dণ à¦¤à¦¾à¦²à¦¿à¦\95া]]à¦\93 à¦ªà¦¾à¦¬ à¥¤",
+       "linkstoimage-more": "à¦\8fà¦\87 à¦«à¦¾à¦\87লà¦\9fà§\8b $1ৰà§\8b à¦¬à§\87à¦\9bি {{PLURAL:$1|পà§\83ষà§\8dঠাà¦\87 à¦¬à§\8dযৱহাৰ}} à¦\95ৰà§\87।\nতলৰ à¦¤à¦¾à¦²à¦¿à¦\95াত à¦¸à¦\82যà§\8bà¦\9cিত {{PLURAL:$1|পà§\8dৰথম à¦ªà§\83ষà§\8dঠা|পà§\8dৰথম $1à¦\9fা à¦ªà§\83ষà§\8dঠা}} à¦¦à§\87à¦\96à§\81à¦\93ৱা à¦¹à§\88à¦\9bà§\87।\n[[Special:WhatLinksHere/$2|সমà§\8dপà§\82ৰà§\8dণ à¦¤à¦¾à¦²à¦¿à¦\95া à¦\87য়াত]] à¦ªà¦¾à¦¬à¥¤ $1 {{PLURAL:$1|page uses|pages use}} this file.\nThe following list shows the {{PLURAL:$1|first page|first $1 pages}} that use this file only.\nA [[Special:WhatLinksHere/$2|full list]] is available.",
        "nolinkstoimage": "এই ফাইলটো কোনো পৃষ্ঠাই ব্যৱহাৰ কৰা নাই",
        "morelinkstoimage": "এই ফাইলৰ [[Special:WhatLinksHere/$1|অধিক সংযোগ]] চাওক ।",
        "linkstoimage-redirect": "$1 (ফাইল পুনৰ্নিৰ্দেশ) $2",
        "htmlform-cloner-create": "আৰু যোগ কৰক",
        "htmlform-cloner-delete": "আঁতৰাওক",
        "logentry-delete-delete": "$3 পৃষ্ঠাটো $1ৰদ্বাৰা {{GENDER:$2|বিলোপ কৰা হ'ল}}",
-       "logentry-delete-restore": "$1-এ $3 পৃষ্ঠাটো {{GENDER:$2|পুনৰ্সংৰক্ষণ কৰিলে}}",
+       "logentry-delete-restore": "$1-এ $3 ($4) পৃষ্ঠাটো {{GENDER:$2|পুনৰ্সংৰক্ষণ কৰিলে}}",
        "logentry-delete-event": "$3: $4 -ত {{PLURAL:$5|এটা লগ ঘটনা|$5 লগ ঘটনাসমূহ}} -ৰ $1 পৰিৱৰ্তন কৰা দৃশ্যমানতা",
        "logentry-delete-revision": "পৃষ্ঠা $3ত {{PLURAL:$5|এটা সংশোধন|$5 সংশোধনসমূহ}}ৰ দৃশ্যমানতা $1 {{GENDER:$2|য়ে সলালে}}: $4",
        "logentry-delete-event-legacy": "$3ত ল'গ ঘটনাসমূহৰ দৃশ্যমানতা $1 {{GENDER:$2|ৰদ্বাৰা সলোৱা হ'ল}}",
        "logentry-move-move_redir": "পুনৰ্নিৰ্দেশৰে পৃষ্ঠা $3ৰ পৰা $4 $1লৈ স্থানান্তৰ কৰা হ’ল",
        "logentry-move-move_redir-noredirect": "পুনৰ্নিৰ্দেশ নেৰাকৈ এটা পুনৰ্নিৰ্দেশৰ ওপৰেৰে পৃষ্ঠা $3 -ৰ পৰা $4 $1 স্থানান্তৰ কৰা হল",
        "logentry-patrol-patrol": "পৃষ্ঠা $3 -ৰ $1 চিহ্নিত সংশোধন $4 নিৰীক্ষণ কৰা হ'ল",
-       "logentry-patrol-patrol-auto": "পৃষ্ঠা $3 -ৰ $1 চিহ্নিত সংশোধন $4 স্বচালিতভাৱে নিৰীক্ষণ কৰা হ'ল",
+       "logentry-patrol-patrol-auto": "$1 স্বচালিতভাৱে $3 পৃষ্ঠাৰ $4 নং সংশোধন নিৰীক্ষণ কৰা হ'ল বুলি {{GENDER:$2|চিহ্নিত}} কৰিছে",
        "logentry-newusers-newusers": "ব্যৱহাৰকাৰী একাউণ্ট $1 সৃষ্টি কৰা হ'ল",
        "logentry-newusers-create": "ব্যৱহাৰকাৰী একাউণ্ট $1 {{GENDER:$2|সৃষ্টি কৰা হ'ল}}",
        "logentry-newusers-create2": "$1ৰ দ্বাৰা এটা ব্যৱহাৰকাৰী একাউণ্ট $3 {{GENDER:$2|সৃষ্টি কৰা হ'ল}}",
index f2a7a95..ea05ebc 100644 (file)
        "autoblockedtext": "La to direición IP bloquióse automáticamente porque usóla otru usuariu que foi bloquiáu por $1.\nEl motivu conseñáu ye:\n\n:<em>$2</em>\n\n* Principiu del bloquéu: $8\n* Caducidá del bloquéu: $6\n* Usuariu a bloquiar: $7\n\nPues ponete'n contautu con $1 o con otru de los [[{{MediaWiki:Grouppage-sysop}}|alministradores]] p'aldericar sobre'l bloquéu.\n\nTen en cuenta que nun pues usar la función «{{int:emailuser}}» a nun ser que tengas rexistrada una direición de corréu electrónicu válida nes [[Special:Preferences|preferencies d'usuariu]] y que nun tengas torgao usala.\n\nLa to direición IP actual ye $3, y la ID del bloquéu ye #$5.\nPor favor, incluye tolos detalles anteriores nes consultes que faigas.",
        "systemblockedtext": "El to nome d'usuariu o dirección IP bloquióse automáticamente pol software MediaWiki.\nEl motivu dau ye:\n\n:<em>$2</em>\n\n* Entamu del bloquéu: $8\n* Caducidá de bloquéu: $6\n* Destinatariu del bloquéu: $7\n\nLa to dirección IP actual ye $3.\nPor favor, incluye tolos anteriores en cualquier consulta que faigas.",
        "blockednoreason": "nun se dio nengún motivu",
+       "blockedtext-composite": "<strong>El to nome d'usuariu o dirección IP ta bloquiáu.</strong>\n\nEl motivu dau ye:\n\n:<em>$2</em>.\n\n* Entamu del bloquéu: $8\n* Caducidá del bloquéu más llargu: $6\n\n* $5\n\nLa to dirección IP actual ye $3.\nPor favor, incluye tolos anteriores en cualquier consulta que faigas.",
+       "blockedtext-composite-ids": "IDs relevantes del bloquéu: $1 (la to direición IP tamién pué tar na llista prieta)",
+       "blockedtext-composite-no-ids": "La to direición IP apaez en delles llistes prietes",
+       "blockedtext-composite-reason": "Hai múltiples bloqueos escontra la to cuenta y/o direición IP",
        "whitelistedittext": "Tienes d'$1 pa editar páxines.",
        "confirmedittext": "Tienes de confirmar la direición de corréu electrónicu enantes d'editar páxines.\nPor favor, configura y valida la direición de corréu nes [[Special:Preferences|preferencies d'usuariu]].",
        "nosuchsectiontitle": "Nun s'alcontró la seición",
        "right-editmyusercss": "Editar los propios ficheros CSS d'usuariu",
        "right-editmyuserjson": "Editar los ficheros JSON d'usuariu propios",
        "right-editmyuserjs": "Editar los propios ficheros JavaScript d'usuariu",
+       "right-editmyuserjsredirect": "Editar los ficheros JavaScript d'usuariu propios que son redireiciones",
        "right-viewmywatchlist": "Ver la llista de vixilancia propia",
        "right-editmywatchlist": "Editar la llista de vixilancia propia. Tenga en cuenta que dalgunes aiciones amestarán páxines igual, inda ensin esti permisu.",
        "right-viewmyprivateinfo": "Ver los datos privaos propios (p. ex. direición de corréu, nome real)",
        "action-editmyusercss": "editar los ficheros CSS d'usuariu propios",
        "action-editmyuserjson": "editar los ficheros JSON d'usuariu propios",
        "action-editmyuserjs": "editar los ficheros JavaScript d'usuariu propios",
+       "action-editmyuserjsredirect": "editar los ficheros JavaScript d'usuariu propios que son redireiciones",
        "action-viewsuppressed": "ver revisiones anubríes de cualquier usuariu",
        "action-hideuser": "bloquiar un nome d'usuariu, tapeciéndolu al públicu",
        "action-ipblock-exempt": "saltar los bloqueos d'IP, los autobloqueos y los bloqueos de rangos",
        "restrictionsfield-help": "Una única direición IP o rangu CIDR per llinia. P'activar toos, utiliza:<pre>0.0.0.0/0\n::/0</pre>",
        "edit-error-short": "Error: $1",
        "edit-error-long": "Errores:\n\n$1",
+       "specialmute": "Silenciar",
+       "specialmute-submit": "Confirmar",
        "revid": "revisión $1",
        "pageid": "ID de páxina $1",
        "interfaceadmin-info": "$1\n\nLos permisos pa editar los ficheros  CSS, JS y JSON globales del sitiu dixebráronse apocayá del permisu <code>editinterface</code>. Si nun entiendes por qué recibes esti error, llei [[mw:MediaWiki_1.32/interface-admin]].",
index f8bbef5..e6581ed 100644 (file)
        "action-userrights-interwiki": "Digər vikilərdəki istifadəçilərin istifadəçi hüquqlarını dəyişdir",
        "action-siteadmin": "Məlumatlar bazasının bloklanması və blokun götürülməsi",
        "action-sendemail": "e-məktub göndər",
-       "action-editmywatchlist": "İzləmə siyahınızda redaktə",
+       "action-editmywatchlist": "izləmə siyahınızda redaktə",
        "action-viewmywatchlist": "İzləmə siyahınıza baxın",
        "action-viewmyprivateinfo": "Şəxsi məlumatlarınıza baxın",
        "action-editmyprivateinfo": "Şəxsi məlumatlarınızı redaktə edin",
        "rcfilters-highlightmenu-help": "Bu xüsusiyyəti rəngləmək üçün rəng seçin",
        "rcfilters-filtergroup-authorship": "Redaktələrin müəllifliyi",
        "rcfilters-filter-editsbyself-label": "Öz dəyişiklikləriniz",
+       "rcfilters-filter-editsbyself-description": "Sizin öz töhfələriniz.",
        "rcfilters-filter-editsbyother-label": "Başqalarının dəyişiklikləri",
        "rcfilters-filtergroup-user-experience-level": "İstifadəçi qeydiyyatı və təcrübəsi",
        "rcfilters-filter-user-experience-level-registered-label": "Qeydiyyatlı",
+       "rcfilters-filter-user-experience-level-registered-description": "Sistemə daxil olmuş istifadəçilər.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Qeydiyyatsız",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Sistemə daxil olmamış istifadəçilər.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Təcrübəsizlər",
+       "rcfilters-filter-user-experience-level-newcomer-description": "10-dan az redaktəsi və 4 gündən az fəaliyyəti olan qeydiyyatdan keçmiş istifadəçilər.",
        "rcfilters-filter-user-experience-level-learner-label": "Öyrənənlər",
        "rcfilters-filter-user-experience-level-experienced-label": "Təcrübəli istifadəçilər",
        "rcfilters-filtergroup-automated": "Avtomatik redaktələr",
index a000ad4..b6f472e 100644 (file)
@@ -59,7 +59,7 @@
        "tog-norollbackdiff": "تفاوتء حذف کن بعد چه اجرای یک ترینگ",
        "tog-useeditwarning": "وهدی دربیگ مان اصلاح کتگین پیج اگان تغییران سیو نبوت اتنت منء هشتار بدئ",
        "tog-prefershttps": "پر مان بوتنء واسته هروهدء یک ایمنین کنکشنء کارمرز بکن",
-       "underline-always": "دراہءَ",
+       "underline-always": "دراہ‌ئا",
        "underline-never": "هچبر",
        "underline-default": "بروزر پݔسری پئیما",
        "editfont-style": "پونتءِ ٹگلݔنگ",
        "thu": "شرۏچ",
        "fri": "ھرۏچ",
        "sat": "زرۏچ",
-       "january": "ژانویہ",
-       "february": "پبرݔر",
-       "march": "مارچ",
-       "april": "آپرݔل",
-       "may_long": "بÙ\84Ú©Ý\94Úº",
-       "june": "جۏن",
-       "july": "جۏلی",
-       "august": "Ø¢Ú¯Ù\88ست",
-       "september": "سپتمبر",
-       "october": "اکتوبر",
-       "november": "نوامبر",
-       "december": "دسمبر",
+       "january": "بھاران/جنۏری",
+       "february": "اُستپان/پبرݔر",
+       "march": "مۏلمان/مارچ",
+       "april": "کڑا/آپرݔل",
+       "may_long": "سÛ\8fÚ\86Ù\90کاÙ\86\85ئ",
+       "june": "جُلکان/جۏئن",
+       "july": "جَلکشان/جۏلی",
+       "august": "ساÚ\86اÙ\86/آگؤست",
+       "september": "تÙ\8fÙ\85شاÙ\86³Ù¾ØªÙ\85بر",
+       "october": "سارتاÙ\86§Ú©ØªÙ\88بر",
+       "november": "گوَبشان/نومبر",
+       "december": "تاکشاÙ\86¯Ø³Ù\85بر",
        "january-gen": "جنۏری",
        "february-gen": "پبرݔر",
        "march-gen": "مارچ",
        "feb": "پبر",
        "mar": "مارچ",
        "apr": "آپریل",
-       "may": "بلکݔں",
+       "may": "مئ",
        "jun": "جۏن",
        "jul": "جۏل",
        "aug": "آگو",
        "category-file-count-limited": "جهلیگین {{PLURAL:$1|فایل|$1 فایلان}} ته هنوکین دسته اینت",
        "listingcontinuesabbrev": "ادامه.",
        "index-category": "سرتاک بوتگێن پێجان",
-       "noindex-category": "سرتاک نبوتگین پیجان",
+       "noindex-category": "سرتاک نبݔتگݔں تاکاں",
        "broken-file-category": "پیج گون پرشتگین لینک فایل",
        "about": "بارہ‌ئا",
        "article": "محتوا صفحه",
        "returnto": "شوتین بی $1.",
        "tagline": "شه {{SITENAME}}",
        "help": "کومک",
+       "help-mediawiki": "ویکی میدیاء بارہ‌ئا کومک",
        "search": "گردگ",
        "searchbutton": "گردگ",
        "go": "برا",
        "talk": "گپ",
        "views": "چارگان",
        "toolbox": "ابزار",
+       "tool-link-userrights": "{{GENDER:$1|user}}ءِ گروپء ٹگلݔنگ",
+       "tool-link-userrights-readonly": "{{GENDER:$1|user}}ء گروپء سۏج",
+       "tool-link-emailuser": "{{GENDER:$1|user}}ء ایمئیل",
        "imagepage": "بگیند پایلی دیما",
        "mediawikipage": "بگیند پیامی دیما",
        "templatepage": "بگیند تیملیتی دیما",
        "pool-queuefull": "مهزنء صف پر انت",
        "pool-errorunknown": "ناپجارین ارور",
        "pool-servererror": "سرویسء پول سینٹر ودی نبیت ($1).",
+       "poolcounter-usage-error": "اشتباہ اِنت: $1",
        "aboutsite": "{{SITENAME}}ءِ بارہ‌ئا",
        "aboutpage": "Project:باره",
        "copyright": "محتوا مان اجازت نامهٔ $1 انت مگان ایشی که آئی هلاپء آرگ ببیت انت.",
        "filerenameerror": "نه تونیت فایل نام عوض کنت  \"$1\" به \"$2\".",
        "filedeleteerror": "نه تونیت فایل حذف کنت  \"$1\".",
        "directorycreateerror": "نه تونیت مسیر شرکتن  \"$1\".",
+       "directoryreadonlyerror": "\"$1\" آمادہ اِنت",
+       "directorynotreadableerror": "\"$1\" آمادہ نئں",
        "filenotfound": "نه تونیت فایل درگیزگ \"$1\".",
        "unexpected": "ارزش نه لوٹتیگن : \"$1\"=\"$2\".",
        "formerror": "حطا: نه تونیت فرم دیم دنت",
        "badarticleerror": "ای کار ته ای صفحه اجرای نه بیت",
        "cannotdelete": "تاک یان پیکچرء هزپ کنگ «$1» بیت نه کنت.\nبلکین پیسرء دگر شهسء آئرا هزپ کتگ.",
        "cannotdelete-title": "نبیت تاکء «$1» هزپ به بیت.",
+       "delete-scheduled": "''$1''ء تاک پہ پاک کنگء واستا گچݔن بیتہ،بہ دار اِت دنکہ پاک بہ بیت۔",
        "delete-hook-aborted": "هزپ گون قلابء واسته ایر دارگ بوت.\nائ بابتء توضیحء درشان نه بوت.",
        "no-null-revision": "امکان نوکین هالیگ نسخهء اڈ کتن پر تاکء «$1» نه انت",
        "badtitle": "عنوان بد",
        "virus-scanfailed": "اسکن پروش وارت(کد $1)",
        "virus-unknownscanner": "ناشناسین آنتی ویروس:",
        "logouttext": "''' شما انیگء در شُت ات'''\nبزان که تانکه شمئی بروزرء چیرداتگین هافظه پهک مبیت، لهتئ چه تاکان ممکن انت رندا هم هنچوش پیش دارگ ببنت که انگار شما لاگین کتگ ات.",
-       "logout-failed": "ھنیگءَ نہ تۏن اِت در بئ اِت:",
+       "logging-out-notify": "شما ھمے ھنی دربیتگ اݔت،کمے سبر بہ کن اݔت",
+       "logout-failed": "ھنیگءَ نہ تۏن اِت در بئ اِت: $1",
+       "cannotlogoutnow-title": "ھنیگ نہ تۏن اݔت در بہ بئ اݔت",
        "welcomeuser": "وشاتک ات $1!",
        "welcomecreation-msg": "نۏکی شمئی ساب جۏڈ کنگ بیتہ.\nمہ شمۏش اِت کہ وتی [[Special:Preferences|واھشتاں {{SITENAME}}]] ٹگل بہ دئ اِت.",
        "yourname": "کار زوروکی نام:",
        "search-interwiki-more": "(گݔشتِر)",
        "search-interwiki-more-results": "گݔشترݔں نتیجہ",
        "search-relatedarticle": "مربوطین",
+       "search-invalid-sort-order": "$1ء ترتیپ شرّ نئں پݔسری ترتیپ پدا سپتءَ بئ اَنت.\nھنیگݔں ترتیپ: $2",
+       "search-unknown-profile": "$1ء شۏھاز نابزانت اِنت،پݔسری شۏھازی سپتءَ بئ اَنت۔",
        "searchrelated": "مربوط",
        "searchall": "کل",
        "showingresults": "جهل پیش دارگنت تا  {{PLURAL:$1|'''1'''نتیجه|'''$1''' نتایج}} شروع بنت گون #'''$2'''.",
index 50e7aa8..dce3652 100644 (file)
        "helppage-top-gethelp": "Даведка",
        "mainpage": "Галоўная старонка",
        "mainpage-description": "Першая старонка",
-       "policy-url": "Project:Ð\90Ñ\80ганÑ\96заÑ\86Ñ\8bйнаÑ\8f Ð¿Ð°Ð»Ñ\96Ñ\82Ñ\8bка",
+       "policy-url": "Project:СпÑ\96Ñ\81 Ð¿Ñ\80авÑ\96л Ñ\96 Ñ\80Ñ\8dкамендаÑ\86Ñ\8bй",
        "portal": "Супольнасць",
        "portal-url": "Project:Супольнасць",
        "privacy": "Палітыка прыватнасці",
        "delete-legend": "Выдаліць",
        "historywarning": "<strong>Увага:</strong> Старонка, якую вы хочаце выдаліць, мае гісторыю з прыблізна $1 {{PLURAL:$1|праўку|праўкі|правак}}:",
        "historyaction-submit": "Паказаць",
-       "confirmdeletetext": "Ð\92Ñ\8b Ð·Ð±Ñ\96Ñ\80аеÑ\86еÑ\81Ñ\8f Ð²Ñ\8bдалÑ\96Ñ\86Ñ\8c Ñ\81Ñ\82аÑ\80онкÑ\83 Ñ\80азам Ð· Ñ\83Ñ\81Ñ\91й Ñ\8fе Ð³Ñ\96Ñ\81Ñ\82оÑ\80Ñ\8bÑ\8fй Ð¿Ñ\80авак.\nÐ\9fаÑ\86веÑ\80дзÑ\96Ñ\86е Ñ\81вой Ð½Ð°Ð¼ÐµÑ\80 Ð·Ñ\80абÑ\96Ñ\86Ñ\8c Ð³Ñ\8dÑ\82а, Ñ\81ваÑ\91 Ñ\80азÑ\83менне Ð½Ð°Ñ\81Ñ\82Ñ\83пÑ\81Ñ\82ваÑ\9e, Ñ\96 Ñ\88Ñ\82о Ð\92Ñ\8b Ñ\80обÑ\96Ñ\86е Ð³Ñ\8dÑ\82а Ñ\9e Ð°Ð´Ð¿Ð°Ð²ÐµÐ´Ð½Ð°Ñ\81Ñ\86Ñ\96 Ð· [[{{MediaWiki:Policy-url}}|палÑ\96Ñ\82Ñ\8bкай (аÑ\81ноÑ\9eнÑ\8bмÑ\96 Ð¿Ñ\80авÑ\96ламÑ\96)]].",
+       "confirmdeletetext": "Ð\92Ñ\8b Ð·Ð±Ñ\96Ñ\80аеÑ\86еÑ\81Ñ\8f Ð²Ñ\8bдалÑ\96Ñ\86Ñ\8c Ñ\81Ñ\82аÑ\80онкÑ\83 Ñ\80азам Ð· Ñ\83Ñ\81Ñ\91й Ñ\8fе Ð³Ñ\96Ñ\81Ñ\82оÑ\80Ñ\8bÑ\8fй Ð¿Ñ\80авак.\nÐ\9fаÑ\86веÑ\80дзÑ\96Ñ\86е Ñ\81вой Ð½Ð°Ð¼ÐµÑ\80 Ð·Ñ\80абÑ\96Ñ\86Ñ\8c Ð³Ñ\8dÑ\82а, Ñ\81ваÑ\91 Ñ\80азÑ\83менне Ð½Ð°Ñ\81Ñ\82Ñ\83пÑ\81Ñ\82ваÑ\9e, Ñ\96 Ñ\88Ñ\82о Ð\92Ñ\8b Ñ\80обÑ\96Ñ\86е Ð³Ñ\8dÑ\82а Ñ\9e Ð°Ð´Ð¿Ð°Ð²ÐµÐ´Ð½Ð°Ñ\81Ñ\86Ñ\96 Ð· [[{{MediaWiki:Policy-url}}|аÑ\81ноÑ\9eнÑ\8bмÑ\96 Ð¿Ñ\80авÑ\96ламÑ\96 Ð¿Ñ\80аекÑ\82а]].",
        "actioncomplete": "Завершана аперацыя",
        "actionfailed": "Памылка дзеяння",
        "deletedtext": "Старонка \"$1\" была выдалена.\nЗапісы аб нядаўніх выдаленнях гл. ў $2.",
index 4a525c7..fd5c2a0 100644 (file)
        "uploadstash-bad-path-unknown-type": "Неизвестен тип „$1“.",
        "uploadstash-bad-path-unrecognized-thumb-name": "Неразпознато име на миниатюрата.",
        "uploadstash-bad-path-bad-format": "Ключът „$1“ не е в подходящ формат.",
-       "uploadstash-file-not-found-missing-content-type": "Ð\9bипÑ\81ваÑ\89о Ð·Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ Ð·Ð° Ñ\82ипа Ð½Ð° Ñ\81Ñ\8aдÑ\8aÑ\80жание.",
-       "uploadstash-file-not-found-not-exists": "Не може да бъде намерен пътят или файлът не е обикновен.",
+       "uploadstash-file-not-found-missing-content-type": "Ð\9bипÑ\81ваÑ\89а Ð·Ð°Ð³Ð»Ð°Ð²ÐºÐ° Ð·Ð° Ñ\82ипа Ð½Ð° Ñ\81Ñ\8aдÑ\8aÑ\80жаниеÑ\82о.",
+       "uploadstash-file-not-found-not-exists": "Не може да бъде намерен пътят или файлът не е обикновен (plain).",
        "uploadstash-wrong-owner": "Файлът ($1) не принадлежи на текущия потребител.",
        "uploadstash-no-such-key": "Няма такъв ключ ($1), не може да бъде премахнат.",
        "uploadstash-no-extension": "Разширението е нулево.",
        "blocklink": "блокиране",
        "unblocklink": "отблокиране",
        "change-blocklink": "промяна на параметрите на блокирането",
-       "empty-username": "(недостъпно потребителско име)",
+       "empty-username": "(няма налично потребителско име)",
        "contribslink": "приноси",
        "emaillink": "изпращане на е-писмо",
        "autoblocker": "Бяхте блокиран автоматично, тъй като неотдавна IP-адресът Ви е бил ползван от блокирания в момента потребител „[[User:$1|$1]]“.\nПричината за блокирането на „$1“ е: „$2“.",
        "authmanager-provider-password": "Удостоверяване с парола",
        "authmanager-provider-temporarypassword": "Временна парола",
        "authprovider-confirmlink-option": "$1 ($2)",
-       "authprovider-confirmlink-success-line": "$1: Ð£Ñ\81пеÑ\88но Ñ\81вÑ\8aÑ\80зано.",
+       "authprovider-confirmlink-success-line": "$1: Ð£Ñ\81пеÑ\88но Ñ\81вÑ\8aÑ\80зване.",
        "authprovider-confirmlink-failed-line": "$1: $2",
        "authprovider-confirmlink-failed": "Свързването на сметката не е напълно успешно: $1",
        "authprovider-confirmlink-ok-help": "Продължаване след показване на съобщения за неуспешно свързване.",
index bbaf678..55caae8 100644 (file)
@@ -20,7 +20,8 @@
                        "Matma Rex",
                        "Trizek (WMF)",
                        "Dishual",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Huñvreüs"
                ]
        },
        "tog-underline": "Liammoù islinennet",
        "history": "Istor ar bajenn",
        "history_short": "Istor",
        "history_small": "istor",
-       "updatedmarker": "kemmet abaoe ma zaol-sell diwezhañ",
+       "updatedmarker": "kemmet abaoe ho kwel diwezhañ",
        "printableversion": "Stumm da voullañ",
        "permalink": "Chomlec'h ar stumm-mañ",
        "print": "Moullañ",
        "defaultmessagetext": "Testenn dre ziouer",
        "content-failed-to-parse": "C'hwitet eo dielfennadur endalc'had $2 evit ar patrom $1: $3",
        "invalid-content-data": "n'eo ket mat roadennoù an endalc'had",
-       "content-not-allowed-here": "N'eo ket aotreet an endalc'had \"$1\" er bajenn [[:$2]]",
+       "content-not-allowed-here": "N'eo ket aotreet an endalc'had \"$1\" er bajenn [[:$2]] e lec’h \"$3\"",
        "editwarning-warning": "Mar kuitait ar bajenn-mañ e c'hallit koll ar c'hemmoù degaset ganeoc'h.\nMa'z oc'h kevreet e c'hallit diweredekaat ar c'hemenn-diwall-mañ e rann \"{{int:prefs-editing}}\" en ho penndibaboù.",
        "editpage-invalidcontentmodel-title": "N'eo ket skoret ar patrom danvez",
        "editpage-invalidcontentmodel-text": "N'eo ket skoret ar patrom danvez \"$1\".",
        "stub-threshold-disabled": "Diweredekaet",
        "recentchangesdays": "Niver a zevezhioù da ziskouez er c'hemmoù diwezhañ :",
        "recentchangesdays-max": "D'ar muiañ $1 {{PLURAL:$1|deiz|deiz}}",
-       "recentchangescount": "Niver a gemmoù da ziskouez dre ziouer",
-       "prefs-help-recentchangescount": "Kemer a ra an dra-mañ e kont ar c'hemmoù diwezhañ, istor ar pajennoù hag ar marilhoù.",
+       "recentchangescount": "Niver a gemmoù da ziskouez e kemmoù diwezhañ, istorioù ha marilhoù, dre ziouer :",
+       "prefs-help-recentchangescount": "Niver brasañ : 1000",
        "prefs-help-watchlist-token2": "Homañ zo an alc'hwez kuzh d'ho roll-evezhiañ davit boued war ar web. Forzh piv a anavez anezhañ a c'hall lenn ho roll-evezhiañ, setu na lavarit grit diwar e benn. M'ho pez ezhomm, e c'hallit [[Special:ResetTokens|assevel anezhañ]].",
        "savedprefs": "Enrollet eo bet ar penndibaboù.",
        "savedrights": "Enrollet eo bet strolladoù implijer {{GENDER:$1|$1}}.",
        "timezoneregion-europe": "Europa",
        "timezoneregion-indian": "Meurvor Indez",
        "timezoneregion-pacific": "Meurvor Habask",
-       "allowemail": "Aotren ar posteloù a-berzh implijerien all",
+       "allowemail": "Aotreañ implijerien all da gas din posteloù",
        "email-allow-new-users-label": "Aotreañ e-bostoù a-berzh an implijerien nevez",
        "email-blacklist-label": "Difenn d'an implijerien-se da gas un e-bost din:",
        "prefs-searchoptions": "Klask",
        "grouppage-autoconfirmed": "{{ns:project}}: Implijerien bet kadarnaet ent emgefre",
        "grouppage-bot": "{{ns:project}}:Botoù",
        "grouppage-sysop": "{{ns:project}}:Merourien",
-       "grouppage-interface-admin": "{{ns:project}}:Merourien etrefas",
+       "grouppage-interface-admin": "{{ns:project}}:Merourien an etrefas",
        "grouppage-bureaucrat": "{{ns:project}}: Burevidi",
        "grouppage-suppress": "{{ns:project}}: Diverkerien",
        "right-read": "Lenn ar pajennoù",
        "rcfilters-exclude-button-off": "Skarzhañ ar re dibabet",
        "rcfilters-exclude-button-on": "Re dibabet skarzhet",
        "rcfilters-view-tags": "Kemmoù merket",
+       "rcfilters-liveupdates-button": "Nevesaat war-eeun",
        "rcfilters-filter-showlinkedfrom-label": "Diskouez ar c'hemmoù war ar bajennoù liammet",
        "rcfilters-filter-showlinkedto-label": "Diskouez ar c'hemmoù war ar bajennoù liammet",
        "rcfilters-target-page-placeholder": "Skrivañ anv ar bajenn (pe rummad)",
        "ipbreason": "Abeg :",
        "ipbreason-dropdown": "*Abegoù stankañ boutinañ\n** Degas titouroù faos\n** Tennañ danvez eus ar pajennoù\n** Degas liammoù Strobus war-du lec'hiennoù diavaez\n** Degas danvez diboell/dizoare er pajennoù\n** Emzalc'h hegazus/handeus betek re\n** Mont re bell gant implij meur a gont\n** Anv implijer n'eo ket aotreet",
        "ipb-hardblock": "Mirout ouzh an implijerien kevreet da zegas kemmoù adalek ar chomlec'h IP-mañ",
-       "ipbcreateaccount": "Mirout ouzh an implijer da grouiñ kontoù",
-       "ipbemailban": "Mirout ouzh an implijer da gas posteloù",
+       "ipbcreateaccount": "Krouiñ kontoù",
+       "ipbemailban": "Kas posteloù",
        "ipbenableautoblock": "Stankañ war-eeun ar chomlec'h IP diwezhañ implijet gant an den-mañ hag an holl chomlec'hioù a c'hallfe klask kemmañ traoù drezo diwezhatoc'h",
        "ipbsubmit": "Stankañ an implijer-mañ",
        "ipbother": "Prantad all",
        "ipboptions": "2 eurvezh:2 hours,1 devezh:1 day,3 devezh:3 days,1 sizhunvezh:1 week,2 sizhunvezh:2 weeks,1 mizvezh:1 month,3 mizvezh:3 months,6 mizvezh:6 months,1 bloaz:1 year,da viken:infinite",
        "ipbhidename": "Kuzhat anv an implijer er rolloù hag er c'hemmoù",
        "ipbwatchuser": "Evezhiañ pajennoù implijer ha kaozeal an implijer-mañ",
-       "ipb-disableusertalk": "Mirout ouzh an implijer-mañ da implijout e bajenn gaozeal dezhañ e-unan e-keit hag emañ stanket",
+       "ipb-disableusertalk": "Kemmañ e bajenn gaozeal dezhañ",
        "ipb-change-block": "Adstankañ an implijer-mañ gant an hevelep arventennoù",
        "ipb-confirm": "Kadarnaat ar stankadenn",
        "ipb-pages-label": "Pajennoù",
        "import-nonewrevisions": "N'eus bet enporzhiet degasadenn ebet (aze e oant dija, pe distaolet e oant bet abalamour da fazioù).",
        "xml-error-string": "$1 war al linenn $2, bann $3 (okted $4) : $5",
        "import-upload": "Enporzhiañ roadennoù XML",
-       "import-token-mismatch": "Kollet eo bet roadennoù an dalc'h.\n\nMarteze oc'h bet digevreet. <strong>Gwiriit emaoc'h mat kevreet ha klaskit en-dro</strong>.\nMa ne'z a ket en-dro c'hoazh, klaskit [[Special:UserLogout|digevreañ]] hag adkevreañ en-dro, ha gwiriit mat ec'h asant ho merdeer degemer toupinoù digant al lec'hienn-mañ.",
+       "import-token-mismatch": "Kollet eo bet roadennoù an dalc'h.\n\nMarteze oc'h bet digevreet. '''Gwiriit emaoc'h kevreet mat ha klaskit en-dro'''.\nMa ne'z a ket en-dro c'hoazh, klaskit [[Special:UserLogout|digevreañ]] hag adkevreañ, ha gwiriit mat ec'h asant ho merdeer degemer toupinoù digant al lec'hienn-mañ.",
        "import-invalid-interwiki": "Dibosupl enporzhiañ adal ar wiki spisaet.",
        "import-error-edit": "N'eo ket bet enporzhiet ar bajenn \"$1\" peogwir n'oc'h ket aotreet da zegas kemmoù enni.",
        "import-error-create": "N'eo ket bet enporzhiet ar bajenn \"$1\" peogwir n'oc'h ket aotreet da grouiñ anezhi.",
        "authmanager-email-help": "Chomlec'h postel",
        "authmanager-realname-label": "Anv gwir",
        "authmanager-realname-help": "Anv gwir an implijer",
-       "authmanager-provider-password": "Gwiriekadur diazezet war ur ger-termen",
+       "authmanager-provider-password": "Gwiriekadur diazezet war ur ger-tremen",
        "authmanager-provider-password-domain": "Dilesadur diazezet war ur ger-tremen hag an domani",
        "authmanager-provider-temporarypassword": "Ger-tremen da c'hortoz",
        "authprovider-confirmlink-message": "Diwar an taolioù-esae diwezhañ graet ganeoc'h evit kevreañ e c'haller liammañ ar c'hontoù da heul ouzh ho kont wiki. Ur wech liammet e c'hallit kevreañ dre ar c'hontoù-se. Diuzit ar re zo da vezañ liammet.",
index c17299f..f6f7023 100644 (file)
        "pool-servererror": "El servei de recompte de la reserva no és disponible ($1).",
        "poolcounter-usage-error": "Error d'ús: $1",
        "aboutsite": "Quant al projecte {{SITENAME}}",
-       "aboutpage": "Project:Quant al",
+       "aboutpage": "Project:Quant a",
        "copyright": "El contingut està disponible sota la llicència $1 si no s'indica el contrari.",
        "copyrightpage": "{{ns:project}}:Drets d'autor",
        "currentevents": "Actualitat",
        "autoblockedtext": "La vostra adreça IP ha estat blocada automàticament perquè va ser usada per un usuari actualment blocat. Aquest usuari va ser blocat per l'{{GENDER:$1|administrador|administradora}} $1. El motiu donat per al blocatge és aquest:\n\n:<em>$2</em>\n\n* Inici del blocatge: $8\n* Final del blocatge: $6\n* Usuari blocat: $7\n\nPodeu contactar l'usuari $1 o algun altre dels [[{{MediaWiki:Grouppage-sysop}}|administradors]] per a discutir el blocatge.\n\nRecordeu que per a poder usar l'opció «{{int:emailuser}}» haureu d'haver validat una adreça de correu electrònic a les vostres [[Special:Preferences|preferències]].\n\nEl número d'identificació de la vostra adreça IP és $3, i l'ID del blocatge és #$5. Si us plau, incloeu aquestes dades en totes les consultes que feu.",
        "systemblockedtext": "El vostre nom d'usuari o adreça IP ha estat blocada automàticament pel MediaWiki.\nEl motiu donat és:\n\n:<em>$2</em>\n\n* Inici del blocatge: $8\n* Caducitat del blocatge: $6\n* Destinatari del blocatge: $7\n\nLa vostra adreça IP actual és $3.\nAfegiu les dades de més amunt en qualsevol consulta que feu al respecte.",
        "blockednoreason": "no s'ha donat cap motiu",
+       "blockedtext-composite-no-ids": "La vostra adreça IP apareix en diferents llistes negres",
        "blockedtext-composite-reason": "Hi ha diferents blocatges associats al vostre compte i/o adreça IP",
        "whitelistedittext": "Heu de $1 per modificar pàgines.",
        "confirmedittext": "Heu de confirmar la vostra adreça electrònica abans de poder modificar les pàgines. Definiu i valideu la vostra adreça electrònica a través de les vostres [[Special:Preferences|preferències d'usuari]].",
        "edit-error-short": "Error: $1",
        "edit-error-long": "Errors:\n\n$1",
        "specialmute": "Silencia",
+       "specialmute-success": "S'han actualitzat les vostres preferències de silenciament. Vegeu tots els usuaris silenciats a les [[Special:Preferences|your preferències]].",
        "specialmute-submit": "Confirma",
        "specialmute-label-mute-email": "Silencia el correu electrònic d'aquest usuari",
+       "specialmute-header": "Seleccioneu les vostres preferències de silenciament de l'usuari <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "No s’ha trobat el nom d’usuari que heu indicat.",
        "specialmute-login-required": "Inicieu una sessió per canviar les preferències de silenciament.",
+       "mute-preferences": "Preferències de silenciament",
        "revid": "revisió $1",
        "pageid": "ID de pàgina $1",
        "rawhtml-notallowed": "No és possible fer servir les etiquetes &lt;html&gt; fora de les pàgines normals.",
index 88e5bc1..7081e67 100644 (file)
        "lockmanager-fail-acquirelock": "«$1» блоктоха цатарло.",
        "lockmanager-fail-openlock": "Блоктохаран «$1» файл схьаелла цаелира.",
        "lockmanager-fail-releaselock": "\"$1\" блокдӀаяккха цаелира.",
+       "zip-file-open-error": "Архивна талламбархьама файл схьаеллаш гӀалат даьлла.",
+       "zip-wrong-format": "Билгалйина файл — ZIP-архив яц.",
+       "zip-unsupported": "ХӀокху ZIP-файло лелош ю таронаш, MediaWiki ловш йоцу.\nИза кхочуш талла еш яц.",
        "uploadstash": "Къайлаха чуяккхар",
        "uploadstash-clear": "ДӀацӀанъян къайла йолу файлаш",
        "uploadstash-nofiles": "Хьан къайла файлаш яц.",
        "allmessages-filter-unmodified": "Хийцан йоцурш",
        "allmessages-filter-all": "Массо",
        "allmessages-filter-modified": "Хийцнарш",
-       "allmessages-prefix": "Ð\9bÑ\83Ñ\8cÑ\82Ñ\82Ñ\83Ñ\80г Ð¾Ñ\86Ñ\83 Ð´ÐµÑ\88аÑ\85Ñ\8cалÑ\85е:",
+       "allmessages-prefix": "Ð\9bÑ\83Ñ\8cÑ\82Ñ\82Ñ\83Ñ\80г Ð¿Ñ\80еÑ\84икÑ\81Ñ\86а:",
        "allmessages-language": "Мотт:",
        "allmessages-filter-submit": "Дехьа гӀо",
        "allmessages-filter-translate": "Гочйе",
index fb0fc71..55157d9 100644 (file)
@@ -98,7 +98,9 @@
                        "McDutchie",
                        "Johanna Strodt (WMDE)",
                        "Andi-3",
-                       "1233qwer1234qwer4"
+                       "1233qwer1234qwer4",
+                       "MarkusRost",
+                       "Mcandri13"
                ]
        },
        "tog-underline": "Links unterstreichen:",
        "mainpage": "Hauptseite",
        "mainpage-description": "Hauptseite",
        "policy-url": "Project:Richtlinien",
-       "portal": "Gemeinschaftsportal",
+       "portal": "Gemeinschafts&shy;portal",
        "portal-url": "Project:Gemeinschaftsportal",
        "privacy": "Datenschutz",
        "privacypage": "Project:Datenschutz",
        "systemblockedtext": "Dein Benutzername oder deine IP-Adresse wurde von MediaWiki automatisch gesperrt.\nDer angegebene Grund ist:\n\n:<em>$2</em>\n\n* Beginn der Sperre: $8\n* Ablauf der Sperre: $6\n* Sperre betrifft: $7\n\nDeine aktuelle IP-Adresse ist $3.\nBitte gib alle oben stehenden Details in jeder Anfrage an.",
        "blockednoreason": "keine Begründung angegeben",
        "blockedtext-composite": "<strong>Dein Benutzername oder deine IP-Adresse wurde gesperrt.</strong>\n\nDer Angegebene Grund ist:\n\n:<em>$2</em>\n\n* Beginn der Sperre: $8\n* Ablauf der längsten Sperre: $6\n\n* $5\n\nDeine aktuelle IP-Adresse ist $3.\nBitte gib alle oben stehenden Details in jeder Anfrage an.",
+       "blockedtext-composite-no-ids": "Deine IP-Adresse taucht in mehreren Sperrlisten auf",
        "blockedtext-composite-reason": "Es gibt mehrere Sperren gegen dein Benutzerkonto und/oder deine IP-Adresse",
        "whitelistedittext": "Du musst dich $1, um Seiten bearbeiten zu können.",
        "confirmedittext": "Du musst deine E-Mail-Adresse erst bestätigen, bevor du Bearbeitungen durchführen kannst. Bitte ergänze und bestätige deine E-Mail in den [[Special:Preferences|Einstellungen]].",
index 51b9846..9988341 100644 (file)
        "rcfilters-clear-all-filters": "Clear all filters",
        "rcfilters-show-new-changes": "View new changes since $1",
        "rcfilters-search-placeholder": "Filter changes (use menu or search for filter name)",
+       "rcfilters-search-placeholder-mobile": "Filters",
        "rcfilters-invalid-filter": "Invalid filter",
        "rcfilters-empty-filter": "No active filters. All contributions are shown.",
        "rcfilters-filterlist-title": "Filters",
        "linkaccounts": "Link accounts",
        "linkaccounts-success-text": "The account was linked.",
        "linkaccounts-submit": "Link accounts",
+       "cannotunlink-no-provider-title": "There are no linked accounts to unlink",
+       "cannotunlink-no-provider": "There are no linked accounts that can be unlinked.",
        "unlinkaccounts": "Unlink accounts",
        "unlinkaccounts-success": "The account was unlinked.",
        "authenticationdatachange-ignored": "The authentication data change was not handled. Maybe no provider was configured?",
index 9110c93..36303ed 100644 (file)
        "svg-long-error": "SVG fitxategi ez baliagarria: $1",
        "show-big-image": "Jatorrizko fitxategia",
        "show-big-image-preview": "Aurreikuspen honen neurria: $1.",
-       "show-big-image-preview-differ": "$2 fitxategi honen $3 aurreikuspenaren tamainia: $1.",
+       "show-big-image-preview-differ": "$2 fitxategi honen $3 aurreikuspenaren tamaina: $1.",
        "show-big-image-other": "Bestelako {{PLURAL:$2|bereizmena|bereizmenak}}: $1.",
        "show-big-image-size": "$1 × $2 pixel",
        "file-info-gif-looped": "kiribildua",
        "mediastatistics": "Media estatistikak",
        "mediastatistics-summary": "Igotako fitxategien estatistikak. Hemen ikus daitekeena fitxategiaren azken bertsioa baino ez da. Fitxategiaren bertsio zahar edo ezabatuak kanpo daude.",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 byte}} ($2; %$3)",
-       "mediastatistics-bytespertype": "Atal honetarako fitxategi tamainia totala: {{PLURAL:$1|$1 byte}} ($2; $3%).",
-       "mediastatistics-allbytes": "Fitxategi guztietarako fitxategi tamainia osoa: {{PLURAL:$1|$1 byte|$1 bytes}} ($2).",
+       "mediastatistics-bytespertype": "Atal honetako fitxategi tamaina, guztira: {{PLURAL:$1|$1 byte}} ($2; % $3).",
+       "mediastatistics-allbytes": "Fitxategi guztien tamaina, guztira: {{PLURAL:$1|$1 byte}} ($2).",
        "mediastatistics-table-mimetype": "MIME mota",
        "mediastatistics-table-extensions": "Luzapen posibleak",
        "mediastatistics-table-count": "Fitxategi kopurua",
index 21b54cf..2cc372a 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Don Alessandro",
                        "Ильнар",
-                       "Рашат Якупов"
+                       "Рашат Якупов",
+                       "Ерней"
                ]
        },
        "exif-imagewidth": "Киңлек",
        "exif-photometricinterpretation": "Төс моделе",
        "exif-orientation": "Кадр куелышы",
        "exif-samplesperpixel": "Төс өлешләре саны",
-       "exif-xresolution": "Ð\93оÑ\80изонÑ\82алÑ\8c Ð·Ñ\83Ñ\80лык",
-       "exif-yresolution": "Ð\92еÑ\80Ñ\82икалÑ\8c Ð·Ñ\83Ñ\80лык",
-       "exif-datetime": "Файл үзгәртүләр датасы һәм вакыты",
-       "exif-imagedescription": "РÓ\99Ñ\81емнең Ð¸Ñ\81еме",
-       "exif-make": "Камераның җитештерүчесе",
-       "exif-model": "Камераның төре",
-       "exif-software": "Ð\9fÑ\80огÑ\80аммалÑ\8b Ñ\82Ó\99Ñ\8dмин Ð¸Ñ\82елеÑ\88",
+       "exif-xresolution": "ЯÑ\82ма Ð°Ñ\87Ñ\8bклык",
+       "exif-yresolution": "Ð\90Ñ\81ма Ð°Ñ\87Ñ\8bклык",
+       "exif-datetime": "Файл үзгәреше датасы һәм вакыты",
+       "exif-imagedescription": "СÑ\83Ñ\80Ó\99Ñ\82 Ð°Ñ\82амаÑ\81Ñ\8b",
+       "exif-make": "Камера җитештерүчесе",
+       "exif-model": "Камера төре",
+       "exif-software": "Ð\9aÑ\83лланÑ\8bлган Ð¿Ñ\80огÑ\80амма",
        "exif-artist": "Автор",
-       "exif-copyright": "Автор хокуклары иясе",
+       "exif-copyright": "Авторлык хокукы иясе",
        "exif-exifversion": "Exif юрамасы",
-       "exif-flashpixversion": "FlashPix Ñ\8eÑ\80амаÑ\81Ñ\8bн Ñ\82Ó\99Ñ\8dмин Ð¸Ñ\82Ò¯",
-       "exif-colorspace": "Төсләр тирәлеге",
+       "exif-flashpixversion": "FlashPix Ñ\8fÑ\80аÑ\88лÑ\8b Ñ\8eÑ\80амаÑ\81Ñ\8b",
+       "exif-colorspace": "Төсләр киңлеге",
        "exif-componentsconfiguration": "Төсләр төзелешенең конфигурациясе",
        "exif-compressedbitsperpixel": "Кысылудан соң төснең тирәнлеге",
-       "exif-pixelxdimension": "РÓ\99Ñ\81емнең киңлеге",
-       "exif-pixelydimension": "РÓ\99Ñ\81емнең биеклеге",
+       "exif-pixelxdimension": "СÑ\83Ñ\80Ó\99Ñ\82 киңлеге",
+       "exif-pixelydimension": "СÑ\83Ñ\80Ó\99Ñ\82 биеклеге",
        "exif-usercomment": "Өстәмә җавап",
        "exif-relatedsoundfile": "Тавыш файлы җавабы",
        "exif-datetimeoriginal": "Чын вакыты",
@@ -36,7 +37,7 @@
        "exif-subsectime": "Файлны үзгәртүнең өлешле секунд вакыты",
        "exif-subsectimeoriginal": "Чын ясалу вакытының өлеш секунды",
        "exif-subsectimedigitized": "Санлаштыру вакытының өлеш секунды",
-       "exif-exposuretime": "ЭкÑ\81позиÑ\86иÑ\8f Ð²Ð°ÐºÑ\8bÑ\82ы",
+       "exif-exposuretime": "ЭкÑ\81позиÑ\86иÑ\8f Ð¾Ð·Ð°ÐºÐ»Ñ\8bгы",
        "exif-exposuretime-format": "$1 с ($2)",
        "exif-fnumber": "Диафрагманың саны",
        "exif-fnumber-format": "f/$1",
        "exif-sharpness": "Ачыклыгы",
        "exif-devicesettingdescription": "Камераның көйләүләр тасвирламасы",
        "exif-subjectdistancerange": "Төшерү җисеменә кадәр ераклык",
-       "exif-imageuniqueid": "РÓ\99Ñ\81емнең саны (ID)",
+       "exif-imageuniqueid": "СÑ\83Ñ\80Ó\99Ñ\82 саны (ID)",
        "exif-gpsversionid": "GPS мәгълүматы блогының версиясе",
        "exif-gpslatituderef": "Киңлек индексы",
        "exif-gpslatitude": "Киңлек",
        "exif-gpslongituderef": "Озынлык индексы",
        "exif-gpslongitude": "Озынлык",
-       "exif-gpsaltituderef": "Ð\91иеклек индексы",
-       "exif-gpsaltitude": "Ð\91иеклек",
+       "exif-gpsaltituderef": "ЮгаÑ\80Ñ\8bлÑ\8bк индексы",
+       "exif-gpsaltitude": "ЮгаÑ\80Ñ\8bлÑ\8bк",
        "exif-gpstimestamp": "UTC буенча вакыт",
        "exif-gpssatellites": "Кулланылган иярченнәр тасвирламасы",
        "exif-gpsstatus": "Алгычның статусы һәм төшерү вакыты",
        "exif-languagecode": "Тел",
        "exif-iimversion": "IIM юрамасы",
        "exif-iimcategory": "Төркем",
+       "exif-iimsupplementalcategory": "Өстәмә төркемнәр",
        "exif-identifier": "Идентификатор",
        "exif-label": "Билгеләү",
-       "exif-copyrighted": "Автор хокуклары халәте:",
-       "exif-copyrightowner": "Автор хокуклары иясе",
+       "exif-copyrighted": "Авторлык хокукы халәте",
+       "exif-copyrightowner": "Авторлык хокукы иясе",
        "exif-usageterms": "Куллану шартлары",
        "exif-orientation-1": "Гадәти",
        "exif-orientation-3": "180° ка борылган",
-       "exif-componentsconfiguration-0": "юк",
+       "exif-componentsconfiguration-0": "барлыкта юк",
        "exif-exposureprogram-0": "Билгесез",
        "exif-exposureprogram-1": "Кулдан җайлау режимы",
        "exif-exposureprogram-2": "Программалы режим (гади)",
        "exif-meteringmode-6": "Өлешләтә",
        "exif-meteringmode-255": "Башка",
        "exif-lightsource-0": "Билгесез",
+       "exif-lightsource-1": "Көндезге яктылык",
        "exif-lightsource-4": "Яктылык",
-       "exif-lightsource-9": "Яхшы һава торышы",
+       "exif-lightsource-9": "Аяз",
+       "exif-lightsource-10": "Болытлы",
        "exif-lightsource-11": "Күләгә",
        "exif-flash-mode-3": "автоматик режим",
        "exif-focalplaneresolutionunit-2": "дюйм",
        "exif-gpsstatus-a": "Үлчәү тәмамланмаган",
        "exif-gpsstatus-v": "Мәгълүматларны җибәрүгә әзер",
        "exif-gpsspeed-k": "км/сәг",
-       "exif-gpsspeed-m": "милÑ\8f/сәг",
-       "exif-gpsspeed-n": "Төен",
+       "exif-gpsspeed-m": "милÑ\8c/сәг",
+       "exif-gpsspeed-n": "узел",
        "exif-gpsdestdistance-k": "Километр",
        "exif-gpsdestdistance-m": "Миль",
        "exif-gpsdestdistance-n": "Диңгез миле",
        "exif-gpsdop-fair": "Ярыйсы ($1)",
        "exif-gpsdop-poor": "Начар ($1)",
        "exif-dc-date": "Дата(лар)",
-       "exif-dc-publisher": "Нәшрият",
+       "exif-dc-publisher": "Нәшир",
        "exif-dc-relation": "Бәйле медиа",
        "exif-dc-rights": "Хокуклар",
        "exif-dc-source": "Чыганак медиа",
        "exif-dc-type": "Медиа төре",
        "exif-rating-rejected": "Кире кагылды",
-       "exif-isospeedratings-overflow": "65535-тән күп",
+       "exif-isospeedratings-overflow": "65535 тән күбрәк",
        "exif-iimcategory-hth": "Сәламәтлек",
        "exif-iimcategory-lab": "Хезмәт",
-       "exif-iimcategory-wea": "Һава тырышы",
+       "exif-iimcategory-wea": "Һава торышы",
        "exif-urgency-normal": "Гадәти ($1)",
        "exif-urgency-low": "Түбән ($1)",
        "exif-urgency-high": "Югары ($1)"
index 755b38f..84e08b8 100644 (file)
        "tags-edit-reason": "Syy:",
        "tags-edit-revision-submit": "Toteuta muutokset {{PLURAL:$1|tähän versioon|$1 versioon}}",
        "tags-edit-logentry-submit": "Lähetä muutoksesi {{PLURAL:$1|tähän lokimerkintään|$1 lokimerkintään}}",
-       "tags-edit-success": "Muutokset on tehty.",
+       "tags-edit-success": "Muutokset toteutettiin.",
        "tags-edit-failure": "Muutoksia ei voitu toteuttaa: $1",
        "tags-edit-nooldid-title": "Kohdeversio ei ole kelvollinen",
        "tags-edit-nooldid-text": "Et ole joko määrittänyt sitä kohdeversiota, johon tämä toimenpide kohdistuu, tai sitten määrättyä versiota ei ole olemassa.",
index 9e0d89c..9b60e21 100644 (file)
        "search-interwiki-more": "(plus)",
        "search-interwiki-more-results": "résultats supplémentaires",
        "search-relatedarticle": "Reliés",
+       "search-invalid-sort-order": "L’ordre de tri de $1 n’est pas reconnu, le tri par défaut sera appliqué. Les ordres de tri valides sont : $2",
+       "search-unknown-profile": "Le profil de recherche de $1 n’est pas reconnu, le profil de recherche par défaut sera appliqué.",
        "searchrelated": "reliés",
        "searchall": "tout",
        "showingresults": "Affichage de <strong>$1</strong> résultat{{PLURAL:$1||s}} à partir du n°<strong>$2</strong>.",
        "linkaccounts": "Lier les comptes",
        "linkaccounts-success-text": "Le compte a été lié.",
        "linkaccounts-submit": "Lier les comptes",
+       "cannotunlink-no-provider-title": "Il n’y a pas de compte lier à délier",
+       "cannotunlink-no-provider": "Il n’y a pas de compte lié qui puisse être délié.",
        "unlinkaccounts": "Dissocier les comptes",
        "unlinkaccounts-success": "Le compte a été dissocié.",
        "authenticationdatachange-ignored": "Les modifications de données d’authentification n’ont pas été gérées. Peut-être aucun fournisseur n’a-t-il été configuré ?",
index 64f112a..4378161 100644 (file)
        "pool-queuefull": "Piha ke kiʻo kiū",
        "pool-errorunknown": "Hewa ʻikeʻole",
        "aboutsite": "No {{SITENAME}}",
-       "aboutpage": "Project:No translatewiki.net",
        "copyright": "Aia nā mealoko ma lalo o ka laikini $1 inā noka ʻole ia.",
        "copyrightpage": "{{ns:project}}:Kūleana kope",
        "currentevents": "Nūhou",
index 79f0e30..28bf8f0 100644 (file)
        "search-interwiki-more": "(עוד)",
        "search-interwiki-more-results": "תוצאות נוספות",
        "search-relatedarticle": "קשור",
+       "search-invalid-sort-order": "סדר המיון של $1 אינו מוכר, יחול הסדר שמוגדר לפי ברירת המחדל. סדרי המיון התקינים הם: $2",
+       "search-unknown-profile": "פרופיל חיפוש של $1 אינו מוכר, יחול הסדר שמוגדר לפי ברירת המחדל.",
        "searchrelated": "קשור",
        "searchall": "הכול",
        "showingresults": "{{PLURAL:$1|מוצגת תוצאה <strong>אחת</strong>|מוצגות עד <strong>$1</strong> תוצאות}} החל ממספר <strong>$2</strong>:",
        "linkaccounts": "קישור חשבונות",
        "linkaccounts-success-text": "החשבון קושר.",
        "linkaccounts-submit": "קישור החשבונות",
+       "cannotunlink-no-provider-title": "אין חשבונות מקושרים שאפשר לבטל את הקישור שלהם",
+       "cannotunlink-no-provider": "אין חשבונות מקושרים שהקישור שלהם יכול להיות מבוטל.",
        "unlinkaccounts": "ביטול הקישור בין חשבונות",
        "unlinkaccounts-success": "קישור החשבון בוטל.",
        "authenticationdatachange-ignored": "השינוי בנתוני האימות לא הצליח. ייתכן שלא הוגדר ספק.",
index 1c23bb8..a8cfdb8 100644 (file)
        "search-result-category-size": "{{PLURAL:$1|անդամ}} ({{PLURAL:$2|ենթակատեգորիա}}, {{PLURAL:$3|նիշք}})",
        "search-redirect": "(վերահղում $1 էջից)",
        "search-section": "(բաժին $1)",
-       "search-category": "(կատեգորիա $1)",
+       "search-category": "(կատեգորիա  $1)",
        "search-file-match": "(համապատասխանում է նիշքի բովանդակությանը)",
        "search-suggest": "Գուցե նկատի ունե՞ք՝ $1",
        "search-interwiki-caption": "Կից նախագծեր",
        "specialpage-empty": "Հայցումը արդյունքներ չվերադարձրեց։",
        "lonelypages": "Որբ էջեր",
        "lonelypagestext": "Հետևյալ էջերին չկան հղումներ այս վիքիի այլ էջերից։",
-       "uncategorizedpages": "Չդասակարգված էջեր",
+       "uncategorizedpages": "Առանց կատեգորիաների էջեր",
        "uncategorizedcategories": "Չդասակարգված կատեգորիաներ",
        "uncategorizedimages": "Չդասակարգված պատկերներ",
        "uncategorizedtemplates": "Չդասակարգված կաղապարներ",
index 031237a..54ea594 100644 (file)
        "december-date": "$1 Դեկտեմբեր",
        "period-am": "Նախ Կէսօր",
        "period-pm": "Կէսօրէն Յետոյ",
-       "pagecategories": "{{PLURAL:$1|Կատեգորիա|Կատեգորիաներ}}",
+       "pagecategories": "{{PLURAL:$1|Ստորոգութիւն|Ստորոգութիւններ}}",
        "category_header": "«$1» ստորոգութեան մէջ էջեր",
        "subcategories": "Ենթակատեգորիաներ",
        "category-media-header": "\"$1\" ստորոգութեան հաղորդամիջոց",
        "category-empty": "<em>Այս ստորոգութիւնը ներկայիս դատարկ է։<em>",
-       "hidden-categories": "{{PLURAL:$1|Թաքցուած կատեգորիա|Թաքցուած կատեգորիաներ}}",
+       "hidden-categories": "{{PLURAL:$1|Թաքուն ստորոգութիւն|Թաքուն ստորոգութիւններ}}",
        "hidden-category-category": "Թաքցուած կատեգորիաներ",
        "category-subcat-count": "{{PLURAL:$2|Այս կատեգորիան ունի միայն հետեւեալ ենթակատեգորիան։|Այս կատեգորիան ունի հետեւեալ {{PLURAL:$1|ենթակատեգորիա|ենթակատեգորիաներ}}ը՝ ընդհանուր $2էն։}}",
        "category-subcat-count-limited": "Այս ստորոգութիւնը ունի հետեւեալ {{PLURAL:$1|ենթաստորոգութիւն|$1 ենթաստորոգութիւններ}}։",
        "nstab-mediawiki": "Հաղորդագրութիւն",
        "nstab-template": "Կաղապար",
        "nstab-help": "Օգնութեան էջ",
-       "nstab-category": "Կատեգորիա",
+       "nstab-category": "Ստորոգութիւն",
        "mainpage-nstab": "Գլխաւոր Էջ",
        "nosuchaction": "Այս գործողութիւնը չկայ",
        "nosuchspecialpage": "Այդպիսի յատուկ էջ չկայ",
        "preview": "Կանխաստուգել",
        "showpreview": "Կանխաստուգել",
        "showdiff": "Ցուցնել փոփոխութիւնները",
-       "anoneditwarning": "<strong>Ô¶Õ£Õ¸Ö\82Õ·Õ¡Ö\81Õ¸Ö\82Õ´Ö\89</strong> Õ\84Õ¸Ö\82Õ¿Ö\84 Õ£Õ¸Ö\80Õ®Õ¡Õ® Õ¹Õ§Ö\84 Õ°Õ¡Õ´Õ¡Õ¯Õ¡Ö\80Õ£Ö\89 Õ\88Ö\80Õ¥Ö\82Õ§ Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ´Õ« ÕºÕ¡Ö\80Õ¡Õ£Õ¡ÕµÕ«Õ¶ Õ±Õ¥Ö\80 IP Õ°Õ¡Õ½Ö\81Õ§Õ¶ Õ¿Õ¥Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ¯Õ¨ Õ¤Õ¡Õ¼Õ¶Õ¡Õµ Õ¢Õ¸Õ¬Õ¸Ö\80Õ«Õ¶Ö\89 ÔµÕ©Õ§ <strong>[$1 Õ´Õ¸Ö\82Õ¿Ö\84 Õ£Õ¸Ö\80Õ®Õ§Ö\84]</strong> Õ¯Õ¡Õ´ <strong>[$2 Õ½Õ¿Õ¥Õ²Õ®Õ§Ö\84 Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ«Ö\81Õ« Õ°Õ¡Õ·Õ«Ö\82]</strong>, Õ±Õ¥Ö\80 Õ¯Õ¡Õ¿Õ¡Ö\80Õ¡Õ® Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ´Õ¶Õ¥Ö\80Õ¨ Õ¯Õ¨ Õ¯Õ¡ÕºÕ¸Ö\82Õ«Õ¶ Õ±Õ¥Ö\80 Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ«Ö\81Õ« Õ¡Õ¶Õ¸Ö\82Õ¶Õ«Õ¶ Õ°Õ¥Õ¿, ինչպէս նաեւ կ՚ունենաք այլ առաւելութիւններ։",
+       "anoneditwarning": "<strong>Ô¶Õ£Õ¸Ö\82Õ·Õ¡Ö\81Õ¸Ö\82Õ´Ö\89</strong> Õ\80Õ¡Õ´Õ¡Õ¯Õ¡Ö\80Õ£ Õ´Õ¸Ö\82Õ¿Ö\84 Õ¹Õ§Ö\84 Õ£Õ¸Ö\80Õ®Õ¡Õ®Ö\89 Õ\88Ö\80Õ¥Ö\82Õ§ Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ´Õ¡Õ¶ ÕºÕ¡Ö\80Õ¡Õ£Õ¡ÕµÕ«Õ¶ Õ\81Õ¥Ö\80 IP Õ°Õ¡Õ½Ö\81Õ§Õ¶ Õ¿Õ¥Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ¯Õ¨ Õ¤Õ¡Õ¼Õ¶Õ¡Õµ Õ¢Õ¸Õ¬Õ¸Ö\80Õ«Õ¶Ö\89 ÔµÕ©Õ§ <strong>[$1 Õ´Õ¸Ö\82Õ¿Ö\84 Õ£Õ¸Ö\80Õ®Õ§Ö\84]</strong> Õ¯Õ¡Õ´ <strong>[$2 Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ«Ö\81Õ« Õ°Õ¡Õ·Õ«Ö\82 Õ½Õ¿Õ¥Õ²Õ®Õ§Ö\84]</strong>, Õ\81Õ¥Ö\80 Õ¯Õ¡Õ¿Õ¡Ö\80Õ¡Õ® Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ´Õ¶Õ¥Ö\80Õ¨ Õ¯Õ¨ Õ¯Õ¡ÕºÕ¸Ö\82Õ«Õ¶ Õ±Õ¥Ö\80 Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ«Ö\81Õ« Õ¡Õ¶Õ¸Ö\82Õ¶Õ«Õ¶, ինչպէս նաեւ կ՚ունենաք այլ առաւելութիւններ։",
        "blockedtitle": "Մասնակիցը արգելափակուած է",
        "blockedtext": "<strong>Ձեր մասնակցային անունը կամ IP հասցէն արգելակուած է։</strong>\n\nԱրգելակումը կատարուած է $1ի կողմէ.\nՊարտճառը՝ <em>$2</em>.\n\n* Արգելակման սկիբժ՝ $8\n* Արգելակման աւարտ՝ $6\n* արգելակուած առարկայ՝ $7\n\nԿրնաք կապուիլ $1ի կամ այլ անդատներու հետ [[{{MediaWiki:Grouppage-sysop}}|վարիչ]] արգելակման մասին զրուցելու համար.\nՉէք կրնար օգտագործել \"{{int:emailuser}}\" հնարաւորութիւնը բացի եթէ նշած էք իմակի վաւերական հասցէ մը ձեր [[Special:Preferences|account preferences]] եւ արգելակուած չէ վեր անոր օգտագործումը.\nՁեր ընթացիկ IP հասցէն է $3, եւ արգելակման ինքնութեան համարն է #$5.\nԿը շնդրենք որ այս մանրամասնութիւնները նշէք ձեր բոլոր թղթակցութիւններուն մէջ։",
        "loginreqtitle": "Կը խնդրուի մուտք գործել համակարգ",
        "search-result-category-size": "{{PLURAL:$1|1 անդամ|$1 անդամներ}} ({{PLURAL:$2|1 ենթաստորոգութիւն|$2 ենթաստորոգութիւններ}}, {{PLURAL:$3|1 նիշք|$3 նիշքեր}})",
        "search-redirect": "(Վերայղուած է $1-էն)",
        "search-section": "(բաժին $1)",
-       "search-category": "(Õ¯Õ¡Õ¿Õ¥Õ£Õ¸Ö\80Õ«Õ¡ $1)",
+       "search-category": "(Õ½Õ¿Õ¸Ö\80Õ¸Õ£Õ¸Ö\82Õ©Õ«Ö\82Õ¶ $1)",
        "search-file-match": "(համապատասխան է նիշքի բովանդակութեան)",
        "search-suggest": "$1 Նկատի ունի՞ք",
        "search-interwiki-default": "$1 արդիւնք.",
        "rcfilters-activefilters-hide": "Թաքցնել",
        "rcfilters-activefilters-show": "Ցուցնել",
        "rcfilters-limit-title": "Ցուցադրուող արդիւնքներ",
+       "rcfilters-filtergroup-authorship": "Ներդրումներու հեղինակ",
+       "rcfilters-filter-editsbyself-label": "Կողմէդ կատարուած փոփոխութիւնները",
+       "rcfilters-filter-editsbyself-description": "Անձնական ներդրումներդ։",
+       "rcfilters-filter-editsbyother-label": "Ուրիշներու կողմէ կատարուած փոփոխութիւնները",
+       "rcfilters-filter-editsbyother-description": "Բոլոր փոփոխութիւնները բացի կատարածէդ",
+       "rcfilters-filtergroup-user-experience-level": "Մասնակիցի արձանագրութիւն եւ փորձառութիւն",
+       "rcfilters-filter-user-experience-level-registered-label": "Արձանագրուած",
+       "rcfilters-filter-user-experience-level-registered-description": "Մուտք գործած խմբագիրներ։",
+       "rcfilters-filter-user-experience-level-unregistered-label": "Չարձանագրուած",
+       "rcfilters-filter-user-experience-level-unregistered-description": "Մուտք չգործած խմբագիրներ",
+       "rcfilters-filter-user-experience-level-newcomer-label": "Նորեկներ",
+       "rcfilters-filter-user-experience-level-newcomer-description": "10-էն նուազ խմբագրումներ կամ 4 օրուան աշխուժութիւն ունեցող արձանագրուած խմբագիրներ։",
+       "rcfilters-filter-user-experience-level-learner-label": "Սորվողներ",
+       "rcfilters-filter-user-experience-level-learner-description": "Արձանագրուած խմբագիրներ, որոնց փորձառութիւնը նորեկներու եւ փորձառու խմբագիրներու միջեւ է։",
+       "rcfilters-filter-user-experience-level-experienced-label": "Փորձառու մասնակիցներ",
+       "rcfilters-filter-user-experience-level-experienced-description": "500-էն աւելի խմբագրումներ եւ 30 օրուան աշխուժութիւն ունեցող արձանագրուած խմբագիրներ։",
+       "rcfilters-filtergroup-automated": "Մեքենայական ներդրումներ",
+       "rcfilters-filter-bots-label": "Մեքենայիկ",
+       "rcfilters-filter-bots-description": "Մեքենայական գործիքներով կատարուած խմբագրումներ",
+       "rcfilters-filter-humans-label": "Մարդ (ոչ մեքենայիկ)",
+       "rcfilters-filter-humans-description": "Մարդ-խմբագիրներէ կատարուած խմբագրումներ",
+       "rcfilters-filtergroup-reviewstatus": "Կարգավիճակը վերատեսնել",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "Չհսկուած",
+       "rcfilters-filter-reviewstatus-manual-description": "Որպէս հսկուած ձեռքով նշուած խմբագրումներ։",
+       "rcfilters-filter-reviewstatus-manual-label": "Ձեռքով հսկուած",
+       "rcfilters-filter-reviewstatus-auto-description": "Փորձառու մասնակիցներու խմբագրումները, որոնք մեքենայականօրէն նշուած են իբրեւ հսկուած։",
+       "rcfilters-filter-reviewstatus-auto-label": "Ինքնահսկուած",
+       "rcfilters-filtergroup-significance": "Կարեւորութիւն",
+       "rcfilters-filter-minor-label": "Ջնջին խմբագրումներ",
        "rcnotefrom": "Ներքեւ {{PLURAL:$5|փոփոխութիւնն է|փոփոխութիւններն են}} սկսեալ <strong>$3, $4</strong> (մինչեւ <strong>$1</strong> ցոյց տրուած).",
        "rclistfrom": "Ցոյց տալ նոր փոփոխութիւնները սկսած $3 $2",
        "rcshowhideminor": "$1 չնչին խմբագրումներ",
        "sharedupload-desc-here": "Այս նիշքը առնուած է $1-էն եւ կրնայ օգտագործուիլ այլ նախագիծերու մէջ։ $1-ի մէջ անոր [$2 նիշքը նկարագրող էջի]ի նկարագրութիւնը ներկայացուած է ստորեւ։",
        "filepage-nofile": "Այս անունով նիշք մը գոյութիւն չունի։",
        "upload-disallowed-here": "Այս նիշքը կարելի չէ ջնջել ու փոխարինել։",
+       "unusedtemplates": "Չօգտագործուող կաղապարներ",
        "randompage": "Պատահական էջ",
+       "randomincategory-category": "Ստորոգութիւն:",
        "statistics": "Վիճակագրութիւն",
        "statistics-header-pages": "Էջերու վիճակագրութիւն",
        "statistics-header-edits": "Խմբագրումներու վիճակագրութիւն",
        "statistics-edits-average": "Իւրաքանչիւր էջի խմբագրումներուն միջին թիւը",
        "statistics-users-active": "Աշխոյժ մասնակիցներ",
        "pageswithprop-submit": "Յառաջ",
+       "doubleredirects": "Կրկնակի վերայղումներ",
        "double-redirect-fixer": "Վերայղումներու շտկիչ",
+       "brokenredirects": "Չշղթայուած յղումներ",
        "brokenredirects-edit": "խմբագրել",
        "brokenredirects-delete": "ջնջել",
-       "withoutinterwiki": "Լեզւային յղումներ չպարունակող էջեր",
+       "withoutinterwiki": "Լեզուային յղումներ չպարունակող էջեր",
        "withoutinterwiki-submit": "Ցուցնել",
+       "fewestrevisions": "Նուազ վերաքաղուած էջեր",
        "nbytes": "$1 {{PLURAL:$1|պայթ}}",
+       "ncategories": "$1 {{PLURAL:$1|ստորոգութիւն|ստորոգութիւններ}}",
        "nmembers": "$1 {{PLURAL:$1|անդամ|անդամներ}}",
+       "uncategorizedpages": "Առանց ստորոգութիւններու էջեր",
+       "uncategorizedcategories": "Ենթաստորոգութիւն չունեցող ստորոգութիւններ",
+       "uncategorizedimages": "Առանց ստորոգութիւններու պատկերներ",
+       "uncategorizedtemplates": "Առանց ստորոգութիւններու կաղապարներ",
+       "unusedcategories": "Չօգտագործուող ստորոգութիւններ",
+       "unusedimages": "Չօգտագործուող նիշքեր",
+       "wantedcategories": "Անհրաժեշտ ստորոգութիւններ",
        "prefixindex": "Բոլոր նախածանցներով էջերը",
        "prefixindex-submit": "Ցուցնել",
+       "deadendpages": "Յղումներ չունեցող էջեր",
+       "protectedpages": "Պաշտպանուած էջեր",
        "protectedpages-page": "Էջ",
+       "protectedtitles": "Պաշտպանուած վերնագրեր",
        "listusers": "Մասնակիցներու ցանկ",
        "newpages": "Նոր էջեր",
        "newpages-submit": "Ցուցնել",
        "redirect-revision": "Էջի տարբերակներ",
        "redirect-file": "Նիշքի անունը",
        "specialpages": "Յատուկ էջեր",
+       "specialpages-group-maintenance": "Շարունակական տեղեկագրեր",
        "tag-filter": "[[Special:Tags|Պիտակներու]] զտիչ՝",
        "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Պիտակ}}]]: $2",
        "tags-active-yes": "Այո",
index 107c22f..5db5e83 100644 (file)
@@ -65,7 +65,8 @@
                        "Pebaryan",
                        "Veracious",
                        "Mnam23",
-                       "Shirayuki"
+                       "Shirayuki",
+                       "ArlandGa"
                ]
        },
        "tog-underline": "Garis bawahi pranala:",
        "history": "Riwayat halaman",
        "history_short": "Versi terdahulu",
        "history_small": "riwayat",
-       "updatedmarker": "berubah sejak kunjungan terakhir saya",
+       "updatedmarker": "dimutakhirkan sejak kunjungan terakhir saya",
        "printableversion": "Versi cetak",
        "permalink": "Pranala permanen",
        "print": "Cetak",
        "autoblockedtext": "Alamat IP Anda telah terblokir secara otomatis karena digunakan oleh pengguna lain, yang diblokir oleh $1. Pemblokiran dilakukan dengan alasan:\n\n:<em>$2</em>\n\n* Diblokir sejak: $8\n* Blokir kedaluwarsa pada: $6\n* Sasaran pemblokiran: $7\n\nAnda dapat menghubungi $1 atau [[{{MediaWiki:Grouppage-sysop}}|pengurus]] lainnya untuk membicarakan pemblokiran ini.\n\nAnda tidak dapat menggunakan fitur \"{{int:emailuser}}\" kecuali Anda telah memasukkan alamat surel yang sah di [[Special:Preferences|preferensi akun]] Anda dan Anda tidak diblokir untuk menggunakannya.\n\nAlamat IP Anda saat ini adalah $3, dan ID pemblokiran adalah #$5.\nTolong sertakan informasi-informasi ini dalam setiap pertanyaan Anda.",
        "systemblockedtext": "Nama pengguna atau alamat IP Anda telah diblokir secara otomatis oleh MediaWiki.\nAlasan yang diberikan adalah:\n\n:<em>$2</em>\n\n* Diblokir sejak: $8\n* Blokir kedaluwarsa pada: $6\n* Sasaran pemblokiran: $7\n\nAlamat IP Anda saat ini adalah $3\nMohon sertakan semua perincian di atas dalam setiap pertanyaan yang Anda ajukan.",
        "blockednoreason": "tidak ada alasan yang diberikan",
+       "blockedtext-composite-no-ids": "Alamat IP Anda muncul dalam daftar hitam ganda",
        "blockedtext-composite-reason": "Ada pemblokiran berganda terhadap akun Anda dan/atau alamat IP Anda.",
        "whitelistedittext": "Anda harus $1 untuk dapat menyunting halaman.",
        "confirmedittext": "Anda harus mengkonfirmasikan dulu alamat surel Anda sebelum menyunting halaman.\nHarap masukkan dan validasikan alamat surel Anda melalui [[Special:Preferences|halaman preferensi pengguna]] Anda.",
        "mw-widgets-abandonedit-title": "Apakah Anda yakin?",
        "mw-widgets-copytextlayout-copy": "Salin",
        "mw-widgets-copytextlayout-copy-fail": "Gagal menyalin ke papan klip.",
-       "mw-widgets-copytextlayout-copy-success": "Salin ke papan klip.",
+       "mw-widgets-copytextlayout-copy-success": "Disalin ke papan klip.",
        "mw-widgets-dateinput-no-date": "Tanggal tidak ada yang terpilih",
        "mw-widgets-dateinput-placeholder-day": "TTTT-BB-HH",
        "mw-widgets-dateinput-placeholder-month": "TTTT-BB",
        "linkaccounts": "Tautkan akun",
        "linkaccounts-success-text": "Akun telah ditautkan.",
        "linkaccounts-submit": "Tautkan akun",
+       "cannotunlink-no-provider": "Tidak ada akun yang tertaut yang dapat dibatalkan tautannya.",
        "unlinkaccounts": "Lepastautkan akun",
        "unlinkaccounts-success": "Akun berikut telah dilepastautkan.",
        "authenticationdatachange-ignored": "Otentikasi perubahan data tidak dijalankan. Mungkin tidak ada provider yang diatur?",
index a965592..66930fd 100644 (file)
        "statistics-pages-desc": "Omna pagini dil Wiki, inkluzite pagini por facar diskuti, ridirektadi, edc.",
        "statistics-files": "Adkargita arkivi",
        "statistics-edits": "Quanto di redakti pos ke {{SITENAME}} kreesis",
-       "statistics-edits-average": "Mezavalora quanto di redakti per pagino",
+       "statistics-edits-average": "Mezavalora quanto di redakti po pagino",
        "statistics-users": "Enrejistrita uzeri",
        "statistics-users-active": "Aktiva uzeri",
        "statistics-users-active-desc": "Uzeri qui facis ula agado dum la lasta {{PLURAL:$1|dio|$1 dii}}",
        "cachedspecial-refresh-now": "Vidar la lasta.",
        "categories": "Kategorii",
        "categories-submit": "Montrez",
+       "categoriespagetext": "La sequanta {{PLURAL:$1|kategorio|kategorii}} existas en ca wiki, e povas uzesar, o ne.\nVidez anke [[Special:WantedCategories|dezirata kategorii]].",
        "categoriesfrom": "Montrez kategorii komencante en:",
        "deletedcontributions": "Efacita uzero-kontributaji",
        "deletedcontributions-title": "Efacita uzero-kontributaji",
        "thumbnail-more": "Plugrandigar",
        "thumbnail_error": "Ne sucesas krear imajeto: $1",
        "import": "Importacar pagini",
+       "import-upload-filename": "Nomo dil arkivo:",
        "import-comment": "Komento:",
        "importtext": "Voluntez exportacar l' arkivo de la fonto-wikio per [[Special:Export|exportacilo]]. Registragar ol a vua komputero ed adkargar ol hike.",
        "importfailed": "La importaco faliis: $1",
        "redirect-page": "Identigo di la pagino",
        "redirect-revision": "Revizo di la pagino",
        "redirect-file": "Arkivo-nomo",
+       "fileduplicatesearch-filename": "Nomo dil arkivo:",
        "fileduplicatesearch-submit": "Serchar",
        "specialpages": "Specala pagini",
        "specialpages-group-maintenance": "Raporti pri manteno",
        "pagelanguage": "Modifikar la linguo di la pagino",
        "pagelang-language": "Linguo",
        "right-pagelang": "Modifikar l'idiomo di la pagino",
+       "mediastatistics": "Statistiki pri arkivi",
+       "mediastatistics-summary": "Statistiki pri arkivi sendita. To nur montras la maxim recenta versiono de ula arkivo. Anciena od efacata versioni ne montresas.",
        "mediastatistics-nbytes": "{{PLURAL:$1|$1 bicoko*|$1 bicoki*}} ($2; $3%)",
+       "mediastatistics-bytespertype": "Grandezo dil arkivi de ca sesiono: {{PLURAL:$1|$1 bicoko*|$1 bicoki*}} ($2; $3%).",
+       "mediastatistics-allbytes": "Grandeso totala por omna arkivi: {{PLURAL:$1|$1 bicoko*|$1 bicoki*}} ($2).",
+       "mediastatistics-table-extensions": "Posibla tipo di arkivi (.webm, .png...)",
+       "mediastatistics-table-count": "Quanto di arkivi",
+       "mediastatistics-table-totalbytes": "Totala grandeso",
+       "mediastatistics-header-bitmap": "Imaji di \"bitmap\"",
+       "mediastatistics-header-total": "Omna arkivi",
        "special-characters-group-latin": "Latina",
        "special-characters-group-latinextended": "Latina extensita",
        "special-characters-group-symbols": "Simboli",
index 2cc9f55..31bd626 100644 (file)
        "systemblockedtext": "Il tuo nome utente o l'indirizzo IP è stato bloccato automaticamente da MediaWiki.\nLa motivazione del blocco è la seguente:\n\n:''$2''\n\n* Inizio del blocco: $8\n* Scadenza del blocco: $6\n* Intervallo di blocco: $7\n\nL'indirizzo IP attuale è $3.\nSi prega di specificare tutti i dettagli qui inclusi nel compilare qualsiasi richiesta di chiarimenti.",
        "blockednoreason": "nessuna motivazione indicata",
        "blockedtext-composite": "<strong>Il tuo nome utente o indirizzo IP sono stati bloccati.</strong>\n\nLa motivazione del blocco è la seguente:\n\n:<em>$2</em>.\n\n* Inizio del blocco: $8\n* Scadenza del blocco più lungo: $6\n\n* $5\n\nL'indirizzo IP attuale è $3.\nSi prega di specificare tutti i dettagli qui inclusi nel compilare qualsiasi richiesta di chiarimenti.",
-       "blockedtext-composite-ids": "ID del blocco rilevante: $1 (il tuo indirizzo IP potrebbe essere anche nella lista nera)",
-       "blockedtext-composite-no-ids": "Il tuo indirizzo IP figura in varie liste nere.",
-       "blockedtext-composite-reason": "Ci sono molteplici blocchi contro il tuo account e/o indirizzo IP.",
+       "blockedtext-composite-ids": "ID del blocco rilevante: $1 (anche il tuo indirizzo IP potrebbe essere nella lista nera)",
+       "blockedtext-composite-no-ids": "Il tuo indirizzo IP è contenuto in varie liste nere.",
+       "blockedtext-composite-reason": "Sono attivi più blocchi sulla tua utenza e/o indirizzo IP",
        "whitelistedittext": "Per modificare le pagine è necessario $1.",
        "confirmedittext": "Per essere abilitati alla modifica delle pagine è necessario confermare il proprio indirizzo e-mail. Per impostare e confermare l'indirizzo servirsi delle [[Special:Preferences|preferenze]].",
        "nosuchsectiontitle": "Impossibile trovare la sezione",
        "edit-gone-missing": "Impossibile aggiornare la pagina.\nSembra che sia stata cancellata.",
        "edit-conflict": "Conflitto di edizione.",
        "edit-no-change": "La modifica è stata ignorata poiché non sono stati apportati cambiamenti al testo.",
-       "edit-slots-cannot-add": "{{PLURAL:$1|Il seguente slot non è|I seguenti slot non sono}} supportati qui: $2",
+       "edit-slots-cannot-add": "{{PLURAL:$1|Il seguente slot non è supportato|I seguenti slot non sono supportati}} qui: $2",
        "postedit-confirmation-created": "La pagina è stata creata.",
        "postedit-confirmation-restored": "La pagina è stata ripristinata.",
        "postedit-confirmation-saved": "La modifica è stata salvata.",
        "expansion-depth-exceeded-warning": "Questa pagina ha superato la profondità di espansione",
        "parser-unstrip-loop-warning": "Rilevato ciclo di Unstrip",
        "unstrip-depth-warning": "Superati i limiti di ricorsione di Unstrip ($1)",
-       "unstrip-size-warning": "Superati i limiti di grandezza di unstrip ($1)",
-       "unstrip-size-category": "Pagine nelle quali il limite di unstrip non viene rispettato",
+       "unstrip-depth-category": "Pagine nelle quali il limite di ricorsione di Unstrip viene superato",
+       "unstrip-size-warning": "Superati i limiti di grandezza di Unstrip ($1)",
+       "unstrip-size-category": "Pagine nelle quali il limite di grandezza di Unstrip viene superato",
        "converter-manual-rule-error": "Rilevato errore nella regola manuale di conversione della lingua",
        "undo-success": "Questa modifica può essere annullata.\nControlla le differenze mostrate sotto fra le due versioni per essere certo che il contenuto corrisponda a quanto desiderato, e quindi salvare le modifiche per completare la procedura di annullamento.",
        "undo-failure": "Impossibile annullare la modifica a causa di un conflitto con modifiche intermedie.",
        "action-changetags": "aggiungere o rimuovere specifiche etichette su singole versioni o voci di registro",
        "action-deletechangetags": "cancellare le etichette dal database",
        "action-purge": "aggiornare questa pagina",
-       "action-editinterface": "modifica l'interfaccia utente",
-       "action-editusercss": "modifica i file CSS di altri utenti",
-       "action-edituserjson": "modifica i file JSON di altri utenti",
-       "action-edituserjs": "modifica i file JavaScript di altri utenti",
-       "action-editsitecss": "modifica il CSS globale del sito",
-       "action-editsitejson": "modifica il JSON globale del sito",
-       "action-editsitejs": "modifica il Javascript globale del sito",
-       "action-editmyusercss": "modifica i propri file CSS",
-       "action-editmyuserjson": "modifica i propri file JSON",
-       "action-editmyuserjs": "modifica i propri file JavaScript",
+       "action-editinterface": "modificare l'interfaccia utente",
+       "action-editusercss": "modificare i file CSS di altri utenti",
+       "action-edituserjson": "modificare i file JSON di altri utenti",
+       "action-edituserjs": "modificare i file JavaScript di altri utenti",
+       "action-editsitecss": "modificare il CSS globale del sito",
+       "action-editsitejson": "modificare il JSON globale del sito",
+       "action-editsitejs": "modificare il Javascript globale del sito",
+       "action-editmyusercss": "modificare i propri file CSS",
+       "action-editmyuserjson": "modificare i propri file JSON",
+       "action-editmyuserjs": "modificare i propri file JavaScript",
        "nchanges": "$1 {{PLURAL:$1|modifica|modifiche}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|dall'ultima visita}}",
        "enhancedrc-history": "cronologia",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|byte}}",
        "limitreport-expansiondepth": "Massima profondità di espansione",
        "limitreport-expensivefunctioncount": "Numero funzioni parser dispendiose",
+       "limitreport-unstrip-depth": "Profondità di ricorsione di Unstrip",
+       "limitreport-unstrip-size": "Dimensione post-espansione di Unstrip",
        "limitreport-unstrip-size-value": "$1/$2 {{PLURAL:$2|byte}}",
        "expandtemplates": "Espandi i template",
        "expand_templates_intro": "Questa pagina speciale elabora un wikitesto espandendo tutti i template presenti.\nCalcola inoltre il risultato delle funzioni supportate dal parser come\n<code><nowiki>{{</nowiki>#language:…}}</code> e delle variabili di sistema quali\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>,\nvale a dire praticamente tutto ciò che si trova tra doppie parentesi graffe.",
index 5d7d405..f85a0f5 100644 (file)
        "specialmute-error-invalid-user": "요청한 사용자 이름을 찾을 수 없습니다.",
        "specialmute-email-footer": "{{BIDI:$2}}의 이메일 환경 설정을 관리하려면 <$1>을(를) 방문해 주십시오.",
        "specialmute-login-required": "알림 미표시 환경 설정을 변경하려면 로그인해 주십시오.",
+       "mute-preferences": "알림 미표시 환경 설정",
        "revid": "$1 판",
        "pageid": "페이지 ID $1",
        "interfaceadmin-info": "$1\n\n사이트 전체에 쓰이는 CSS/JS/JSON 파일의 편집 권한이 최근 <code>editinterface</code> 권한에서 분리되었습니다. 왜 이 오류가 발생하는지 이해가 되지 않는다면, [[mw:MediaWiki_1.32/interface-admin]]을 참고하십시오.",
index cb6b134..de1f164 100644 (file)
        "printableversion": "Verscion da stanpâ",
        "permalink": "Ingancio fisso",
        "print": "Stampa",
-       "view": "Visualizza",
+       "view": "Vixoalìzza",
        "view-foreign": "Véddi in sce $1",
        "edit": "Modìfica",
        "edit-local": "Modifica descrission locale",
        "page_first": "prìmma",
        "page_last": "ùrtima",
        "histlegend": "Confronto tra verscioîn: selession-a e cascette corispondenti a-e verscioîn dexidiæ e schissa Invio oppû o pomello da basso.\n\nLegenda: (corr) = differense co-a verscion corrente, (prec) = differense co-a verscion precedente, '''m''' = modiffica minô",
-       "history-fieldset-title": "Çerca de verscioin",
+       "history-fieldset-title": "Çerca e verscioin",
        "history-show-deleted": "Solo verscioin scassæ",
        "histfirst": "prìmma",
        "histlast": "ùrtima",
        "recentchanges-page-removed-from-category": "[[:$1]] rimosso da-a categoria",
        "recentchanges-page-removed-from-category-bundled": "[[:$1]] rimossa da-a categoria, [[Special:WhatLinksHere/$1|questa pagina a l'è inclusa a l'interno di atre pagine]]",
        "autochange-username": "Modiffica aotomattica MediaWiki",
-       "upload": "Carrega 'n file",
+       "upload": "Càrega 'n file",
        "uploadbtn": "Carreghilo",
        "reuploaddesc": "Torna a-o moddulo pe-o caregamento.",
        "upload-tryagain": "Invia a descrission do file modificou",
        "imagelinks": "Utilìzzo do file",
        "linkstoimage": "{{PLURAL:$1|A segoente pàgina a contegne|E segoenti $1 pàgine contegnan}} colegaménti a-o file:",
        "linkstoimage-more": "Ciù de $1 {{PLURAL:$1|pagina aponta|pagine apontan}} a questo file.\nA seguente lista a mostra {{PLURAL:$1|a primma paggina ch'a l'aponta|e primme $1 paggine ch'apontan}} a sto file.\nL'è disponibile un [[Special:WhatLinksHere/$2|elenco completo]].",
-       "nolinkstoimage": "No gh'è nisciun-a paggina inganciâ a sto file.",
+       "nolinkstoimage": "No gh'è nisciun-a pàgina ch'a contegne sto file.",
        "morelinkstoimage": "Vixualizza [[Special:WhatLinksHere/$1|di atri inganci]] a questo file.",
        "linkstoimage-redirect": "$1 (rendriççamento file) $2",
        "duplicatesoffile": "{{PLURAL:$1|O seguente file o l'è un dupricou|I seguenti $1 file son di dupricæ}} de questo file ([[Special:FileDuplicateSearch/$2|urteioî detaggi]]):",
        "tooltip-t-contributions": "Lista de contribûssioin de {{GENDER:$1|questo|questa}} utente",
        "tooltip-t-emailuser": "Invia un messaggio email a {{GENDER:$1|questo|questa}} utente",
        "tooltip-t-info": "Urteioî informaçioin insce questa pagina",
-       "tooltip-t-upload": "Carrega di file murtimediali",
+       "tooltip-t-upload": "Càrega di files",
        "tooltip-t-specialpages": "Lista de tùtte e pagine speçiâli",
        "tooltip-t-print": "Verscion stanpabbile de sta paggina",
        "tooltip-t-permalink": "Colegaménto fisso a sta revixión da pàgina",
index a1a00f1..8bbf28c 100644 (file)
        "directorynotreadableerror": "تیرنشونگٱ \"$1\" ڤٱننی نؽ.",
        "filenotfound": "نمؽ تونؽت جانؽا $1 ناْ بٱجۊرؽت.",
        "unexpected": "ٱرزایش نهاستٱ: \"$1\"=\"$2\".",
-       "formerror": "خٱتا:نمۊئٱ نوم بٱلگٱ ناْ ڤمو بۉیؽت.",
+       "formerror": "خٱتا:نمۊئٱ نوم بٱلگٱ ناْ ڤمو بۉئؽت.",
        "badarticleerror": "اؽ کنشکاری د اؽ بٱلگٱ ٱنجوم نمۊئٱ.",
        "cannotdelete": "نمۊئٱ بٱلگٱیا جانؽا $1 پاکسا با.\nگاسؽ د ایسنی کٱسؽ تر ڤٱ ناْ پاکسا کردٱ.",
        "cannotdelete-title": "نمۊئٱ بٱلگٱ $1 پاکسا با",
        "delete-hook-aborted": "پاکسا کاری ڤا قولاڤ نوئاگیری بیٱ.\nهیچ تۉزیهی سیش نؽ.",
        "no-null-revision": "سی بٱلگٱ $1 ڤانیٱری خونسا ناْ دۏرس بٱکؽت",
-       "badtitle": "داسون گٱن",
+       "badtitle": "داسوݩ گٱن",
        "badtitletext": "داسون بٱلگٱ هاستنی نادؽارٱ، یٱ یاٛ داسوݩ مؽنجا زڤونی یا مؽنجا ڤیکی اْشتبائٱ.\nگاسؽ یٱ د ڤٱر گرتٱ یاٛ کاراکتر یا چٱن تا کاراکتر با کاْ نمۊئٱ د داسونؽا ڤ کارشو گرت.",
        "title-invalid-empty": "داسون بٱلگٱ هاستنی هالٛیٱ یا فقٱت مؽنونٱ دار یاٛ نوم یا نوم جا ئٱ.",
        "title-invalid-utf8": "داسون بٱلگٱ هاستنی مؽنونٱ دار یاٛ نماجا UTF-8 نادؽارٱ.",
        "passwordremindertitle": "رازینٱ گوئارسن موڤٱقٱتی تازٱ سی {{SITENAME}}",
        "passwordremindertext": "یئ نأفأر (گاسی خوتوٙ،د تیرنئشوٙن آی پی $1) یئ گئل رازینە گوڤاردئن هأنی سی {{SITENAME}}($4) حاستە.یئ گئل رازینە گوڤاردئن موڤأقأتی سی کاریاری\"$2\" رأڤأندیاری بیە و د \"$3\" جاگئر بییە. أر یە نە حاستیتە،شما بایأد ئیسئ روٙییت ڤامین و یئ گئل رازینە گوڤاردئن هأنی نە ئنتئخاڤ بأکیت.\nرازینە گوڤاردئن موڤأقأتی د {{PLURAL:$5|یئ روٙ|$5 روٙزیا}}  تأموٙم بوٙە.\n\nأر یئ نأفأر هأنی ئی حاست نە داشتوٙە، یا أر رازینە گوڤاردئن توٙنە د ڤیرتوٙ ئوٙما، و أر حاستیت ڤئنە آلئشت کاری بأکیت، گاسی شوما د ئی پئیغوم تیە پوٙشی بأکیت و بئحایت ڤئ کار گئرئتئن رازینە گوڤاردئن دئماتریتوٙ نە دئماداری بأکیت.",
        "noemail": "هیژ تیرنشوݩ ٱنجوماناماٛیی سی کاریار $1 زٱفت ناٛییٱ.",
-       "noemailcreate": "شما بایٱد یاٛ تیرنشوݩ ٱنجومانامٱ جادیار سی خوتو داشتۊیؽت.",
-       "passwordsent": "یاٛ رازینٱ گوئارسن هنی کلٛ بیٱ سی تیرنشوݩ ٱنجوماناماٛیی کاْ \"$1\" ڤاش سٱبت نوم کردٱ.\nخاهش مؽکم هنی رۉیؽت ڤامؽن ۉ اۊساْ باٛیرتش.",
+       "noemailcreate": "شما بایٱد یاٛ تیرنشوݩ ٱنجومانامٱ جادیار سی خوتو داشتۊئؽت.",
+       "passwordsent": "یاٛ رازینٱ گوئارسن هنی کلٛ بیٱ سی تیرنشوݩ ٱنجوماناماٛیی کاْ \"$1\" ڤاش سٱبت نوم کردٱ.\nخاهش مؽکم هنی رۉئؽت ڤامؽن ۉ اۊساْ باٛیرؽتش.",
        "blocked-mailpassword": "نئها آی پی شوما سی ڤیرایئشت کاری گئرئتە بییە، هأنی صئلا یە نە نارە کئ د رازینە گوڤاردئن د نۊ کئل بییە سی نئهاگئری د گأن کاری نارە.",
        "eauthentsent": "یاٛ ٱنجومانامٱ پوشت دۏرس کردنی د یاٛ تیرنشوݩ ڤیژٱ کلٛ بیٱ.\nدما یٱ کاْ یاٛ ٱنجومانامٱ هنی د هساو کلٛ بۊئٱ، شما بایٱد دما رٱدؽارکونی ناْ د ٱنجومانامٱ باٛیرؽت، سی یٱ کاْ هساو شما راسٱکی پوشت دۏرش بۊئٱ.",
        "throttled-mailpassword": "یاٛ رازینٱ گوئارسن د نۊ زنٱ بیٱ ۉ ایساْ کلٛ بیٱ، د آخری {{PLURAL:$1|ساعٱت|$1 ساعٱتؽا}}.\nسی نهاگیری د ٱزیٱت بیئن، فقٱت یاٛ رازینٱ گوئارسن د ٱنجومانامٱ د نۊ زنٱ بیٱ د هٱر {{PLURAL:$1|ساعٱت|$1 ساعٱتؽا}} کلٛ بیٱ.",
        "expansion-depth-exceeded-category-desc": "زؽر دٱسٱ سی بٱلگٱیایؽ کاْ د ڤنو پی یا ڤلٱ بیئن فرٱ پیشکرد کردٱ.",
        "expansion-depth-exceeded-warning": "بٱلگٱ د پی یا ڤلٱ بیئن پیشکرد کرد",
        "parser-unstrip-loop-warning": "گردۊلٱ د فرمونٱ Unstrip پاٛدا بیٱ",
-       "unstrip-depth-warning": "د Ø¨Ø½Ø´ØªØ±Ù\88Ù\86Ù± Ø¯ Ø³Ø±Ú\86Ø´Ù\85Ù± Ø±Ù±ØªÙ\86 Ø¯ Ø¯Ù±Ø³Ø¯Û\8aر Unstrip Ú¤Ø§Ø±Û\89تر رٱتؽتٱ($1)",
+       "unstrip-depth-warning": "د Ø¨Ø½Ø´ØªØ±Ù\88Ù\86Ù± Ø¯ Ø³Ø±Ú\86Ø´Ù\85Ù± Ø±Ù±ØªÙ\86 Ø¯ Ø¯Ù±Ø³Ø¯Û\8aر Unstrip Ú¤Ø§Ø±Û\8fتر رٱتؽتٱ($1)",
        "converter-manual-rule-error": "خٱتا د قانۊن ڤالٛرشتن دٱسی زڤوݩ",
        "undo-success": "نمۊئٱ ڤیرایش ناْ ٱنجومشیو بٱکؽت.\nلوتفٱن اؽ فٱرخؽ کاْ ها د هار ناْ ڤارسی بٱکؽت تا یاٛ کارؽ کاْ مؽهایت ٱنجوم باٛیؽت،ۉ اۊساْ آلشتؽا هار ناْآمادٱ بٱکؽت سی یٱ کاْ خونسا کردن ڤیرایش ناْ ٱنجوم باٛیؽت.",
        "undo-failure": "سی ری ڤ ری بیئن اؽ ڤیرایش ڤا ڤیرایشؽا مؽنجایی، نمۊئٱ اؽ ڤیرایش ناْ خونسا بٱکؽت.",
        "cantcreateaccount-range-text": "حساو دروس بیه وا تیرنشون آی پی که د پوشینه <strong>$1</strong> ، که وه ئم مینونه دار تیرنشون آی پی شما ئم هئ(<strong>$4</strong>)، وه دس [[کاریار:$3|$3]]قلف بیه.\n\nدلیل دئه بیه وا $3، \"$2\" ئه.",
        "viewpagelogs": "ساٛلٛ پهرستنومٱیا اؽ بٱلگٱ بٱکؽت",
        "nohistory": "هیژ ڤیرگار ڤیرایشتی د اؽ بٱلگٱ نؽ.",
-       "currentrev": "آخرÛ\8c Ø¯Ù\88ئارٱ Ø¯Û\8cئÙ\86",
+       "currentrev": "آخری دوئرٱ دیئن",
        "currentrev-asof": "آخری ڤانری چی $1",
        "revisionasof": "دوئرٱ دیئن $1",
        "revision-info": "دوئارٱ ساٛلٛ بیٱ چی $1 ڤا $2",
        "revdelete-radio-same": "آلشت نٱکؽت",
        "revdelete-radio-set": "قایم بیٱ",
        "revdelete-radio-unset": "دیئنی",
-       "revdelete-suppress": "پاکساگری کردن رسینه یا سی دیوونداریا و کسونا تر",
-       "revdelete-unsuppress": "محدودیتیانه د وانیریا امباربیه جا وه جا بکید",
-       "revdelete-log": "دألیل:",
-       "revdelete-submit": "سی {{PLURAL:$1|وانیری|وانیریا}} انتخاو بیه وه کار بوریتو",
+       "revdelete-suppress": "پاکساگری کردن رٱسینٱیا سی دیڤوندارؽا ۉ کٱسونؽا تر",
+       "revdelete-unsuppress": "مٱئدۊدؽٱتؽا ناْ د ڤانیریا ٱمبار بیٱ جا ڤ جا بٱکؽت",
+       "revdelete-log": "دلٛیلٛ:",
+       "revdelete-submit": "سی {{PLURAL:$1|ڤانیری|ڤانیرؽا}} اْنتخاب بیٱ ڤ کار بۉرؽتو",
        "revdelete-success": "'''دیئن وانیری وه خوئی وه هنگوم بی.'''",
-       "revdelete-failure": "'''دیئن وانیری وه خوئی وه هنگوم نبی:'''$1",
+       "revdelete-failure": "'''دیئن ڤانیری ڤ خۊیی ڤ هٱنگوم نبی:'''$1",
        "logdelete-success": "پهرستنومه دیار بیین د خوئی میزونکاری بی.",
-       "logdelete-failure": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù\87 Ø¯Û\8cار Ø¨Û\8cÛ\8cÙ\86 Ù\86بÙ\88ئÙ\87 میزونکاری با. $1",
-       "revdel-restore": "آلشت حال و بال ديئن",
-       "pagehist": "ڤیرگار بألگە",
-       "deletedhist": "ڤیرگار پاکسا بییە",
-       "revdelete-hide-current": "خطا Ø¯ Ù\82اÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8c Ú©Ù\87 Ù\87ا Ø¯ Ù\88Û\8cرگار $2 Ø³Ø§Ø¹Øª $1: Ø§Û\8c Ù\86سÙ\82Ù\87Ø\8c Ù\86سÙ\82Ù\87 Ø§Û\8cسÙ\86Û\8c Û\8cÙ\87 Ù\88 Ù\86بÙ\88ئÙ\87 Ù\86Ù\87Ù\88Ø´ Ø¨Ú©Û\8cت.",
-       "revdelete-show-no-access": "خطا Ø¯ Ù\82اÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8cÛ\8c Ú©Ù\87 Ù\87ا Ø¯ Ù\88Û\8cرگار $2 Ø³Ø§Ø¹Øª $1: Ø§Û\8c Ù\86سÙ\82Ù\87 Ù\86Ø´Ù\88Ù\86 Â«Ù\85ئÙ\86 ØªÙ\86Ú¯Ù\84ا Ø¨Û\8cئÙ\86» Ø¯Ø§Ø±Ù\87 Ù\88 Ø´Ù\85ا Ù\86Ù\85Û\8c ØªÙ\88Ù\86Û\8cت Ù\88Ù\87 Ø´ Ø¯Ø³Ø±Ø³Û\8c Ø¯Ø§Ø´ØªÙ\88Û\8cت.",
-       "revdelete-modify-no-access": "خطا Ø¯ Ù\82اÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8cÛ\8c Ú©Ù\87 Ù\87ا Ø¯ Ù\88Û\8cرگار $2 Ø³Ø§Ø¹Øª $1: Ø§Û\8c Ù\86سÙ\82Ù\87 Ù\86Ø´Ù\88Ù\86 Â«Ù\85ئÙ\86 ØªÙ\86Ú¯Ù\84ا Ø¨Û\8cئÙ\86» Ø¯Ø§Ø±Ù\87 Ù\88 Ø´Ù\85ا Ù\86Ù\85Û\8c ØªÙ\88Ù\86Û\8cت Ù\88Ù\87 Ø´ Ø¯Ø³Ø±Ø³Û\8c Ø¯Ø§Ø´ØªÙ\88Û\8cت.",
-       "revdelete-modify-missing": "خطا Ø¯ Ù\82اÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8c Ø´Ù\85ارÙ\87Ù\94 $1: Ø§Û\8c Ù\86سÙ\82Ù\87 Ø¯ Ø±Ø³Û\8cÙ\86Ù\87 Ú¯Ø§ Ù\86Û\8cئش!",
-       "revdelete-no-change": "'''زئنار:''' چی که ها د ویرگا $2 ساعت $1 د دماتر دیاری میزونکاری حاسته بینه داشته.",
-       "revdelete-concurrent-change": "خطا Ø¯ Ù\82اÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8cÛ\8c Ú©Ù\87 Ù\87ا Ø¯ Ù\88Û\8cرگار $2 Ø³Ø§Ø¹Øª $1: Ù\88Ù\87 Ù\88Û\8cر Ù\88 Ø¨Ø§Ù\88ر Ù\85Û\8cا Ú©Ù\87 Ø¯ Ø§Ù\88 Ú¯Ø§ØªÛ\8c Ú©Ù\87 Ø´Ù\85ا Ø³Û\8c Ø¢Ù\84شت Ø¯Ø¦Ù\86 Ø­Ø§Ù\84 Ù\88 Ø¨Ø§Ø± Ù\88Ù\87 Ø³Ø¹Û\8c Ù\85Û\8c Ú©Ø±Ø¯Û\8cتÙ\87Ø\8c Ø­Ø§Ù\84 Ù\88 Ø¨Ø§Ø±Ø´ Ù\88Ù\87 Ø¯Ø³ Ú©Ø³Û\8c ØªØ± Ø¢Ù\84شت Ø¯Ø¦Ù\87 Ø¨Û\8cÙ\87.\nÙ\84Ø·Ù\81Ù\86 Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù\87 Û\8cا Ù\86Ù\87 Ù\88ارسÛ\8c Ø¨Ú©Û\8cت.",
-       "revdelete-only-restricted": "خطا Ø¯ Ù\82اÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8cÛ\8c Ú©Ù\87 Ù\87ا Ø¯ Ù\88Û\8cرگار $2 Ø³Ø§Ø¹Øª $1: Ø´Ù\85ا Ù\86Û\8cÙ\85Û\8c ØªÙ\88Ù\86Û\8cت Ú\86Û\8cاÙ\86Ù\87 Ø¯ Ù\88رتÛ\8cÙ\87 Ø¯Û\8cÙ\88Ù\88Ù\86دارÛ\8cا Ù\82اÙ\85 Ø¨Ú©Û\8cتÙ\88 Ù\85ر Û\8cÙ\87 Ú©Ù\87 Û\8cÙ\87 Ú¯Ù\84 Ø¯ Ú¯Ø²Û\8cÙ\86Ù\87 Û\8cا Ø¯Û\8cارÛ\8c Ú©Ø±Ø¯Ù\86 Ù\87Ù\86Û\8c Ù\86Ù\87 Ø§Ù\86تخاÙ\88 Ø¨کیت.",
-       "revdelete-reason-dropdown": "*دلیلیا جاونه سی پاکسا کردن\n** تیه پوشی د حق درتیچ کردن\n** ویر و باور یا دونسمنیا شخصی نامناسو\n** نوم کاریاری نامناسو\n** دونسمنیا فره تنادار",
-       "revdelete-otherreason": "دألیل ھأنی:",
-       "revdelete-reasonotherlist": "دألیل ھأنی",
-       "revdelete-edit-reasonlist": "دلیلیا پاکسا کردنه نه ویرایشت بکید",
-       "revdelete-offender": "Ù\86Û\8cسÙ\86Ù\87 Ù\88انیری:",
-       "suppressionlog": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù\87 پاکساگری",
-       "suppressionlogtext": "د هار یه گل نوم گه ای هئ که مینونه یا پاکسا بیه و قلف بیه  که هان دش د ورتیه دیوونداریا قام بینه.\n[[ویجه:نوم گه قلف بیه|نوم گه قلف بیئنیا]]نه سی نوم گه ایی که انجومکاریا قدقن بیه و قلف بینیا هان دش بونیت.",
-       "mergehistory": "ویرگاریا بلگه نه یکی بکید",
+       "logdelete-failure": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù± Ø¯Ø½Ø§Ø± Ø¨Û\8cئÙ\86 Ù\86Ù\85Û\8aئٱ میزونکاری با. $1",
+       "revdel-restore": "آلشت هال ۉ بال ديئن",
+       "pagehist": "ڤیرگار بٱلگٱ",
+       "deletedhist": "ڤیرگار پاکسا بیٱ",
+       "revdelete-hide-current": "ختا Ø¯ Ù\82اÛ\8cÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8c Û\8cؽ Ú©Ø§Ù\92 Ù\87ا Ø¯ Ú¤Û\8cرگار $2 Ø³Ø§Ø¹Ù±Øª $1: Ø§Ø½ Ù\86Û\8fسخٱØ\8c Ù\86Û\8fسخٱ Ø§Û\8cسÙ\86Û\8c Ø¦Ù± Û\89 Ù\86Ù\85Û\8aئٱ Ù\82اÛ\8cÙ\85Ø´ Ø¨Ù±Ú©Ø½ت.",
+       "revdelete-show-no-access": "ختا Ø¯ Ù\82اÛ\8cÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8c Û\8cؽ Ú©Ø§Ù\92 Ù\87ا Ø¯ Ú¤Û\8cرگار $2 Ø³Ø§Ø¹Ù±Øª $1: Ø§Ø½ Ù\86Û\8fسخٱ Ù\86Ø´Ù\88Ý© Â«Ù\85ؽÙ\86 ØªÙ±Ù\86Ú³Ù\84اتÛ\8c Ø¨Û\8cئÙ\86» Ø¯Ø§Ø±Ù± Û\89 Ø´Ù\85ا Ù\86Ù\85ؽ ØªÙ\88Ù\86ؽت  Ú¤Ø´ Ø¯Ù±Ø³Ø±Ø³Û\8c Ø¯Ø§Ø´ØªÛ\8aئؽت.",
+       "revdelete-modify-no-access": "ختا Ø¯ Ù\82اشÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8c Û\8cؽ Ú©Ø§Ù\92 Ù\87ا Ø¯ Ú¤Û\8cرگار $2 Ø³Ø§Ø¹Ù±Øª $1: Ø§Ø½ Ù\86Û\8fسخٱ Ù\86Ø´Ù\88Ý© Â«Ù\85ؽÙ\86 ØªÙ±Ù\86Ú³Ù\84اتÛ\8c Ø¨Û\8cئÙ\86» Ø¯Ø§Ø±Ù± Û\89 Ø´Ù\85ا Ù\86Ù\85ؽ ØªÙ\88Ù\86ؽت Ú¤Ø´ Ø¯Ù±Ø³Ø±Ø³Û\8c Ø¯Ø§Ø´ØªÛ\8aئؽت.",
+       "revdelete-modify-missing": "ختا Ø¯ Ù\82اÛ\8cÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8c Ø´Ù\85ارٱ $1: Ø§Ø½ Ù\86Û\8fسخٱ Ø¯ Ø±Ù±Ø³Û\8cÙ\86Ù±Ú¯Ù± Ù\86ؽسش!",
+       "revdelete-no-change": "'''زٱنڳؽار:''' چی یؽ کاْ ها د ڤیرگار $2 ساعٱت $1 د دماتر دؽاری میزونکاری هاستٱ بینٱ داشتٱ.",
+       "revdelete-concurrent-change": "ختا Ø¯ Ù\82اÛ\8cÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8c Û\8cؽ Ú©Ø§Ù\92 Ù\87ا Ø¯ Ú¤Û\8cرگار $2 Ø³Ø§Ø¹Ù±Øª $1: Ú¤ Ú¤Û\8cر Û\89 Ø¨Ø§Ú¤Ù±Ø± Ù\85ؽا Ú©Ø§Ù\92 Ø¯ Ø§Ù\88 Ú¯Ø§ØªØ½ Ú©Ø§Ù\92 Ø´Ù\85ا Ø³Û\8c Ø¢Ù\84شت Ø¯Ø§Ù\9bئÙ\86 Ù\87اÙ\84 Û\89 Ø¨Ø§Ø± Ú¤Ù± ØªÙ±Ù\81رٱ Ù\85ؽ Ú©Ø±Ø¯Ø½ØªÙ±Ø\8c Ù\87اÙ\84 Û\89 Ø¨Ø§Ø±Ø´ Ú¤ Ø¯Ù±Ø³ Ú©Ù±Ø³Ø½ ØªØ± Ø¢Ù\84شت Ø¯Ø§Ù\9bئٱ Ø¨Û\8cÙ±.\nÙ\84Ù\88تÙ\81Ù±Ù\86 Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù±Û\8cا Ù\86اÙ\92 Ú¤Ø§Ø±Ø³Û\8c Ø¨Ù±Ú©Ø½ت.",
+       "revdelete-only-restricted": "ختا Ø¯ Ù\82اÛ\8cÙ\85 Ú©Ø±Ø¯Ù\86 Ú\86Û\8c Û\8cؽ Ú©Ø§Ù\92 Ù\87ا Ø¯ Ú¤Û\8cرگار $2 Ø³Ø§Ø¹Ù±Øª $1: Ø´Ù\85ا Ù\86Ù\85ؽ ØªÙ\88Ù\86ؽت Ú\86Û\8cا Ù\86اÙ\92 Ø¯ Ú¤Ù±Ø± ØªÛ\8cÙ± Ø¯Û\8cÚ¤Ù\88Ù\86دارÛ\8cا Ù\82اÛ\8cÙ\85 Ø¨Ù±Ú©Ø½ØªÙ\88 Ù\85ٱر Û\8cÙ± Ú©Ø§Ù\92 Û\8cٱکؽ Ø¯ Ú¯Ù\88زÛ\8cÙ\86Ù±Û\8cا Ø¯Ø½Ø§Ø±Û\8c Ú©Ø±Ø¯Ù\86 Ù\87Ù\86Û\8c Ù\86اÙ\92 Ø§Ù\92Ù\86تخاب Ø¨Ù±کیت.",
+       "revdelete-reason-dropdown": "*دلٛیلٛؽا جاڤٱنٱ سی پاکسا کردن\n** تیٱ پۊشی د هٱق درتیچ کردن\n** ڤیر ۉ باڤٱرؽا دونسمٱنیا شٱخسی ناموناسب\n** نوم کاریاری ناموناسب\n** دونسمٱنیا فرٱ اْفترا آمیز",
+       "revdelete-otherreason": "دلٛیلٛ ھنی:",
+       "revdelete-reasonotherlist": "دلٛیلٛ ھنی",
+       "revdelete-edit-reasonlist": "دلٛیلٛؽا پاکسا کردن ناْ ڤیرایش بٱکؽت",
+       "revdelete-offender": "Ù\86Û\8cسٱÙ\86Ù± Ú¤انیری:",
+       "suppressionlog": "Ù¾Ù\87رستÙ\86Ù\88Ù\85Ù± پاکساگری",
+       "suppressionlogtext": "د هار یاٛ نومگٱیؽ هؽ کاْ مؽنونٱیا پاکسا بیٱ ۉ قلف بیٱ کاْ هان دش د ڤٱر تیٱ دیڤوندارؽا قایم بینٱ.\n[[ڤیژٱ:نومگٱ قلف بیٱ|نومگٱ قلف بیئنؽا]] ناْ سی نومگاٛیؽ کاْ ٱنجومکارؽا قٱدقٱن بیٱ ۉ قلف بیئنؽا هان دش بونؽت.",
+       "mergehistory": "ڤیرگارؽا بٱلگٱ ناْ یٱکؽ بٱکؽت",
        "mergehistory-header": "ای بلگه وه شما اجازه می ئه که وانیریانه ویرگار سرچشمه بلگه نه د یه گل بلگه تازه سریک سازی بکید.\nمطمئن بویت که ای آلشت د لحاظ ویرگاری د مین بلگه موندگاره.",
-       "mergehistory-box": "دوواره دیئن دوبلگه ای نه سر یک سازی کو:",
-       "mergehistory-from": "بألگە سأرچئشمە:",
-       "mergehistory-into": "بÙ\84Ú¯Ù\87 Ù\85Ù\82صد:",
-       "mergehistory-list": "ویرگار ویرایشت سر یک سازی بیئنی",
-       "mergehistory-merge": "نسقه یا هاری که د [[:$1]] وه یک شیوسنی وا[[:$2]] هئن.\nستین دگمه یا رادیویی نه به کار به ونیت سی یه که نسقه یایی نه که د گاتی دماتر دروس بینه انتخاو بکیت.\nد ویرتو با که پورسن ری پیوندیا باعث بوئه که ستین وه شکل اولیه خوش ؤرئرده.",
-       "mergehistory-go": "ویرایشتیایی که سریک سازی بوئن نشو بیئه",
-       "mergehistory-submit": "سر یک سازی دوواره دیئنیا",
-       "mergehistory-empty": "هیپ دوواره دیئنی نبوئه یکی سازی بوئه.",
+       "mergehistory-box": "دوئارٱ دیئن دۏ بٱلگٱ ناْ سٱریٱک سازی کو:",
+       "mergehistory-from": "بٱلگٱ سرچشمٱ:",
+       "mergehistory-into": "بٱÙ\84Ú¯Ù± Ù\85Ù±Ù\82سٱد:",
+       "mergehistory-list": "ڤیرگار ڤیرایش سٱریٱک سازی بیئنی",
+       "mergehistory-merge": "نۏسخٱیا هاری کاْ د [[:$1]] ڤٱ یاٛ شؽڤسنی ڤا[[:$2]] هؽسن.\nستین دۏگمٱیا رادیویی ناْ ڤ کار بڤٱنؽت سی یٱ کاْ نۏسخٱیایؽ ناْ کاْ د گاتؽ دماتر دۏرس بینٱ اْنتخاب بٱکؽت.\nد ڤیرتو با کاْ پۊرسن ری پاٛڤٱنؽا باعس مۊئٱ کاْ ستین ڤٱ شکل ٱڤلٛیٱ خوش ناْ ڤرارٱ.",
+       "mergehistory-go": "ڤیرایشؽایؽ کاْ سٱریٱک سازی مۊئٱن نشوݩ باٛ",
+       "mergehistory-submit": "سٱریٱک سازی دوئرٱ دیئنؽا",
+       "mergehistory-empty": "هیژ دوئرٱ دیئنی نمۊئٱ یٱکؽ سازی بۊئٱ.",
        "mergehistory-done": "$3 {{PLURAL:$3|وانیری|وانیریا}} د $1 وه خوئی د [[:$2]] سریک سازی بی.",
-       "mergehistory-fail": "سریک سازی ویرگار انجوم نبوئه، لطفن پینیاریا گات و بلگه نه د نو وارسی بکید.",
-       "mergehistory-fail-toobig": "نبوئه وه یک شیوسن ویرگا انجوم دئه سی یکه وه بیشتر د محدودیت $1 {{PLURAL:$1|نسقه}}جا وه جا موئه.",
-       "mergehistory-no-source": "سرÚ\86Ø´Ù\85Ù\87 Ø¨Ù\84Ú¯Ù\87 $1 Ù\88جÙ\88د Ù\86ارÙ\87.",
-       "mergehistory-no-destination": "بÙ\84Ú¯Ù\87 Ù\85Ù\82صد $1 Ù\88جÙ\88د Ù\86ارÙ\87.",
-       "mergehistory-invalid-source": "نوم ون بلگه سرچشمه با معتور بوئه.",
-       "mergehistory-invalid-destination": "نوم ون بلگه سرچشمه با معتور بوئه.",
-       "mergehistory-autocomment": " [[:$1]]وا[[:$2]] یکی بیه",
-       "mergehistory-comment": " [[:$1]]وا[[:$2]] یکی بیه:$3",
-       "mergehistory-same-destination": "سرÚ\86Ø´Ù\85Ù\87 Ù\88 Ø¨Ù\84Ú¯Ù\87 Û\8cا Ù\85Ù\82صد Ù\86بÙ\88ئÙ\87 Û\8cÚ©Û\8c Ø¨Ù\88ئن",
-       "mergehistory-reason": "دأليل:",
+       "mergehistory-fail": "سٱریٱک سازی ڤیرگار ٱنجوم نمۊئٱ، لوتفٱن پین یارؽا گات ۉ بٱلگٱ ناْ د نۊ ڤارسی بٱکؽت.",
+       "mergehistory-fail-toobig": "نمۊئٱ ڤ یٱک شؽڤسن ڤیرگا ٱنجوم داٛئٱ سی یٱ کاْ ڤۉ بؽشتر د مٱئدۊدیٱت $1 {{PLURAL:$1|نۏسخٱ}}جا ڤ جا مۊئٱ.",
+       "mergehistory-no-source": "سرÚ\86Ø´Ù\85Ù± Ø¨Ù±Ù\84Ú¯Ù± $1 Ú¤Ø¬Û\8aد Ù\86ارٱ.",
+       "mergehistory-no-destination": "بٱÙ\84Ú¯Ù± Ù\85Ù±Ù\82سٱد $1 Ú¤Ø¬Û\8aد Ù\86ارٱ.",
+       "mergehistory-invalid-source": "نوم ڤٱن بٱلگٱ سرچشمٱ بایٱد موعتٱبٱر بۊئٱ.",
+       "mergehistory-invalid-destination": "نوم ڤٱن بٱلگٱ سرچشمٱ بایٱد موعتٱبٱر بۊئٱ.",
+       "mergehistory-autocomment": " [[:$1]]ڤا[[:$2]] یٱکؽ بیٱ",
+       "mergehistory-comment": " [[:$1]]ڤا[[:$2]] یٱکؽ بیٱ:$3",
+       "mergehistory-same-destination": "سرÚ\86Ø´Ù\85Ù± Û\89 Ø¨Ù±Ù\84Ú¯Ù±Û\8cا Ù\85Ù±Ù\82سٱد Ù\86Ù\85Û\8aئٱ Û\8cٱکؽ Ø¨Û\8aئٱن",
+       "mergehistory-reason": "دلٛیلٛ:",
        "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
        "mergelog": "سٱریٱک سازی پهرستنومٱ",
-       "revertmerge": "بی لوئه",
-       "mergelogpagetext": "شما د هار نوم گه آخرین چیا وه یک شیوسن ویرگار یه بلگه نه د بلگه تر میئنیت.",
-       "history-title": "دÙ\88ئارٱ Ø¯Û\8cئÙ\86 Ú¤Û\8cرگار $1",
+       "revertmerge": "بؽ لوئٱ",
+       "mergelogpagetext": "شما د هار نومگٱ آخری چیا ڤ یٱک شؽڤسن ڤیرگار یاٛ بٱلگٱ ناْ د بٱلگاٛ تر ماٛینؽت.",
+       "history-title": "دوئرٱ دیئن ڤیرگار $1",
        "difference-title": "فٱرخ مؽنجا ڤانیرؽا \"$1\"",
-       "difference-title-multipage": "فرخ مینجا بلگه یا \"$1\" و \"$2\"",
-       "difference-multipage": "(فرخ مینجا بلگه یا)",
+       "difference-title-multipage": "فٱرخ مؽنجا بٱلگٱیا \"$1\" و \"$2\"",
+       "difference-multipage": "(فٱرخ مؽنجا بٱلگٱیا)",
        "lineno": "خٱت $1:",
-       "compareselectedversions": "دÙ\88ئارٱ Ø¯Û\8cئÙ\86ؽاÛ\8cؽ Ú©Ø§Ù\92 Ø§Ù\92Ù\86تخاÙ\88 بینٱ ناْ موقایسٱ بٱکؽت",
-       "showhideselectedversions": "شلک دیئن وانیریا انتخاو بیه نه آلشت بکید",
+       "compareselectedversions": "دÙ\88ئرٱ Ø¯Û\8cئÙ\86ؽاÛ\8cؽ Ú©Ø§Ù\92 Ø§Ù\92Ù\86تخاب بینٱ ناْ موقایسٱ بٱکؽت",
+       "showhideselectedversions": "شکل دیئن ڤانیریا اْنتخاب بیٱ ناْ آلشت بٱکؽت",
        "editundo": "ناٱنجومگر کردن",
        "diff-empty": "(بؽ فٱرق)",
        "diff-multi-sameuser": "({{PLURAL:$1|یاٛ نۏسخٱ مؽنجایی|$1 نۏسخٱیا مؽنجایی}} ڤ دٱس{{PLURAL:$2|کاریارؽ تر|$2 کاریارؽا}} نشوݩ داٛئٱ ناٛیٱ)",
        "diff-multi-otherusers": "({{PLURAL:$1|یاٛ نۏسخٱ مؽنجایی|$1 نۏسخٱیا مؽنجایی}} ڤ دٱس{{PLURAL:$2|کاریاری تر|$2 کاریارؽا}} نشوݩ داٛئٱ ناٛیٱ)",
-       "diff-multi-manyusers": "({{PLURAL:$1|یه گل وانیری مینجاگرته|$1وانیریا مینجا گرته}} بیشتر د $2 {{PLURAL:$2|کاریار|کاریاریا}} نشو دئه نبیه)",
-       "difference-missing-revision": "{{PLURAL:$2|یه گل ویرایشت|$2 ویرایشت}} د فرق مینجا($1) {{PLURAL:$2|پیدا نبی|پیدا نبینه}}.\n\nشایت بانی جاونه وه وا یه گل ویرگار وه هنگوم نبیه که د یه گل بلگه پاکسا بیه هوم پیوند بیه بوئه.\nشایت جزئیات د   [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log]  پیدا بوئن.",
+       "diff-multi-manyusers": "({{PLURAL:$1|یاٛ ڤانیری مؽنجاگرتٱ|$1ڤانیریا مؽنجا گرتٱ}} بؽشتر د $2 {{PLURAL:$2|کاریار|کاریارؽا}} نشوݩ داٛئٱ ناٛییٱ)",
+       "difference-missing-revision": "{{PLURAL:$2|یاٛ ڤیرایش|$2 ڤیرایش}} د فٱرخ مؽنجا($1) {{PLURAL:$2|پاٛدا ناٛی|پاٛدا ناٛییٱ}}.\n\nشایٱد بانی جاڤٱنٱ ڤٱ ڤا یاٛ ڤیرگار ڤٱ هٱنگوم ناٛییٱ کاْ د یاٛ بٱلگٱ پاکسا بیٱ هوم پاٛڤٱن باٛئٱ بۊئٱ.\nشایٱد جۏزییات د  [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log]  پاٛدا مۊئٱن.",
        "searchresults": "نتيجٱیا پاٛ جۊری",
-       "searchresults-title": "نتيجٱیا پاٛ جۊری سی \"$1\"",
-       "titlematches": "داسون بلگه یکی بیه",
-       "textmatches": "Ù\87Ù\88Ù\85سازÛ\8c Ù\86Û\8cسسÙ\87 Ø¨Ù\84Ú¯Ù\87.",
-       "notextmatches": "Ù\86Û\8cسسÙ\87 Ø¨Ù\84Ú¯Ù\87 Ù\87Ù\88Ù\85سازÛ\8c Ù\86ارÙ\87",
+       "searchresults-title": "نٱتيجٱیا پاٛ جۊری سی \"$1\"",
+       "titlematches": "داسوݩ بٱلگٱ یٱکؽ بیٱ",
+       "textmatches": "Ù\87Ù\88Ù\85سازÛ\8c Ù\86Û\8cسسٱ Ø¨Ù±Ù\84Ú¯Ù±.",
+       "notextmatches": "Ù\86Û\8cسسٱ Ø¨Ù±Ù\84Ú¯Ù± Ù\87Ù\88Ù\85سازÛ\8c Ù\86ارٱ",
        "prevn": "ڤادما {{PLURAL:$1|$1}}",
        "nextn": "نوئایی {{PLURAL:$1|$1}}",
-       "prev-page": "بÙ\84Ú¯Ù\87 دمايی",
-       "next-page": "بÙ\84Ú¯Ù\87 Ù\86Ù\87ایی",
+       "prev-page": "بٱÙ\84Ú¯Ù± دمايی",
+       "next-page": "بٱÙ\84Ú¯Ù± Ù\86Ù\88ئایی",
        "prevn-title": "زیتر $1 {{PLURAL:$1|نٱتیجٱ|نٱتيجٱيا}}",
        "nextn-title": "دمایی $1 {{PLURAL:$1|نٱتيجٱ|نٱتيجؽا}}",
-       "shown-title": "نشوݩ داٛین $1 {{PLURAL:$1|نتیجٱ|نتیجٱیا}} سی هٱر بٱلگٱ",
+       "shown-title": "نشوݩ داٛئن $1 {{PLURAL:$1|نتیجٱ|نتیجٱیا}} سی هٱر بٱلگٱ",
        "viewprevnext": "ديئن ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''ایچاْ بٱلگاٛیؽ هؽ ڤ نوم\"[[:$1]]\" کاْ ها د اؽ ڤیکی'''",
        "searchmenu-new": "'''اؽ بٱلگٱ ناْ دۏرس كو \"[[:$1]]\" د اؽ ڤیکی!'''",
        "searchprofile-articles": "بٱلگٱيا مؽنونٱ دار",
-       "searchprofile-images": "ڤارسگرؽا خلکمٱن",
-       "searchprofile-everything": "همٱ چی",
+       "searchprofile-images": "ڤارسگرؽا Ø®Ù±Ù\84Ú©Ù\85Ù±Ù\86",
+       "searchprofile-everything": "Ù\87Ù±Ù\85Ù± Ú\86Û\8c",
        "searchprofile-advanced": "پیشکردٱ",
        "searchprofile-articles-tooltip": "بٱگٱرد مؽن $1",
-       "searchprofile-images-tooltip": "جانؽایا ناْ پاٛ جۊری کو",
-       "searchprofile-everything-tooltip": "همٱ مؽنونٱیا ناْ پاٛ جۊری كو (شامل بٱلگٱيا چٱک چنٱ)",
+       "searchprofile-images-tooltip": "جانؽایا ناْ پاٛجۊری کو",
+       "searchprofile-everything-tooltip": "همٱ مؽنونٱیا ناْ پاٛجۊری كو (شامل بٱلگٱيا چٱک چنٱ)",
        "searchprofile-advanced-tooltip": "نوم جايا نوم دؽار بٱگٱرد",
        "search-result-size": "$1 ({{PLURAL:$2|1 کلٱمٱ|$2 کلٱمٱیا}})",
        "search-result-category-size": "{{PLURAL:$1|1 ٱندوم|$1 ٱندومؽا}} ({{PLURAL:$2|1 زؽردٱسٱ|$2 زؽردٱسٱیا}}، {{PLURAL:$3|1 جانؽا|$3 جانؽایا}}",
        "search-redirect": "(ڤرگٱشتن سی $1)",
        "search-section": "(بٱئرجا $1)",
-       "search-category": "(دسه $1)",
+       "search-category": "(دٱسٱ $1)",
        "search-file-match": "(یٱکؽ کردن مؽنونٱ جانؽا)",
        "search-suggest": "مٱنزۊرت يٱ بی:$1",
-       "search-rewritten": "Ù\86ئشÙ\88Ù\99 Ø¯Ø£Ø¦Ù\86 Ù\86أتÛ\8cجÛ\95 Û\8cا Ø³Û\8c $1. Ø³Û\8c Ù\86ئÙ\85Ù\88Ù\99Ù\86Û\95 Ø¨Ø£Ú¯Ø£Ø±Ø¯Û\8cت سی $2.",
+       "search-rewritten": "Ù\86Ø´Ù\88Ý© Ø¯Ø§Ù\9bئÙ\86 Ù\86ٱتÛ\8cجٱÛ\8cا Ø³Û\8c $1. Ø³Û\8c Ù\86Ù\85Û\8aÙ\86Ù± Ø¨Ù±Ú¯Ù±Ø±Ø¯Ø½ت سی $2.",
        "search-interwiki-caption": "پروجه یا خوئر",
-       "search-interwiki-default": "$1 نتیجه یا:",
-       "search-interwiki-more": "(بیشتر)",
-       "search-relatedarticle": "مرتوط",
-       "searchrelated": "مرتوط",
-       "searchall": "همٱ",
+       "search-interwiki-default": "$1 نٱتیجٱیا:",
+       "search-interwiki-more": "(بؽشتر)",
+       "search-relatedarticle": "مورتٱبت",
+       "searchrelated": "مورتٱبت",
+       "searchall": "Ù\87Ù±Ù\85Ù±",
        "showingresults": "نمایش بؽشترونٱ {{PLURAL:$1|'''۱''' نتیجٱ|'''$1''' نتیجٱ}} د هار، شرۊ د شمارٱ'''$2'''.",
-       "showingresultsinrange": "نمایش بؽشترونٱ {{PLURAL:$1|'''۱''' نتیجٱ|'''$1''' نتیجٱ}} د هار، شرۊ د شمارٱ'''$2''' تا شمارٱ '''$3'''.",
+       "showingresultsinrange": "نمایش بؽشترونٱ {{PLURAL:$1|'''۱''' نٱتیجٱ|'''$1''' نٱتیجٱ}} د هار، شرۊ د شمارٱ'''$2''' تا شمارٱ '''$3'''.",
        "search-showingresults": "{{PLURAL:$4|نٱتیجٱیا<strong>$1</strong> د <strong>$3</strong>|نٱتیجٱیا<strong>$1 - $2</strong د <strong>$3</strong>}}",
-       "search-nonefound": "هیچ نتیجاٛیؽ ڤا پاٛجۊری تو یٱکؽ نؽ.",
-       "powersearch-legend": "پی جوری پیشکرده",
-       "powersearch-ns": "د نوم جايا نوم ديار پی جوری بک:",
-       "powersearch-togglelabel": "ڤارئسÛ\8c Ú©Ø¦Ø±Ø¯Ø¦ن:",
-       "powersearch-toggleall": "هأمە",
-       "powersearch-togglenone": "هيش كوم",
-       "powersearch-remember": "د ویر داشتن انتخاو سی پی جوریا نهایی",
-       "search-external": "پی جوری د در",
-       "searchdisabled": "Ù\85ئÙ\86 Ø¬Ù\88رÛ\8c Ø¯ {{SITENAME}} Ú©Ù\86شتگر Ù\86ئ.\nÙ\85Ù\88Ù\82تاÙ\8b Ù\85Û\8c ØªÙ\88Ù\86Û\8cت Ù\85ئÙ\86 Ø¬Ù\88رÛ\8c Google Ù\86Ù\87 Ø¨Ù\88Ù\86Û\8cت Ù\88Ù\87 Ú©Ø§Ø±.\nد Ù\88Û\8cرتÙ\88 Ø¨Ø§ Ú©Ù\87 Ù\86تÛ\8cجÙ\87 Û\8cاÛ\8cÛ\8c Ú©Ù\87 Ø¯ Ù\85ئÙ\86 Ø¬Ù\88رÛ\8c Ù\88ا Ø§Ù\88 Ø±Ù\88شت Ù\88Ù\87 Ø¯Ø³Øª Ù\85Û\8cاÙ\86 Ø´Ø§Û\8cت Ù\88Ù\87 Ø±Ù\88ز Ù\86بان.",
-       "search-error": "یه گل خطا سی اوسنی که پی جوری می کردیت اتفاق افتائه:$1",
-       "preferences": "Ø®Ù\88صÙ\88Ù\99Û\8cات Ù\87Ø£نی",
+       "search-nonefound": "هیچ نٱتیجاٛیؽ ڤا پاٛجۊری تو یٱکؽ نؽ.",
+       "powersearch-legend": "پاٛجۊری پیشکردٱ",
+       "powersearch-ns": "د نوم جايا نوم دؽار پاٛجۊری کو:",
+       "powersearch-togglelabel": "ڤارسÛ\8c Ú©Ø±Ø¯ن:",
+       "powersearch-toggleall": "هٱمٱ",
+       "powersearch-togglenone": "هیچ کوم",
+       "powersearch-remember": "د ڤیر داشتن اْنتخاب سی پاٛجۊرؽا نهایی",
+       "search-external": "پاٛجۊری د دٱر",
+       "searchdisabled": "Ù\85ؽÙ\86 Ø¬Û\8aرÛ\8c Ø¯ {{SITENAME}} Ú©Ù\86شگٱر Ù\86ؽ.\nÙ\85Ù\88Ú¤Ù±Ù\82ٱتٱÙ\86 Ù\85ؽتÙ\88Ù\86ؽت Ù\85ؽÙ\86 Ø¬Û\8aرÛ\8c Google Ù\86اÙ\92 Ø¨Ù\88Ù\86ؽت Ú¤ Ú©Ø§Ø±.\nد Ú¤Û\8cرتÙ\88 Ø¨Ø§ Ú©Ø§Ù\92 Ù\86ٱتÛ\8cجٱÛ\8cاÛ\8cؽ Ú©Ø§Ù\92 Ø¯ Ù\85ؽÙ\86 Ø¬Ù\88Ù¾Û\8aرÛ\8c Ú¤Ø§ Ø§Ù\88 Ø±Ù±Ú¤Ø´ Ú¤ Ø¯Ù±Ø³ Ù\85ؽاÙ\86 Ø´Ø§Û\8cٱد Ú¤ Ø±Û\8aز Ù\86Û\8aئٱن.",
+       "search-error": "یاٛ خٱتا سی اۊسنؽ کاْ پاٛجۊری مؽ کردؽت اْتفاق اوفتایٱ:$1",
+       "preferences": "Ø®Ù\88سÛ\8aسÛ\8cات Ù\87نی",
        "mypreferences": "چیا هنی",
-       "prefs-edits": "Ø´Ù\88Ù\85ارÛ\95 Ú¤Û\8cراÛ\8cئشتÛ\8cا:",
-       "prefsnologintext2": "لطف بکیت بیایت وامین و ترجیحات خوتونه آلشت بئیت.",
-       "prefs-skin": "پوس",
-       "skin-preview": "Ù¾Û\8cØ´ Ø³Ø¦Û\8cÙ\84",
-       "datedefault": "هیچ ترجیحات دش نئ",
-       "prefs-labs": "گزینشتیا ازماشتی",
-       "prefs-user-pages": "بألگە کاریار",
-       "prefs-personal": "جانیاگە کاریار",
-       "prefs-rc": "Ø¢Ù\84ئشتÛ\8cا Ø¦Û\8cسئنی",
-       "prefs-watchlist": "سئÛ\8cÙ\84 Ø¨Ø£رگ",
-       "prefs-editwatchlist": "Ú¤Û\8cراÛ\8cئشت Ø³Ø¦Û\8cÙ\84 Ø¨Ø£رگ",
-       "prefs-editwatchlist-label": "دادÙ\87 Û\8cا Ù\86Ù\87 Ø¯ Ø³Û\8cÙ\84 Ø¨Ø±Ú¯ Ø®Ù\88تÙ\88 Ù\88Û\8cراÛ\8cشت Ø¨Ú©Û\8cت:",
-       "prefs-editwatchlist-edit": "داسÙ\88Ù\86اÙ\86Ù\87 Ø³Û\8cÙ\84 Ø¨Ú©Û\8cت Ù\88 Ù\88Ù\86Ù\88Ù\86Ù\87 Ø¯ Ø³Û\8cÙ\84 Ø¨Ø±Ú¯ Ø®Ù\88تÙ\88 Ù\88ردارÛ\8cت",
-       "prefs-editwatchlist-raw": "Ú¤Û\8cراÛ\8cئشتکارÛ\8c Ø±Ø£Ø¯Û\8cÙ\81Û\8c Ø³Ø¦Û\8cÙ\84 Ø¨Ø£رگ",
-       "prefs-editwatchlist-clear": "سئÛ\8cÙ\84 Ø¨Ø£Ø±Ú¯Ø¦ ØªÙ\88Ù\99Ù\86Û\95 Ù¾Ø§Ú© Ø¨Ø£Ú©Û\8cت",
-       "prefs-watchlist-days": "روزیا نه د سیل برگ نشو دئه بو:",
-       "prefs-watchlist-days-max": "$1 بیشترونه {{PLURAL:$1|روز|روزیا}}",
+       "prefs-edits": "Ø´Ù\85ارٱ Ú¤Û\8cراÛ\8cشؽا:",
+       "prefsnologintext2": "لوتف بٱکؽت بؽایؽت ڤامؽن ۉ تٱرجیهؽا خوتو ناْ آلشت بٱکؽت.",
+       "prefs-skin": "پۊس",
+       "skin-preview": "Ù¾Û\8cØ´ Ø³Ø§Ù\9bÙ\84Ù\9b",
+       "datedefault": "هیچ تٱرجیهاتؽ دش نؽ",
+       "prefs-labs": "گوزینشؽا آزمایشی",
+       "prefs-user-pages": "بٱلگٱ کاریار",
+       "prefs-personal": "جانؽاگٱ کاریار",
+       "prefs-rc": "Ø¢Ù\84شتؽا Ø§Û\8cسنی",
+       "prefs-watchlist": "ساÙ\9bÙ\84Ù\9b Ø¨Ù±رگ",
+       "prefs-editwatchlist": "Ú¤Û\8cراÛ\8cØ´ Ø³Ø§Ù\9bÙ\84Ù\9b Ø¨Ù±رگ",
+       "prefs-editwatchlist-label": "دادٱÛ\8cا Ù\86اÙ\92 Ø¯ Ø³Ø§Ù\9bÙ\84Ù\9b Ø¨Ù±Ø±Ú¯ Ø®Ù\88تÙ\88 Ú¤Û\8cراÛ\8cØ´ Ø¨Ù±Ú©Ø½ت:",
+       "prefs-editwatchlist-edit": "داسÙ\88Ù\86ؽا Ù\86اÙ\92 Ø³Ø§Ù\9bÙ\84Ù\9b Ø¨Ù±Ú©Ø½Øª Û\89 Ú¤Ù\86Ù\88 Ù\86اÙ\92 Ø¯ Ø³Ø§Ù\9bÙ\84Ù\9b Ø¨Ù±Ø±Ú¯ Ø®Ù\88تÙ\88 Ú¤Ø±Ø¯Ø§Ø±Ø½ت",
+       "prefs-editwatchlist-raw": "Ú¤Û\8cراÛ\8cشتکارÛ\8c Ø±Ø¯Û\8cÙ\81Û\8c Ø³Ø§Ù\9bÙ\84Ù\9b Ø¨Ù±رگ",
+       "prefs-editwatchlist-clear": "ساÙ\9bÙ\84Ù\9b Ø¨Ù±Ø±Ú¯ ØªÙ\88 Ù\86اÙ\92 Ù¾Ø§Ú© Ø¨Ù±Ú©Ø½ت",
+       "prefs-watchlist-days": "رۊزؽا د ساٛلٛ بٱرگ نشوݩ داٛئٱ بۊئٱن:",
+       "prefs-watchlist-days-max": "$1 بؽشترونٱ {{PLURAL:$1|رۊز|رۊزؽا}}",
        "prefs-watchlist-edits": "بیشترونه انازه آلشتیایی که د سیل برگ گپ بیه نشو دئه بیه:",
-       "prefs-watchlist-edits-max": "Ø´Ù\85ارÙ\87 Ø¨Û\8cشترÙ\88Ù\86Ù\87:1000",
-       "prefs-watchlist-token": "Ù\86Ø´Ù\88Ù\86Ù\87 Ø³Û\8cÙ\84 Ø¨رگ:",
-       "prefs-misc": "شیڤئسئن",
-       "prefs-resetpass": "رازÛ\8cÙ\86Ù\87 Ú¯Ù\88اردÙ\86 Ù\86Ù\87 Ø¢Ù\84شت Ø¨Ù\83Ù\8aت",
-       "prefs-changeemail": "تÛ\8cرÙ\86ئشÙ\88Ù\99Ù\86 Ø£Ù\86جÙ\88Ù\85اÙ\86اÙ\85Û\95 ØªÙ\88Ù\99Ù\86Û\95 Ø¢Ù\84ئشت Ø¨Ø£Ú©Û\8cت",
-       "prefs-setemail": "يه گل انجومانامه بنیت",
-       "prefs-email": "Ú\86Û\8cا Ù\87Ù\86Û\8c Ø§Ù\86جÙ\88Ù\85اÙ\86اÙ\85Ù\87",
-       "prefs-rendering": "شیڤە",
-       "saveprefs": "ئÙ\85اÛ\8cÛ\95 Ú©Ø¦Ø±Ø¯Ø¦ن",
-       "restoreprefs": "د نو زنه کردن همه میزونکاریا پیش فرض(د همه جایا)",
-       "prefs-editing": "د حال و بال ڤیرایئشت",
-       "searchresultshead": "پئÛ\8c Ø¬Ù\88Ù\99ری",
+       "prefs-watchlist-edits-max": "Ø´Ù\85ارٱ Ø¨Ø½Ø´ØªØ±Ù\88Ù\86Ù±:1000",
+       "prefs-watchlist-token": "Ù\86Ø´Ù\88Ù\86Ù± Ø³Ø§Ù\9bÙ\84Ù\9b Ø¨Ù±رگ:",
+       "prefs-misc": "شؽڤسن",
+       "prefs-resetpass": "رازÛ\8cÙ\86Ù± Ú¯Ù\88ئارسÙ\86 Ù\86اÙ\92 Ø¢Ù\84شت Ø¨Ù±Ú©Ø½ت",
+       "prefs-changeemail": "تÛ\8cرÙ\86Ø´Ù\88Ý© Ù±Ù\86جÙ\88Ù\85اÙ\86اÙ\85Ù± ØªÙ\88 Ù\86اÙ\92 Ø¢Ù\84شت Ø¨Ù±Ú©Ø½ت",
+       "prefs-setemail": "یاٛ ٱنجومانامٱ بٱنؽت",
+       "prefs-email": "Ú\86Û\8cا Ù\87Ù\86Û\8c Ø§Ù\86جÙ\88Ù\85اÙ\86اÙ\85Ù±",
+       "prefs-rendering": "شؽڤٱ",
+       "saveprefs": "Ø¢Ù\85ادٱ Ú©Ø±Ø¯ن",
+       "restoreprefs": "د نۊ زنٱ کردن هٱمٱ میزونکاریا پیش فٱرز(د هٱمٱ جایا)",
+       "prefs-editing": "د هال ۉ بال ڤیرایش",
+       "searchresultshead": "پاÙ\9bجÛ\8aری",
        "stub-threshold": "آستوٙنە ڤیرایئشتکاریا د یأک دیسئسە <a href=\"#\" class=\"stub\">ناقئص</a> (بایت):",
-       "stub-threshold-sample-link": "نئموٙنە",
-       "stub-threshold-disabled": "Ù\86اکÙ\88Ù\86ئشتگأر Ø¨Û\8cÛ\8cÛ\95",
-       "recentchangesdays": "روزیا آلشتیا تازه باو نه نشو بیه:",
-       "recentchangesdays-max": "$1 بیشترونه {{PLURAL:$1|روز|روزیا}}",
+       "stub-threshold-sample-link": "نمۊنٱ",
+       "stub-threshold-disabled": "Ù\86اکÙ\86شگٱر Ø¨Û\8cÙ±",
+       "recentchangesdays": "رۊزؽا آلشتیا تازٱ بۊ ناْ نشوݩ باٛیٱ:",
+       "recentchangesdays-max": "$1 بؽشترونٱ {{PLURAL:$1|رۊز|رۊزؽا}}",
        "recentchangescount": "انازه ویرایشتیایی که دیاری می که:",
        "prefs-help-recentchangescount": "یه شامل آلشتیا تازه،ویرگاریا بلگه و پهرستنومه یا هئ.",
        "prefs-help-watchlist-token2": "یه یه گل کلیت رازینه دار سی خوارک تیارگه سیل برگه شمانه.\nهر کسی که شما مئشناسیت می تونه سیل برگ شما نه بوحونه،په ونه هومبئری نکیت.[[Special:ResetTokens|ار لازمه ونه آلشت بئیت ایچه نه بپورنیت]].",
-       "savedprefs": "ویجه گیا هنی تو اماییه بیه.",
-       "timezonelegend": "گات Ø±Ø§Ø³Ø§Ú¯Ù\87",
-       "localtime": "گات ولاتی:",
-       "timezoneuseserverdefault": "ویکی پیش فرض($1) وه کار بونیت",
+       "savedprefs": "ویژگیا هنی تو آمادٱ بیٱ.",
+       "timezonelegend": "گات Ø±Ø§Ø³Ø§Ú¯Ù±:",
+       "localtime": "گات ڤلاتی:",
+       "timezoneuseserverdefault": "ڤیکی پیش فٱرز($1) ڤ کار بونؽت",
        "timezoneuseoffset": "هنی",
-       "servertime": "گات رسینه جا:",
-       "guesstimezone": "وا جاگرد پر بوئه",
-       "timezoneregion-africa": "اÙ\81رقا",
-       "timezoneregion-america": "اÙ\85رÙ\83ا",
-       "timezoneregion-antarctica": "قطو هار ونه",
-       "timezoneregion-arctic": "قطو شمال",
-       "timezoneregion-asia": "آسيا",
-       "timezoneregion-atlantic": "جهون آو آتلانتیک",
-       "timezoneregion-australia": "استراليا",
-       "timezoneregion-europe": "اوروپا",
-       "timezoneregion-indian": "جهوناو هند",
-       "timezoneregion-pacific": "جهوناو آروم",
+       "servertime": "گات رٱسینٱجا:",
+       "guesstimezone": "ڤا جاگرد پور بۊئٱ",
+       "timezoneregion-africa": "اÙ\92Ù\81رÛ\8cقا",
+       "timezoneregion-america": "اÙ\92Ù\85رÛ\8cÚ©ا",
+       "timezoneregion-antarctica": "قوتب هارگٱ",
+       "timezoneregion-arctic": "قوتب شمال",
+       "timezoneregion-asia": "آسؽا",
+       "timezoneregion-atlantic": "جهوݩ آو آتلانتیک",
+       "timezoneregion-australia": "اوسترالٛیا",
+       "timezoneregion-europe": "اورۊپا",
+       "timezoneregion-indian": "جهوݩ آو هند",
+       "timezoneregion-pacific": "جهوݩ آو آروم",
        "allowemail": "انجومانامه نه سی کاریاریا هنی کنشتگر کو",
-       "prefs-searchoptions": "پئÛ\8c Ø¬Ù\88Ù\99ری",
+       "prefs-searchoptions": "پاÙ\9bجÛ\8aری",
        "prefs-namespaces": "نوم جایا",
-       "default": "پيش فرض",
-       "prefs-files": "جانیایا",
-       "prefs-custom-css": "سی اس اس جاافتائه",
-       "prefs-custom-js": "جاوا نیسسه جاافتائه",
+       "default": "پيش فٱرز",
+       "prefs-files": "جانؽایا",
+       "prefs-custom-css": "سی اْس اْس جا اوفتایٱ",
+       "prefs-custom-js": "جاڤا نیسسٱ جا اوفتایٱ",
        "prefs-common-config": " سی اس اس/جاوا اسکریپت بهر بیه سی همه پوسه یا:",
-       "prefs-reset-intro": "شما می تونیت ای بلگه سی د نو زنه کردن ترجیحات خوت وه شکل تیارگه پیش فرض وه کار بوونیت.\nیه ورئشت پذیر نئ.",
-       "prefs-emailconfirm-label": "پش راست کردن انجومانامه:",
-       "youremail": "أنجومانامە:",
+       "prefs-reset-intro": "شما مؽ تونؽت اؽ بٱلگٱ ناْ سی د نۊ زنٱ کردن تٱرجیهؽا خوت ڤ شکل تیارگٱ پیش فٱرز ڤ کار بونؽت.\nیٱ ورگٱشت پٱزیر نؽ.",
+       "prefs-emailconfirm-label": "تٱیید کردن ٱنجومانامٱ:",
+       "youremail": "ٱنجومانامٱ:",
        "username": "{{GENDER:$1|نوم کاریاری}}:",
-       "prefs-memberingroups": "{{GENDER:$2|أندوم}}  {{PLURAL:$1|دأسە|دأسە یا}}:",
+       "prefs-memberingroups": "{{GENDER:$2|ٱندوم}}  {{PLURAL:$1|دٱسٱ|دٱسٱیا}}:",
        "prefs-memberingroups-type": "$1",
-       "prefs-registration": "گات Ø«Ù\88ت Ù\86ام:",
+       "prefs-registration": "گات Ø³Ù±Ø¨Øª Ù\86Ù\88م:",
        "prefs-registration-date-time": "$1",
-       "yourrealname": "نوم راستكی:",
-       "yourlanguage": "زوٙن:",
+       "yourrealname": "نوم راسی:",
+       "yourlanguage": "زڤوݩ:",
        "yourvariant": "مینونٱ آلشتگٱر زڤوݩ:",
-       "prefs-help-variant": "قسٱ ڤری اْنتخاویی شما سی نمایش مینونٱ بٱلگٱیا د اؽ ڤیکی.",
-       "yournick": "اÙ\85ضا ØªØ§Ø²Ù\87:",
-       "prefs-help-signature": "ویر و باوریا نیسسه بیه د بلگه چک چنه باید وا«<nowiki>~~~~</nowiki>» امضا بان؛ ای نشون وه شکل خودانجومی وه امضا شما و مؤر ویرگار تبدیل بوئه.",
+       "prefs-help-variant": "قسٱ ڤری اْنتخابی شما سی نمایش مؽنونٱ بٱلگٱیا د اؽ ڤیکی.",
+       "yournick": "اÙ\92Ù\85زا ØªØ§Ø²Ù±:",
+       "prefs-help-signature": "ڤویر ۉ باڤٱرؽا نیسسٱ بیٱ د بٱلگٱ چٱک چنٱ بایٱد ڤا«<nowiki>~~~~</nowiki>» اْمزا بۊئٱن؛ اؽ نشوݩ ڤ شکل خودٱنجومؽ ڤ اْمزا شما ۉ مۉئر ڤیرگار تٱبدیلٛ مۊئٱ.",
        "badsig": "ئمضا خوم بی ئتئڤار.\nسأردیسیا ئچ تی ئم ئل نە ڤارئسی بأکیت.",
        "badsiglength": "امضا شما فره گپه.\nدرازا امضا باید کمتر  د $1 {{PLURAL:$1|نیسه}} بوئه.",
        "yourgender": "شما بیشتر میهایت که چه جوری گوته بوئه؟",
index 2e5a6ba..7614e38 100644 (file)
        "protectedpages-timestamp": "Laiko žyma",
        "protectedpages-page": "Puslapis",
        "protectedpages-expiry": "Galioja iki",
-       "protectedpages-performer": "Užrakinantis naudotojas",
+       "protectedpages-performer": "Užrakinęs naudotojas",
        "protectedpages-params": "Užrakinimo nuostatos",
        "protectedpages-reason": "Priežastis",
        "protectedpages-submit": "Rodyti puslapius",
index c29f5d6..9f73d05 100644 (file)
@@ -17,7 +17,8 @@
                        "Amjad Khan",
                        "Zakiy",
                        "Vlad5250",
-                       "S Kartika"
+                       "S Kartika",
+                       "NoiX180"
                ]
        },
        "tog-underline": "Garisbawahi tautan:",
        "tags": "Tag parubahan nan sah",
        "tag-filter": "[[Special:Tags|Tag]] sariang:",
        "tag-filter-submit": "Sariang",
-       "tag-list-wrapper": "[[Istimewa:Tag|{{PLURAL:$1|Tag}}]]: $2",
+       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|Tag}}]]: $2",
        "tags-title": "Tag",
        "tags-intro": "Laman ko barisi daftar tag nan dapek ditandoi dek parangkaik lunak jo suntiangan dan maknanyo.",
        "tags-tag": "Namo tag",
index de39a2e..10f26ab 100644 (file)
        "watchlistedit-raw-done": "Joew volglieste is bie-ewörken.",
        "watchlistedit-raw-added": "Der {{PLURAL:$1|is 1 zied|bin $1 ziejen}} bie edaon:",
        "watchlistedit-raw-removed": "Der {{PLURAL:$1|is 1 zied|bin $1 ziejen}} vortedaon:",
+       "watchlistedit-clear-done": "Juw volglyste is eleadigd.",
        "watchlisttools-clear": "Volglieste leegmaken",
        "watchlisttools-view": "Wiezigingen bekieken",
        "watchlisttools-edit": "Volglieste bekieken en bewarken",
index 7a7589c..fa5ee6f 100644 (file)
        "search-interwiki-more": "(meer)",
        "search-interwiki-more-results": "meer resultaten",
        "search-relatedarticle": "Gerelateerd",
+       "search-invalid-sort-order": "De sorteervolgorde $1 is onbekend, de normale sorteervolgorde is in plaats daarvan toegepast. Geldige sorteervolgorden zijn: $2",
+       "search-unknown-profile": "Het zoekprofiel $1 is onbekend. Het standaard zoekprofiel zal worden toegepast.",
        "searchrelated": "gerelateerd",
        "searchall": "alle",
        "showingresults": "Hieronder {{PLURAL:$1|staat '''1''' resultaat|staan '''$1''' resultaten}} vanaf #'''$2'''.",
index a011006..c11c94a 100644 (file)
        "editingcomment": "(ߛߌ߰ߘߊ߬ ߞߎߘߊ߫) ߡߊߦߟߍ߬ߡߊ߲ ߦߴߌ ߘߐ߫ $1",
        "editconflict": "ߝߐߢߐ߲߯ߞߐ ߡߊߦߟߍ߬ߡߊ߲߬: $1",
        "yourtext": "ߌ ߟߊ߫ ߛߓߍߟߌ",
+       "storedversion": "ߟߢߊ߬ߟߌ߬ ߟߊߞߎ߲߬ߘߎ߬ߣߍ߲",
+       "editingold": "<strong>ߖߊ߲߬ߓߌ߬ߟߊ߬ߟߌ: ߌ ߦߋ߫ ߟߢߊ߬ߟߌ ߕߎ߬ߡߊ ߕߊ߬ߡߌ߲߬ߣߍ߲ ߠߋ߬ ߡߊߦߟߍߡߊ߲ ߞߊ߲߬ ߞߐߜߍ ߣߌ߲߬ ߘߐ߫ ߣߌ߲߬.</strong> \nߣߴߌ ߞߵߊ߬ ߟߊߞߎ߲߬ߘߎ߫߸ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߝߋ߲߫-ߋ-ߝߋ߲߫ ߞߍߣߍ߲߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߣߌ߲߬ ߞߐ߫߸ ߓߣߐ߬ ߘߌ߫ ߞߴߏ߬ ߓߍ߯ ߘߐ߫.",
+       "unicode-support-fail": "ߊ߬ ߛߓߍߣߍ߲߫ ߦߋ߫ ߞߏ߫ ߞߏ߫ ߌ ߟߊ߫ ߛߏ߲߯ߓߊߟߊ߲ ߘߌ߬ߢߍ߬ߣߍ߲߬ ߕߍ߫ ߎߣߌߞߐߘ ߡߊ߬.ߞߐߜߍ ߡߊߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߞߊ߬ߣߌ߲߬ ߣߍ߲߫߸ ߏ߬ ߘߐ߫ ߌ ߟߊ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߕߎ߲߬ ߡߊ߫ ߟߊߞߎ߲߬ߘߎ߬ ߡߎߣߎ߲߬.",
+       "yourdiff": "ߓߐߣߍ߲ߢߐ߲߰ߡߊ ߟߎ߬",
+       "editpage-cannot-use-custom-model": "ߞߐߜߍ ߣߌ߲߬ ߞߣߐߘߐ ߛߎ߮ߦߊ ߕߍߣߊ߬ ߛߐ߲߬ ߠߊ߫ ߡߊߦߟߍ߬ߡߊ߲߫ ߠߊ߫.",
        "templatesused": "{{PLURAL:$1|ߞߙߊߞߏ|ߞߙߊߞߏ ߟߎ߫}} ߟߎ߫ ߟߊߓߊ߯ߙߊ߫ ߘߊ߫ ߞߐߜߍ ߣߌ߲߬ ߘߐ߫",
        "templatesusedpreview": "{{PLURAL:$1|ߞߙߊߞߏ|ߞߙߊߞߏ ߟߎ߬}} ߟߋ߬ ߟߊߓߊ߯ߙߊ߫ ߣߍ߲߫ ߢߍߦߋߟߌ ߣߌ߲߬ ߘߐ߫",
        "template-protected": "(ߊ߬ ߡߊߞߊ߲ߞߊ߲ߣߍ߲߫ ߠߋ߬)",
        "search-filter-title-prefix-reset": "ߞߐߜߍ ߓߍ߯ ߢߌߣߌ߲߫",
        "searchresults-title": "ߣߌ߲߬ \"$1\" ߢߌߣߌ߲ߠߌ߲ ߞߐߝߟߌ",
        "titlematches": "ߞߐߜߍ ߞߎ߲߬ߕߐ߮ ߓߍ߲߬ߢߐ߲߰ߡߊ߬ߣߍ߲߫",
+       "textmatches": "ߞߐߜߍ ߞߟߏߜߍ ߦߋ߫ ߦߋ߲߬",
+       "notextmatches": "ߞߐߜߍ ߞߟߏߜߍ߫ ߕߴߦߋ߲߬",
        "prevn": "ߕߊ߬ߡߌ߲߬ߣߍ߲ ߠߎ߬ {{PLURAL:$1|$1}}",
        "nextn": "ߟߊߕߎ߲߰ߠߊ {{PLURAL:$1|$1}}",
        "prev-page": "ߞߐߜߍ ߢߍߕߊ",
        "prefs-changeswatchlist": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߓߘߊ߫ ߦߌ߬ߘߊ߬",
        "prefs-pageswatchlist": "ߞߐߜߍ߫ ߜߋ߬ߟߎ߲߬ߣߍ߲ ߠߎ߬",
        "prefs-tokenwatchlist": "ߖߐߟߐ߲ߞߐ",
+       "prefs-diffs": "ߓߐߣߍ߲ߢߐ߲߰ߡߊ ߟߎ߬",
        "prefs-help-prefershttps": "ߟߊ߬ߝߌ߬ߛߦߊ߬ߟߌ ߣߌ߲߬ ߘߴߊ߬ ߝߏ߲߬ߝߏ߲ ߟߴߌ ߟߊ߫ ߜߊ߲߬ߞߎ߲߬ߠߌ߲ ߣߊ߬ߕߐ ߞߊ߲߬.",
        "userrights": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߤߊߞߍ",
        "userrights-lookup-user": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ ߘߏ߫ ߛߎߥߊ߲ߘߌ߫",
        "rcfilters-filter-user-experience-level-unregistered-label": "ߕߐ߯ߛߓߍߓߊߟߌ",
        "rcfilters-filter-user-experience-level-unregistered-description": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߊ ߡߍ߲ ߜߊ߲߬ߞߎ߲߬ߣߍ߲߬ ߕߍ߫.",
        "rcfilters-filter-user-experience-level-learner-label": "ߞߊ߬ߙߊ߲߬ߠߊ ߟߎ߬",
+       "rcfilters-filter-user-experience-level-experienced-label": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߫ ߖߊߙߌ߲ߒߕߋ",
        "rcfilters-filter-user-experience-level-experienced-description": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߊ߬ ߕߐ߯ߛߓߍߣߍ߲ ߡߍ߲ ߠߊ߫ ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߓߘߊ߫ ߕߊ߬ߡߌ߲߬ ߅߀߀ ߞߊ߲߬ ߕߟߋ߬ ߃߀ ߓߊ߯ߙߊ߫ ߣߐ.",
+       "rcfilters-filtergroup-automated": "ߞߍߒߖߘߍߦߋ߫ ߓߟߏߓߌߟߊߢߐ߲߯ߞߊ߲",
        "rcfilters-filter-bots-label": "ߓߏߕ",
        "rcfilters-filter-bots-description": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߡߍ߲ ߠߎ߬ ߛߌ߲ߘߌߣߍ߲߫ ߞߍߒߖߘߍߦߋ߫ ߖߐ߯ߙߊ߲ ߠߎ߬ ߘߐ߫.",
        "rcfilters-filter-humans-label": "ߡߐ߱ (ߓߏߕ  ߕߍ߫)",
        "rcfilters-filter-watchlist-watched-description": "ߊ߬ ߡߊߝߊ߬ߟߋ߲߬ ߌ ߟߊ߫ ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߞߐߜߍ ߟߎ߬ ߘߐ߫.",
        "rcfilters-filter-watchlist-watchednew-label": "ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ߫ ߞߎߘߊ߫ ߓߘߊ߫ ߡߊߦߟߍ߬ߡߊ߲߫",
        "rcfilters-filter-watchlist-notwatched-label": "ߊ߬ ߕߍ߫ ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߘߐ߫",
+       "rcfilters-filtergroup-watchlistactivity": "ߜߋ߬ߟߎ߲߬ߠߌ߲߬ ߛߙߍߘߍ ߡߛߍ߬ߞߍ߬ߡߛߍߞߍ",
+       "rcfilters-filter-watchlistactivity-unseen-label": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲߬ ߦߋߓߊߟߌ ߟߎ߬",
+       "rcfilters-filter-watchlistactivity-seen-label": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ ߠߎ߫ ߦߋ߫",
        "rcfilters-filtergroup-changetype": "ߡߊ߬ߦߟߍ߬ߡߊ߲߬ߠߌ߲ ߛߎ߯ߦߊ",
        "rcfilters-filter-pageedits-label": "ߞߐߜߐ ߡߊߦߟߍ߬ߡߊ߲߫",
        "rcfilters-filter-pageedits-description": "ߞߐߜߍ ߛߌ߲ߘߟߌ",
        "uploadwarning-text": "ߞߐߕߐ߮ ߘߎ߰ߟߊ߬ߘߐ߫ ߞߊ߲ߛߓߍߟߌ ߡߊ߬ߦߟߍ߬ߡߊ߲߫ ߖߊ߰ߣߌ߲߬߸ ߞߵߊ߬ ߡߊߝߍߣߍ߲߫ ߕߎ߲߯.",
        "savefile": "ߞߐߕߐ߮ ߟߊߞߎ߲߬ߘߎ߬",
        "upload-source": "ߞߐߕߐ߮ ߛߎ߲",
+       "sourcefilename": "ߞߐߕߐ߮ ߕߐ߮ ߛߎ߲:",
        "sourceurl": "URL ߛߎ߲:",
        "destfilename": "ߞߐߕߐ߮ ߕߐ߮ ߞߎ߲߬ߕߋߟߋ߲:",
        "upload-maxfilesize": "ߞߐߕߐ߮ ߢߊ߲ߞߊ߲ ߞߐߘߊ߲: $1",
        "upload-dialog-button-upload": "ߟߊ߬ߦߟߍ߬ߟߌ",
        "upload-form-label-infoform-title": "ߝߊߙߊ߲ߝߊ߯ߛߟߌ",
        "upload-form-label-infoform-name": "ߕߐ߮",
+       "upload-form-label-infoform-description": "ߞߊ߲߬ߛߓߍߟߌ",
        "upload-form-label-usage-title": "ߟߊ߬ߓߊ߰ߙߊ߬ߟߌ",
        "upload-form-label-usage-filename": "ߞߐߕߐ߮ ߕߐ߮",
        "upload-form-label-own-work": "ߒ ߖߘߍ߬ߞߊ߬ߣߌ߲߬ ߓߊ߯ߙߊ ߟߋ߬",
        "license-header": "ߟߊ߬ߘߌ߬ߢߍ߬ߟߌ ߦߴߌ ߘߐ߫",
        "nolicense": "ߊ߬ ߡߊ߫ ߓߊߕߐ߬ߡߐ߲߬",
        "listfiles-delete": "ߊ߬ ߖߏ߬ߛߌ߬",
+       "listfiles_search_for": "ߡߍ߲ߕߊߦߋߕߊ ߕߐ߮ ߢߌߣߌ߲ߠߌ߲:",
+       "listfiles-userdoesnotexist": "ߟߊ߬ߓߊ߰ߙߊ߬ ߖߊߕߋߘߊ \"$1\" ߟߊߞߎ߲߬ߘߎ߬ߣߍ߲߫ ߕߍ߫.",
        "imgfile": "ߞߐߕߐ߮",
        "listfiles": "ߞߐߕߐ߮ ߛߙߍߘߍ",
        "listfiles_thumb": "ߞߝߊ߬ߟߋ߲ߛߋ߲",
index 009a9e4..f505038 100644 (file)
        "search-interwiki-more": "(więcej)",
        "search-interwiki-more-results": "Więcej wyników",
        "search-relatedarticle": "Pokrewne",
+       "search-invalid-sort-order": "Kolejność sortowania $1 jest nierozpoznawana. Zastosowane zostanie domyślne sortowanie. Właściwymi kolejnościami są: $2",
+       "search-unknown-profile": "Profil wyszukiwania $1 jest nierozpoznawany. Zostanie zastosowany domyślny profil.",
        "searchrelated": "pokrewne",
        "searchall": "wszystkie",
        "showingresults": "Poniżej znajduje się lista {{PLURAL:$1|z '''1''' wynikiem|'''$1''' wyników}}, rozpoczynając od wyniku numer '''$2'''.",
index 00c631f..d96cbbe 100644 (file)
        "search-interwiki-more": "(mais)",
        "search-interwiki-more-results": "Mais resultados",
        "search-relatedarticle": "Relacionado",
+       "search-invalid-sort-order": "A ordem de classificação de $1 não é reconhecida, a classificação padrão será aplicada. Ordens de classificação válidas são: $2",
+       "search-unknown-profile": "O perfil de pesquisa de $1 não é reconhecido, o perfil de pesquisa padrão será aplicado.",
        "searchrelated": "relacionados",
        "searchall": "todos",
        "showingresults": "A seguir {{PLURAL:$1|é mostrado '''um''' resultado|são mostrados até '''$1''' resultados}}, iniciando no '''$2'''º.",
index 658e7bc..7756b2d 100644 (file)
        "search-interwiki-more": "(mais)",
        "search-interwiki-more-results": "mais resultados",
        "search-relatedarticle": "Relacionado",
+       "search-invalid-sort-order": "A ordenação $1 não é reconhecida, será aplicada a ordenação padrão. As ordenações válidas são: $2",
+       "search-unknown-profile": "O perfil de pesquisa $1 não é reconhecido, será aplicado o perfil de pesquisa padrão.",
        "searchrelated": "relacionados",
        "searchall": "todos",
        "showingresults": "{{PLURAL:$1|É apresentado <strong>um</strong> resultado|São apresentados até <strong>$1</strong> resultados}} abaixo{{PLURAL:$1||, começando pelo <strong>$2</strong>º}}.",
index 6c8942c..f0eeaa4 100644 (file)
        "rcfilters-clear-all-filters": "Title for the button that clears all filters",
        "rcfilters-show-new-changes": "Label for the button to show new changes. Parameters:\n* $1 - timestamp from which new changes are available. It indicates that clicking the refresh link will bring changes newer than (or equal to) this timestamp. It is formatted according to the user's date, time and timezone preferences",
        "rcfilters-search-placeholder": "Placeholder for the filter search input. The first \"Filter\" is a verb, and the second \"filter\" is a noun.",
+       "rcfilters-search-placeholder-mobile": "Placeholder for the filter search input for mobile devices.",
        "rcfilters-invalid-filter": "A label for an invalid filter.",
        "rcfilters-empty-filter": "Placeholder for the filter list when no filters were chosen.",
        "rcfilters-filterlist-title": "Title for the filters list.\n{{Identical|Filter}}",
        "linkaccounts": "Title of the special page [[Special:LinkAccounts]] which allows the user to connect the local user accounts with external ones such as Google or Facebook.",
        "linkaccounts-success-text": "Text shown on top of the form after a successful action.",
        "linkaccounts-submit": "Text of the main submit button on [[Special:LinkAccounts]] (when there is one)",
+       "cannotunlink-no-provider-title": "Error page title shown when the user visits [[Special:UnlinkAccounts]] but there is no external account that could be unlinked.",
+       "cannotunlink-no-provider": "Error message shown when the user visits [[Special:UnlinkAccounts]] but there is no external account that could be unlinked.",
        "unlinkaccounts": "Title of the special page [[Special:UnlinkAccounts]] which allows the user to remove linked remote accounts.",
        "unlinkaccounts-success": "Account unlinking form success message",
        "authenticationdatachange-ignored": "Shown when authentication data change was unsuccessful due to configuration problems.\n\nCf. e.g. {{msg-mw|Passwordreset-ignored}}.",
index cc12656..6267b0d 100644 (file)
        "right-editmyusercss": "Редактирование своих пользовательских CSS-файлов",
        "right-editmyuserjson": "Редактирование своих пользовательских JSON-файлов",
        "right-editmyuserjs": "Редактирование своих пользовательских JavaScript-файлов",
+       "right-editmyuserjsredirect": "Редактирование собственных JavaScript-файлов, которые являются перенаправлениями",
        "right-viewmywatchlist": "Просмотр своего списка наблюдения",
        "right-editmywatchlist": "Редактирование своего списка наблюдения. Некоторые действия будут добавлять страницы даже без такого права.",
        "right-viewmyprivateinfo": "Просмотр собственных личных данных (например, адрес электронной почты, настоящее имя)",
        "action-editmyusercss": "редактирование собственных CSS-файлов",
        "action-editmyuserjson": "редактирование собственных JSON-файлов",
        "action-editmyuserjs": "редактирование собственных JavaScript-файлов",
+       "action-editmyuserjsredirect": "редактирование собственных JavaScript-файлов, которые являются перенаправлениями",
        "action-viewsuppressed": "просмотр версий, скрытых от всех участников",
        "action-hideuser": "запрет имени участника и его сокрытие",
        "action-ipblock-exempt": "обход блокировок по IP, автоблокировок и блокировок диапазонов",
        "specialmute-success": "Изменения были успешно сделаны. Просмотрите всех отключённых участников на [[Special:Preferences|ваших настройках]].",
        "specialmute-submit": "Подтвердить",
        "specialmute-label-mute-email": "Отключить эл. почту от этого участника",
-       "specialmute-header": "Ð\9fожалÑ\83йÑ\81Ñ\82а, Ð²Ñ\8bбеÑ\80иÑ\82е Ð½Ð°Ñ\81Ñ\82Ñ\80ойки Ñ\83ведомлений Ð¾Ñ\82 <b>{{BIDI:[[User:$1]]}}</b>.",
+       "specialmute-header": "Ð\9fожалÑ\83йÑ\81Ñ\82а, Ð²Ñ\8bбеÑ\80иÑ\82е Ð½Ð°Ñ\81Ñ\82Ñ\80ойки Ñ\83ведомлений Ð´Ð»Ñ\8f {{GENDER:$1|Ñ\83Ñ\87аÑ\81Ñ\82ника|Ñ\83Ñ\87аÑ\81Ñ\82ниÑ\86Ñ\8b}} <b>{{BIDI:[[User:$1|$1]]}}</b>.",
        "specialmute-error-invalid-user": "Указанное вами имя участника не может быть найдено.",
-       "specialmute-email-footer": "Для управления настройками эл. почты для {{BIDI:$2}}, пожалуйста, посмотрите <$1>.",
+       "specialmute-email-footer": "Для управления настройками эл. почты {{GENDER:$2|участника|участницы}} {{BIDI:$2}}, пожалуйста, посетите <$1>.",
        "specialmute-login-required": "Пожалуйста, войдите, чтобы совершить изменения.",
        "mute-preferences": "Настройки выключения",
        "revid": "версия $1",
index 0c2df6b..da01122 100644 (file)
@@ -1740,6 +1740,7 @@ return [
        /* MediaWiki Special pages */
 
        'mediawiki.rcfilters.filters.base.styles' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'skinStyles' => [
                        'default' => 'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less',
                ],
@@ -1753,6 +1754,7 @@ return [
                ],
        ],
        'mediawiki.rcfilters.filters.dm' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'localBasePath' => "$IP/resources/src/mediawiki.rcfilters",
                'remoteBasePath' => "$wgResourceBasePath/resources/src/mediawiki.rcfilters",
                'packageFiles' => [
@@ -1783,6 +1785,7 @@ return [
                ],
        ],
        'mediawiki.rcfilters.filters.ui' => [
+               'targets' => [ 'desktop', 'mobile' ],
                'localBasePath' => "$IP/resources/src/mediawiki.rcfilters",
                'remoteBasePath' => "$wgResourceBasePath/resources/src/mediawiki.rcfilters",
                'packageFiles' => [
@@ -1853,6 +1856,7 @@ return [
                        'styles/mw.rcfilters.ui.RclToOrFromWidget.less',
                        'styles/mw.rcfilters.ui.RclTargetPageWidget.less',
                        'styles/mw.rcfilters.ui.WatchlistTopSectionWidget.less',
+                       'styles/mw.rcfilters.ui.FilterTagMultiselectWidgetMobile.less'
                ],
                'skinStyles' => [
                        'vector' => [
@@ -1900,6 +1904,7 @@ return [
                        'rcfilters-clear-all-filters',
                        'rcfilters-show-new-changes',
                        'rcfilters-search-placeholder',
+                       'rcfilters-search-placeholder-mobile',
                        'rcfilters-invalid-filter',
                        'rcfilters-empty-filter',
                        'rcfilters-filterlist-title',
@@ -1961,6 +1966,7 @@ return [
                        'oojs-ui.styles.icons-interactions',
                        'oojs-ui.styles.icons-layout',
                        'oojs-ui.styles.icons-media',
+                       'oojs-ui-windows.icons'
                ],
        ],
        'mediawiki.interface.helpers.styles' => [
index 4684ea2..cce3061 100644 (file)
        background-image: e( '/* @embed */' ) url( @url );
 }
 
-.vertical-gradient( @startColor: gray, @endColor: white, @startPos: 0, @endPos: 100% ) {
-       background-color: @endColor;
-       background-image: -webkit-linear-gradient( top, @startColor @startPos, @endColor @endPos ); // Safari 5.1+, Chrome 10+
-       background-image: -moz-linear-gradient( top, @startColor @startPos, @endColor @endPos ); // Firefox 3.6+
-       background-image: linear-gradient( @startColor @startPos, @endColor @endPos ); // Standard
+.horizontal-gradient( @startColor: #808080, @endColor: #fff, @startPos: 0, @endPos: 100% ) {
+       background-color: average( @startColor, @endColor );
+       background-image: -webkit-gradient( linear, left top, right top, color-stop( @startPos, @startColor ), color-stop( @endPos, @endColor ) );
+       background-image: -webkit-linear-gradient( left, @startColor @startPos, @endColor @endPos );
+       background-image: -moz-linear-gradient( left, @startColor @startPos, @endColor @endPos );
+       background-image: linear-gradient( to right, @startColor @startPos, @endColor @endPos );
+}
+
+.vertical-gradient( @startColor: #808080, @endColor: #fff, @startPos: 0, @endPos: 100% ) {
+       background-color: average( @startColor, @endColor );
+       background-image: -webkit-gradient( linear, right top, right bottom, color-stop( @startPos, @startColor ), color-stop( @endPos, @endColor ) );
+       background-image: -webkit-linear-gradient( top, @startColor @startPos, @endColor @endPos );
+       background-image: -moz-linear-gradient( top, @startColor @startPos, @endColor @endPos );
+       background-image: linear-gradient( to bottom, @startColor @startPos, @endColor @endPos );
 }
 
 // SVG support using a transparent gradient to guarantee cross-browser
index 87f257b..4338b0b 100644 (file)
@@ -28,7 +28,6 @@
        }
 
        &-results {
-               width: 35em;
                margin: 5em auto;
 
                &-noresult,
 .mw-rcfilters-highlight-color-c1.mw-rcfilters-highlight-color-c2.mw-rcfilters-highlight-color-c3.mw-rcfilters-highlight-color-c4.mw-rcfilters-highlight-color-c5 {
        .highlight-results( tint( mix( @highlight-c1, mix( @highlight-c2, mix( @highlight-c3, average( @highlight-c4, @highlight-c5 ), 20% ), 20% ), 20% ), 15% ) );
 }
+
+@media screen and ( min-width: @width-breakpoint-tablet ) {
+       // center conflict message
+       // e.g. Special:RecentChanges?goodfaith=maybebad&hidepageedits=1&hidenewpages=1&hidecategorization=1&hideWikibase=1&limit=50&days=0.0833&enhanced=1&urlversion=2
+       // More context in https://phabricator.wikimedia.org/T223363#5374874
+       .mw-rcfilters-ui-changesListWrapperWidget {
+               &-results {
+                       width: 35em;
+               }
+       }
+}
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterTagMultiselectWidgetMobile.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterTagMultiselectWidgetMobile.less
new file mode 100644 (file)
index 0000000..d3b4a2b
--- /dev/null
@@ -0,0 +1,35 @@
+@import 'mediawiki.mixins';
+@import 'mediawiki.ui/variables';
+
+.mw-rcfilters-ui-filterTagMultiselectWidget-mobile {
+
+       // Them mobile version of the search input is meant to function
+       // as a button, so styles are modified to that effect. See T224655 for details.
+       .oo-ui-tagMultiselectWidget-input {
+               & .oo-ui-iconElement-icon {
+                       opacity: 1;
+                       cursor: pointer;
+               }
+
+               &.oo-ui-textInputWidget input[ readonly ] {
+                       background-color: @background-color-base;
+                       font-weight: bold;
+                       cursor: pointer;
+                       .mixin-placeholder( { color: @colorText; } );
+               }
+       }
+
+       .mw-rcfilters-ui-filterTagMultiselectWidget-mobile-view {
+               width: 100%;
+               margin-top: -1px;
+
+               & .oo-ui-buttonOptionWidget {
+                       width: 50%;
+
+                       & .oo-ui-buttonElement-button {
+                               width: 100%;
+                               text-align: initial;
+                       }
+               }
+       }
+}
index 949980d..4e7d02d 100644 (file)
        }
 
        &-bottom {
-               .flex-display;
-               .flex;
+               .flex-display();
+               .flex();
+               flex-wrap: wrap;
                margin-top: 1em;
        }
+
+       &-bottom-mobile {
+               .oo-ui-buttonElement {
+                       margin-bottom: 1em;
+
+                       &-button {
+                               text-align: left;
+                       }
+               }
+
+               .mw-rcfilters-ui-changesLimitAndDateButtonWidget {
+                       order: 1;
+               }
+
+               .mw-rcfilters-ui-liveUpdateButtonWidget {
+                       order: 2;
+               }
+
+               .mw-rcfilters-ui-filterWrapperWidget-showNewChanges {
+                       order: 3;
+                       font-size: 0.85em;
+
+                       & > a {
+                               white-space: normal;
+                               /* stylelint-disable-next-line */
+                               padding-top: 0 !important; //overrides .oo-ui-buttonElement-button
+                       }
+               }
+       }
 }
index a0c0d80..ce869e3 100644 (file)
@@ -42,13 +42,14 @@ ChangesLimitPopupWidget = function MwRcfiltersUiChangesLimitPopupWidget( limitMo
                .addClass( 'mw-rcfilters-ui-changesLimitPopupWidget' )
                .append(
                        this.valuePicker.$element,
-                       new OO.ui.FieldLayout(
-                               this.groupByPageCheckbox,
-                               {
-                                       align: 'inline',
-                                       label: mw.msg( 'rcfilters-group-results-by-page' )
-                               }
-                       ).$element
+                       OO.ui.isMobile() ? undefined :
+                               new OO.ui.FieldLayout(
+                                       this.groupByPageCheckbox,
+                                       {
+                                               align: 'inline',
+                                               label: mw.msg( 'rcfilters-group-results-by-page' )
+                                       }
+                               ).$element
                );
 };
 
index 3429590..a50cd0e 100644 (file)
@@ -40,6 +40,7 @@ FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( c
        this.matchingQuery = null;
        this.currentView = this.model.getCurrentView();
        this.collapsed = false;
+       this.isMobile = config.isMobile;
 
        // Parent
        FilterTagMultiselectWidget.parent.call( this, $.extend( true, {
@@ -55,6 +56,8 @@ FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( c
                        filterFromInput: false,
                        hideWhenOutOfView: false,
                        hideOnChoose: false,
+                       // Only set width and footers for desktop
+                       isMobile: this.isMobile,
                        width: 650,
                        footers: [
                                {
@@ -81,9 +84,17 @@ FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( c
                                }
                        ]
                },
+               /**
+                * In the presence of an onscreen keyboard (i.e. isMobile) the filter input should act as a button
+                * rather than a text input. Mobile screens are too small to accommodate both an
+                * onscreen keyboard and a popup-menu, so readyOnly is set to disable the keyboard.
+                * A different icon and shorter message is used for mobile as well. (See T224655 for details).
+                */
                input: {
-                       icon: 'menu',
-                       placeholder: mw.msg( 'rcfilters-search-placeholder' )
+                       icon: this.isMobile ? 'funnel' : 'menu',
+                       placeholder: this.isMobile ? mw.msg( 'rcfilters-search-placeholder-mobile' ) : mw.msg( 'rcfilters-search-placeholder' ),
+                       readOnly: !!this.isMobile,
+                       classes: [ 'oo-ui-tagMultiselectWidget-input' ]
                }
        }, config ) );
 
@@ -148,11 +159,14 @@ FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( c
        this.model.connect( this, {
                initialize: 'onModelInitialize',
                update: 'onModelUpdate',
-               searchChange: 'onModelSearchChange',
+               searchChange: this.isMobile ? function () {} : 'onModelSearchChange',
                itemUpdate: 'onModelItemUpdate',
                highlightChange: 'onModelHighlightChange'
        } );
-       this.input.connect( this, { change: 'onInputChange' } );
+
+       if ( !this.isMobile ) {
+               this.input.connect( this, { change: 'onInputChange' } );
+       }
 
        // The filter list and button should appear side by side regardless of how
        // wide the button is; the button also changes its width depending
@@ -176,46 +190,10 @@ FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( c
        }
 
        // Add a selector at the right of the input
-       this.viewsSelectWidget = new OO.ui.ButtonSelectWidget( {
-               classes: [ 'mw-rcfilters-ui-filterTagMultiselectWidget-views-select-widget' ],
-               items: [
-                       new OO.ui.ButtonOptionWidget( {
-                               framed: false,
-                               data: 'namespaces',
-                               icon: 'article',
-                               label: mw.msg( 'namespaces' ),
-                               title: mw.msg( 'rcfilters-view-namespaces-tooltip' )
-                       } ),
-                       new OO.ui.ButtonOptionWidget( {
-                               framed: false,
-                               data: 'tags',
-                               icon: 'tag',
-                               label: mw.msg( 'tags-title' ),
-                               title: mw.msg( 'rcfilters-view-tags-tooltip' )
-                       } )
-               ]
-       } );
+       this.viewsSelectWidget = this.createViewsSelectWidget();
 
-       // Rearrange the UI so the select widget is at the right of the input
-       this.$element.append(
-               $( '<div>' )
-                       .addClass( 'mw-rcfilters-ui-table' )
-                       .append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-row' )
-                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views' )
-                                       .append(
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views-input' )
-                                                       .append( this.input.$element ),
-                                               $( '<div>' )
-                                                       .addClass( 'mw-rcfilters-ui-cell' )
-                                                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views-select' )
-                                                       .append( this.viewsSelectWidget.$element )
-                                       )
-                       )
-       );
+       // change the layout of the viewsSelectWidget
+       this.restructureViewsSelectWidget();
 
        // Event
        this.viewsSelectWidget.connect( this, { choose: 'onViewsSelectWidgetChoose' } );
@@ -258,6 +236,11 @@ FilterTagMultiselectWidget = function MwRcfiltersUiFilterTagMultiselectWidget( c
        this.$element
                .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget' );
 
+       if ( this.isMobile ) {
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-mobile' );
+       }
+
        this.reevaluateResetRestoreState();
 };
 
@@ -267,6 +250,78 @@ OO.inheritClass( FilterTagMultiselectWidget, OO.ui.MenuTagMultiselectWidget );
 
 /* Methods */
 
+/**
+ * Create a OOUI ButtonSelectWidget. The buttons are framed and have additional CSS
+ * classes applied on mobile.
+ * @return {OO.ui.ButtonSelectWidget}
+ */
+FilterTagMultiselectWidget.prototype.createViewsSelectWidget = function () {
+       return new OO.ui.ButtonSelectWidget( {
+               classes: this.isMobile ?
+                       [
+                               'mw-rcfilters-ui-table',
+                               'mw-rcfilters-ui-filterTagMultiselectWidget-mobile-view'
+                       ] :
+                       [
+                               'mw-rcfilters-ui-filterTagMultiselectWidget-views-select-widget'
+                       ],
+               items: [
+                       new OO.ui.ButtonOptionWidget( {
+                               framed: !!this.isMobile,
+                               data: 'namespaces',
+                               icon: 'article',
+                               label: mw.msg( 'namespaces' ),
+                               classes: this.isMobile ? [ 'mw-rcfilters-ui-cell' ] : []
+                       } ),
+                       new OO.ui.ButtonOptionWidget( {
+                               framed: !!this.isMobile,
+                               data: 'tags',
+                               icon: 'tag',
+                               label: mw.msg( 'tags-title' ),
+                               title: mw.msg( 'rcfilters-view-tags-tooltip' ),
+                               classes: this.isMobile ? [ 'mw-rcfilters-ui-cell' ] : []
+                       } )
+               ]
+       } );
+};
+
+/**
+ * Rearrange the DOM structure of the viewsSelectWiget so that on the namespace & tags buttons
+ * are at the right of the input on desktop, and below the input on mobile.
+ */
+FilterTagMultiselectWidget.prototype.restructureViewsSelectWidget = function () {
+       if ( this.isMobile ) {
+               // On mobile, append the search input and the extra buttons below the search input.
+               this.$element.append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views-input' )
+                               .append( this.input.$element )
+                               .append( this.viewsSelectWidget.$element )
+               );
+       } else {
+               // On desktop, rearrange the UI so the select widget is at the right of the input
+               this.$element.append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-table' )
+                               .append(
+                                       $( '<div>' )
+                                               .addClass( 'mw-rcfilters-ui-row' )
+                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views' )
+                                               .append(
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views-input' )
+                                                               .append( this.input.$element ),
+                                                       $( '<div>' )
+                                                               .addClass( 'mw-rcfilters-ui-cell' )
+                                                               .addClass( 'mw-rcfilters-ui-filterTagMultiselectWidget-views-select' )
+                                                               .append( this.viewsSelectWidget.$element )
+                                               )
+                               )
+               );
+       }
+};
+
 /**
  * Respond to view select widget choose event
  *
@@ -333,7 +388,9 @@ FilterTagMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {
        FilterTagMultiselectWidget.parent.prototype.onMenuToggle.call( this );
 
        if ( isVisible ) {
-               this.focus();
+               if ( !this.isMobile ) {
+                       this.focus();
+               }
 
                mw.hook( 'RcFilters.popup.open' ).fire();
 
@@ -360,21 +417,33 @@ FilterTagMultiselectWidget.prototype.onMenuToggle = function ( isVisible ) {
                this.blur();
        }
 
-       this.input.setIcon( isVisible ? 'search' : 'menu' );
+       if ( this.isMobile ) {
+               this.input.setIcon( isVisible ? 'close' : 'funnel' );
+       } else {
+               this.input.setIcon( isVisible ? 'search' : 'menu' );
+       }
 };
 
 /**
  * @inheritdoc
  */
 FilterTagMultiselectWidget.prototype.onInputFocus = function () {
-       // Parent
-       FilterTagMultiselectWidget.parent.prototype.onInputFocus.call( this );
+       var scrollToElement = this.isMobile ? this.input.$input : this.$element;
+
+       // treat the input as a menu toggle rather than a text field on mobile
+       if ( this.isMobile ) {
+               this.input.$input.trigger( 'blur' );
+               this.getMenu().toggle();
+       } else {
+               // Parent
+               FilterTagMultiselectWidget.parent.prototype.onInputFocus.call( this );
+       }
 
        // Only scroll to top of the viewport if:
        // - The widget is more than 20px from the top
        // - The widget is not above the top of the viewport (do not scroll downwards)
        //   (This isn't represented because >20 is, anyways and always, bigger than 0)
-       this.scrollToTop( this.$element, 0, { min: 20, max: Infinity } );
+       this.scrollToTop( scrollToElement, 0, { min: 20, max: Infinity } );
 };
 
 /**
@@ -525,7 +594,10 @@ FilterTagMultiselectWidget.prototype.onMenuChoose = function ( item ) {
        // Select the tag if it exists, or reset selection otherwise
        this.selectTag( this.findItemFromData( item.model.getName() ) );
 
-       this.focus();
+       if ( !this.isMobile ) {
+               this.focus();
+       }
+
 };
 
 /**
index a0f098c..5893a6c 100644 (file)
@@ -47,7 +47,8 @@ FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget(
                {
                        $overlay: this.$overlay,
                        collapsed: config.collapsed,
-                       $wrapper: this.$wrapper
+                       $wrapper: this.$wrapper,
+                       isMobile: OO.ui.isMobile()
                }
        );
 
@@ -82,7 +83,11 @@ FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget(
                .addClass( 'mw-rcfilters-ui-filterWrapperWidget-top' );
 
        $bottom = $( '<div>' )
-               .addClass( 'mw-rcfilters-ui-filterWrapperWidget-bottom' )
+               .addClass( OO.ui.isMobile() ?
+                       'mw-rcfilters-ui-filterWrapperWidget-bottom ' +
+                       'mw-rcfilters-ui-filterWrapperWidget-bottom-mobile' :
+                       'mw-rcfilters-ui-filterWrapperWidget-bottom'
+               )
                .append(
                        this.showNewChangesLink.$element,
                        this.numChangesAndDateWidget.$element
index 1e75020..465d5b9 100644 (file)
@@ -14,6 +14,8 @@ var FilterMenuHeaderWidget = require( './FilterMenuHeaderWidget.js' ),
  * @param {mw.rcfilters.Controller} controller Controller
  * @param {mw.rcfilters.dm.FiltersViewModel} model View model
  * @param {Object} [config] Configuration object
+ * @cfg {boolean} [isMobile] a boolean flag determining whether the menu
+ * should display a header or not (the header is omitted on mobile).
  * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
  * @cfg {Object[]} [footers] An array of objects defining the footers for
  *  this menu, with a definition whether they appear per specific views.
@@ -46,7 +48,7 @@ MenuSelectWidget = function MwRcfiltersUiMenuSelectWidget( controller, model, co
        // Parent
        MenuSelectWidget.parent.call( this, $.extend( config, {
                $autoCloseIgnore: this.$overlay,
-               width: 650,
+               width: config.isMobile ? undefined : 650,
                // Our filtering is done through the model
                filterFromInput: false
        } ) );
@@ -54,16 +56,21 @@ MenuSelectWidget = function MwRcfiltersUiMenuSelectWidget( controller, model, co
                $( '<div>' )
                        .addClass( 'mw-rcfilters-ui-menuSelectWidget-group' )
        );
-       this.setClippableElement( this.$body );
-       this.setClippableContainer( this.$element );
-
-       header = new FilterMenuHeaderWidget(
-               this.controller,
-               this.model,
-               {
-                       $overlay: this.$overlay
-               }
-       );
+
+       if ( !config.isMobile ) {
+               // When hiding the header (i.e. mobile mode) avoid problems
+               // with clippable and the menu's fixed width.
+               this.setClippableElement( this.$body );
+               this.setClippableContainer( this.$element );
+
+               header = new FilterMenuHeaderWidget(
+                       this.controller,
+                       this.model,
+                       {
+                               $overlay: this.$overlay
+                       }
+               );
+       }
 
        this.noResults = new OO.ui.LabelWidget( {
                label: mw.msg( 'rcfilters-filterlist-noresults' ),
@@ -79,7 +86,7 @@ MenuSelectWidget = function MwRcfiltersUiMenuSelectWidget( controller, model, co
        // Initialization
        this.$element
                .addClass( 'mw-rcfilters-ui-menuSelectWidget' )
-               .append( header.$element )
+               .append( config.isMobile ? undefined : header.$element )
                .append(
                        this.$body
                                .append( this.$group, this.noResults.$element )
@@ -87,7 +94,7 @@ MenuSelectWidget = function MwRcfiltersUiMenuSelectWidget( controller, model, co
 
        // Append all footers; we will control their visibility
        // based on view
-       config.footers = config.footers || [];
+       config.footers = config.isMobile ? [] : config.footers || [];
        config.footers.forEach( function ( footerData ) {
                var isSticky = footerData.sticky === undefined ? true : !!footerData.sticky,
                        adjustedData = {
index 395fb8b..c2c5960 100644 (file)
                                // Can't, sorry.
                        },
                        apiCheckValid: function () {
-                               var ok = this.getValue() !== null || suppressErrors;
-                               this.setIcon( ok ? null : 'alert' );
+                               var ok = this.getValue() !== null && this.getValue() !== undefined || suppressErrors;
+                               this.info.setIcon( ok ? null : 'alert' );
                                this.setTitle( ok ? '' : mw.message( 'apisandbox-alert-field' ).plain() );
                                return $.Deferred().resolve( ok ).promise();
                        }
index 65e7eb7..56419ae 100644 (file)
@@ -54,7 +54,7 @@
 
                // Events
                this.button.connect( this, { click: 'onButtonClick' } );
-               this.textInput.$input.on( 'click', this.onInputClick.bind( this ) );
+               this.textInput.$input.on( 'focus', this.onInputFocus.bind( this ) );
 
                this.$element.addClass( 'mw-widget-copyTextLayout' );
        };
        };
 
        /**
-        * Handle button click events
+        * Handle text widget focus events
         */
-       mw.widgets.CopyTextLayout.prototype.onInputClick = function () {
-               this.selectText();
+       mw.widgets.CopyTextLayout.prototype.onInputFocus = function () {
+               if ( !this.selecting ) {
+                       this.selectText();
+               }
        };
 
        /**
                        scrollTop = input.scrollTop,
                        scrollLeft = input.scrollLeft;
 
+               this.selecting = true;
                this.textInput.select();
+               this.selecting = false;
 
                // Restore scroll position
                input.scrollTop = scrollTop;
index dbb32e5..b0355b0 100644 (file)
                 *
                 * @property {mw.Map} config
                 */
-               // Dummy placeholder later assigned in ResourceLoaderStartUpModule
-               config: null,
+               config: new Map( $VARS.wgLegacyJavaScriptGlobals ),
 
                /**
                 * Empty object for third-party libraries, for cases where you don't
                                                }
 
                                                if (
+                                                       !$VARS.storeEnabled ||
+
                                                        // Disabled because localStorage quotas are tight and (in Firefox's case)
                                                        // shared by multiple origins.
                                                        // See T66721, and <https://bugzilla.mozilla.org/show_bug.cgi?id=1064466>.
-                                                       /Firefox/.test( navigator.userAgent ) ||
-
-                                                       // Disabled by configuration.
-                                                       !mw.config.get( 'wgResourceLoaderStorageEnabled' )
+                                                       /Firefox/.test( navigator.userAgent )
                                                ) {
                                                        // Clear any previous store to free up space. (T66721)
                                                        this.clear();
                                                        this.enabled = false;
                                                        return;
                                                }
-                                               if ( mw.config.get( 'debug' ) ) {
-                                                       // Disable module store in debug mode
-                                                       this.enabled = false;
-                                                       return;
-                                               }
 
                                                try {
                                                        // This a string we stored, or `null` if the key does not (yet) exist.
index da048ff..06c6737 100644 (file)
@@ -113,7 +113,6 @@ if ( !isCompatible( navigator.userAgent ) ) {
         */
        ( function () {
                /* global mw */
-               mw.config = new mw.Map( $VARS.wgLegacyJavaScriptGlobals );
 
                $CODE.registrations();
 
index ba85027..e3c20a2 100644 (file)
@@ -1302,7 +1302,7 @@ class ParserTestRunner {
        public function setupDatabase( $nextTeardown = null ) {
                global $wgDBprefix;
 
-               $this->db = wfGetDB( DB_MASTER );
+               $this->db = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( DB_MASTER );
                $dbType = $this->db->getType();
 
                if ( $dbType == 'oracle' ) {
index a79a139..ce3f2e2 100644 (file)
@@ -33,7 +33,7 @@ trait MediaWikiCoversValidator {
         */
        public function testValidCovers() {
                $methods = get_class_methods( $this );
-               $class = get_class( $this );
+               $class = static::class;
                $bad = '';
                foreach ( $methods as $method ) {
                        if ( strpos( $method, 'test' ) === 0 ) {
diff --git a/tests/phpunit/data/media/zip-comment-overflow.png b/tests/phpunit/data/media/zip-comment-overflow.png
new file mode 100644 (file)
index 0000000..710831f
Binary files /dev/null and b/tests/phpunit/data/media/zip-comment-overflow.png differ
diff --git a/tests/phpunit/data/media/zip-kind-of-valid-2.png b/tests/phpunit/data/media/zip-kind-of-valid-2.png
new file mode 100644 (file)
index 0000000..c0e7ff6
Binary files /dev/null and b/tests/phpunit/data/media/zip-kind-of-valid-2.png differ
diff --git a/tests/phpunit/data/media/zip-kind-of-valid.png b/tests/phpunit/data/media/zip-kind-of-valid.png
new file mode 100644 (file)
index 0000000..1121af4
Binary files /dev/null and b/tests/phpunit/data/media/zip-kind-of-valid.png differ
diff --git a/tests/phpunit/data/media/zip-sig-near-end.png b/tests/phpunit/data/media/zip-sig-near-end.png
new file mode 100644 (file)
index 0000000..29f3684
Binary files /dev/null and b/tests/phpunit/data/media/zip-sig-near-end.png differ
index 8a98217..8108639 100644 (file)
@@ -1161,7 +1161,7 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
                        'auto' => true,
                        'expiry' => 0
                ] );
-               $this->user->mBlock->mTimestamp = 0;
+               $this->user->mBlock->setTimestamp( 0 );
                $this->assertEquals( [ [ 'autoblockedtext',
                        "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
                        "\u{202A}Useruser\u{202C}", null, 'infinite', '127.0.8.1',
index 0648bfc..83872e3 100644 (file)
@@ -12,6 +12,8 @@ use MediaWiki\Revision\RevisionStore;
 use MediaWiki\Revision\SlotRoleRegistry;
 use MediaWiki\Revision\SlotRecord;
 use MediaWiki\Storage\SqlBlobStore;
+use Wikimedia\Rdbms\ILoadBalancer;
+use Wikimedia\Rdbms\MaintainableDBConnRef;
 use MediaWikiTestCase;
 use MWException;
 use Title;
@@ -77,6 +79,17 @@ class RevisionStoreTest extends MediaWikiTestCase {
                        ->disableOriginalConstructor()->getMock();
        }
 
+       /**
+        * @param ILoadBalancer $mockLoadBalancer
+        * @param Database $db
+        * @return callable
+        */
+       private function getMockDBConnRefCallback( ILoadBalancer $mockLoadBalancer, IDatabase $db ) {
+               return function ( $i, $g, $domain, $flg ) use ( $mockLoadBalancer, $db ) {
+                       return new MaintainableDBConnRef( $mockLoadBalancer, $db, $i );
+               };
+       }
+
        /**
         * @return \PHPUnit_Framework_MockObject_MockObject|SqlBlobStore
         */
@@ -158,10 +171,14 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $this->setService( 'DBLoadBalancer', $mockLoadBalancer );
 
                $db = $this->getMockDatabase();
-               // Title calls wfGetDB() which uses a regular Connection
+               // RevisionStore uses getConnectionRef
+               $mockLoadBalancer->expects( $this->any() )
+                       ->method( 'getConnectionRef' )
+                       ->willReturnCallback( $this->getMockDBConnRefCallback( $mockLoadBalancer, $db ) );
+               // Title calls wfGetDB() which uses getMaintenanceConnectionRef
                $mockLoadBalancer->expects( $this->atLeastOnce() )
-                       ->method( 'getConnection' )
-                       ->willReturn( $db );
+                       ->method( 'getMaintenanceConnectionRef' )
+                       ->willReturnCallback( $this->getMockDBConnRefCallback( $mockLoadBalancer, $db ) );
 
                // First call to Title::newFromID, faking no result (db lag?)
                $db->expects( $this->at( 0 ) )
@@ -192,15 +209,15 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $this->setService( 'DBLoadBalancer', $mockLoadBalancer );
 
                $db = $this->getMockDatabase();
-               // Title calls wfGetDB() which uses a regular Connection
+               // Title calls wfGetDB() which uses getMaintenanceConnectionRef
                // Assert that the first call uses a REPLICA and the second falls back to master
-               $mockLoadBalancer->expects( $this->exactly( 2 ) )
-                       ->method( 'getConnection' )
-                       ->willReturn( $db );
-               // RevisionStore getTitle uses a ConnectionRef
                $mockLoadBalancer->expects( $this->atLeastOnce() )
                        ->method( 'getConnectionRef' )
-                       ->willReturn( $db );
+                       ->willReturnCallback( $this->getMockDBConnRefCallback( $mockLoadBalancer, $db ) );
+               // Title calls wfGetDB() which uses getMaintenanceConnectionRef
+               $mockLoadBalancer->expects( $this->exactly( 2 ) )
+                       ->method( 'getMaintenanceConnectionRef' )
+                       ->willReturnCallback( $this->getMockDBConnRefCallback( $mockLoadBalancer, $db ) );
 
                // First call to Title::newFromID, faking no result (db lag?)
                $db->expects( $this->at( 0 ) )
@@ -251,14 +268,14 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $this->setService( 'DBLoadBalancer', $mockLoadBalancer );
 
                $db = $this->getMockDatabase();
-               // Title calls wfGetDB() which uses a regular Connection
-               $mockLoadBalancer->expects( $this->atLeastOnce() )
-                       ->method( 'getConnection' )
-                       ->willReturn( $db );
-               // RevisionStore getTitle uses a ConnectionRef
                $mockLoadBalancer->expects( $this->atLeastOnce() )
                        ->method( 'getConnectionRef' )
-                       ->willReturn( $db );
+                       ->willReturnCallback( $this->getMockDBConnRefCallback( $mockLoadBalancer, $db ) );
+               // Title calls wfGetDB() which uses getMaintenanceConnectionRef
+               // RevisionStore getTitle uses getMaintenanceConnectionRef
+               $mockLoadBalancer->expects( $this->atLeastOnce() )
+                       ->method( 'getMaintenanceConnectionRef' )
+                       ->willReturnCallback( $this->getMockDBConnRefCallback( $mockLoadBalancer, $db ) );
 
                // First call to Title::newFromID, faking no result (db lag?)
                $db->expects( $this->at( 0 ) )
@@ -299,15 +316,15 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $this->setService( 'DBLoadBalancer', $mockLoadBalancer );
 
                $db = $this->getMockDatabase();
-               // Title calls wfGetDB() which uses a regular Connection
                // Assert that the first call uses a REPLICA and the second falls back to master
-               $mockLoadBalancer->expects( $this->exactly( 2 ) )
-                       ->method( 'getConnection' )
-                       ->willReturn( $db );
-               // RevisionStore getTitle uses a ConnectionRef
+               // RevisionStore uses getMaintenanceConnectionRef
                $mockLoadBalancer->expects( $this->atLeastOnce() )
                        ->method( 'getConnectionRef' )
-                       ->willReturn( $db );
+                       ->willReturnCallback( $this->getMockDBConnRefCallback( $mockLoadBalancer, $db ) );
+               // Title calls wfGetDB() which uses getMaintenanceConnectionRef
+               $mockLoadBalancer->expects( $this->exactly( 2 ) )
+                       ->method( 'getMaintenanceConnectionRef' )
+                       ->willReturnCallback( $this->getMockDBConnRefCallback( $mockLoadBalancer, $db ) );
 
                // First call to Title::newFromID, faking no result (db lag?)
                $db->expects( $this->at( 0 ) )
@@ -368,12 +385,14 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $this->setService( 'DBLoadBalancer', $mockLoadBalancer );
 
                $db = $this->getMockDatabase();
-               // Title calls wfGetDB() which uses a regular Connection
+               // Title calls wfGetDB() which uses getMaintenanceConnectionRef
                // Assert that the first call uses a REPLICA and the second falls back to master
 
                // RevisionStore getTitle uses getConnectionRef
-               // Title::newFromID uses getConnection
-               foreach ( [ 'getConnection', 'getConnectionRef' ] as $method ) {
+               // Title::newFromID uses getMaintenanceConnectionRef
+               foreach ( [
+                       'getConnectionRef', 'getMaintenanceConnectionRef'
+               ] as $method ) {
                        $mockLoadBalancer->expects( $this->exactly( 2 ) )
                                ->method( $method )
                                ->willReturnCallback( function ( $masterOrReplica ) use ( $db ) {
index b8f60c4..f42777c 100644 (file)
@@ -160,27 +160,6 @@ class BlockManagerTest extends MediaWikiTestCase {
                ];
        }
 
-       /**
-        * @covers ::isLocallyBlockedProxy
-        */
-       public function testIsLocallyBlockedProxyDeprecated() {
-               $proxy = '1.2.3.4';
-
-               $this->hideDeprecated(
-                       'IP addresses in the keys of $wgProxyList (found the following IP ' .
-                       'addresses in keys: ' . $proxy . ', please move them to values)'
-               );
-
-               $blockManager = TestingAccessWrapper::newFromObject(
-                       $this->getBlockManager( [
-                               'wgProxyList' => [ $proxy => 'test' ]
-                       ] )
-               );
-
-               $ip = '1.2.3.4';
-               $this->assertTrue( $blockManager->isLocallyBlockedProxy( $ip ) );
-       }
-
        /**
         * @dataProvider provideIsDnsBlacklisted
         * @covers ::isDnsBlacklisted
index 0f23b8c..51ad915 100644 (file)
@@ -163,4 +163,40 @@ class MimeAnalyzerTest extends PHPUnit\Framework\TestCase {
                ];
        }
 
+       function providePngZipConfusion() {
+               return [
+                       [
+                               'An invalid ZIP file due to the signature being too close to the ' .
+                                       'end to accomodate an EOCDR',
+                               'zip-sig-near-end.png',
+                               'image/png',
+                       ],
+                       [
+                               'An invalid ZIP file due to the comment length running beyond the ' .
+                                       'end of the file',
+                               'zip-comment-overflow.png',
+                               'image/png',
+                       ],
+                       [
+                               'A ZIP file similar to the above, but without either of those two ' .
+                                       'problems. Not a valid ZIP file, but it passes MimeAnalyzer\'s ' .
+                                       'definition of a ZIP file. This is mostly a sanity check of the ' .
+                                       'above two tests.',
+                               'zip-kind-of-valid.png',
+                               'application/zip',
+                       ],
+                       [
+                               'As above with non-zero comment length',
+                               'zip-kind-of-valid-2.png',
+                               'application/zip',
+                       ],
+               ];
+       }
+
+       /** @dataProvider providePngZipConfusion */
+       function testPngZipConfusion( $description, $fileName, $expectedType ) {
+               $file = __DIR__ . '/../../../data/media/' . $fileName;
+               $actualType = $this->doGuessMimeType( [ $file, 'png' ] );
+               $this->assertEquals( $expectedType, $actualType, $description );
+       }
 }
index 522af43..4a56fc5 100644 (file)
@@ -113,6 +113,9 @@ class BagOStuffTest extends MediaWikiTestCase {
         * @covers MediumSpecificBagOStuff::changeTTL
         */
        public function testChangeTTL() {
+               $now = 1563892142;
+               $this->cache->setMockTime( $now );
+
                $key = $this->cache->makeKey( self::TEST_KEY );
                $value = 'meow';
 
@@ -126,7 +129,7 @@ class BagOStuffTest extends MediaWikiTestCase {
                $this->assertFalse( $this->cache->changeTTL( $key, 15 ) );
 
                $this->cache->add( $key, $value, 5 );
-               $this->assertTrue( $this->cache->changeTTL( $key, time() - 3600 ) );
+               $this->assertTrue( $this->cache->changeTTL( $key, $now - 3600 ) );
                $this->assertFalse( $this->cache->get( $key ) );
        }
 
@@ -134,6 +137,9 @@ class BagOStuffTest extends MediaWikiTestCase {
         * @covers MediumSpecificBagOStuff::changeTTLMulti
         */
        public function testChangeTTLMulti() {
+               $now = 1563892142;
+               $this->cache->setMockTime( $now );
+
                $key1 = $this->cache->makeKey( 'test-key1' );
                $key2 = $this->cache->makeKey( 'test-key2' );
                $key3 = $this->cache->makeKey( 'test-key3' );
@@ -166,7 +172,7 @@ class BagOStuffTest extends MediaWikiTestCase {
                $this->assertEquals( 2, $this->cache->get( $key2 ) );
                $this->assertEquals( 3, $this->cache->get( $key3 ) );
 
-               $ok = $this->cache->changeTTLMulti( [ $key1, $key2, $key3 ], time() + 86400 );
+               $ok = $this->cache->changeTTLMulti( [ $key1, $key2, $key3 ], $now + 86400 );
                $this->assertTrue( $ok, "Expiry set for all keys" );
 
                $ok = $this->cache->changeTTLMulti( [ $key1, $key2, $key3, $key4 ], 300 );
@@ -210,17 +216,28 @@ class BagOStuffTest extends MediaWikiTestCase {
         * @covers MediumSpecificBagOStuff::getWithSetCallback
         */
        public function testGetWithSetCallback() {
+               $now = 1563892142;
+               $this->cache->setMockTime( $now );
                $key = $this->cache->makeKey( self::TEST_KEY );
+
+               $this->assertFalse( $this->cache->get( $key ), "No value" );
+
                $value = $this->cache->getWithSetCallback(
                        $key,
                        30,
-                       function () {
+                       function ( &$ttl ) {
+                               $ttl = 10;
+
                                return 'hello kitty';
                        }
                );
 
                $this->assertEquals( 'hello kitty', $value );
-               $this->assertEquals( $value, $this->cache->get( $key ) );
+               $this->assertEquals( $value, $this->cache->get( $key ), "Value set" );
+
+               $now += 11;
+
+               $this->assertFalse( $this->cache->get( $key ), "Value expired" );
        }
 
        /**
index 9e4a5d7..329c642 100644 (file)
@@ -1070,7 +1070,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
         * @covers WANObjectCache::getWithSetCallback()
         * @covers WANObjectCache::fetchOrRegenerate()
         */
-       public function testBusyValue() {
+       public function testBusyValueBasic() {
                $cache = $this->cache;
                $key = wfRandomString();
                $value = wfRandomString();
@@ -1080,7 +1080,7 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $cache->setMockTime( $mockWallClock );
 
                $calls = 0;
-               $func = function () use ( &$calls, $value, $cache, $key ) {
+               $func = function () use ( &$calls, $value ) {
                        ++$calls;
                        return $value;
                };
@@ -1125,6 +1125,52 @@ class WANObjectCacheTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 3, $calls, 'Callback was not used; used interim' );
        }
 
+       public function getBusyValues_Provider() {
+               $hash = new HashBagOStuff( [] );
+
+               return [
+                       [
+                               function () {
+                                       return "Saint Oliver Plunckett";
+                               },
+                               'Saint Oliver Plunckett'
+                       ],
+                       [ 'strlen', 'strlen' ],
+                       [ 'WANObjectCache::newEmpty', 'WANObjectCache::newEmpty' ],
+                       [ [ 'WANObjectCache', 'newEmpty' ], [ 'WANObjectCache', 'newEmpty' ] ],
+                       [ [ $hash, 'getLastError' ], [ $hash, 'getLastError' ] ],
+                       [ [ 1, 2, 3 ], [ 1, 2, 3 ] ]
+               ];
+       }
+
+       /**
+        * @covers WANObjectCache::getWithSetCallback()
+        * @covers WANObjectCache::fetchOrRegenerate()
+        * @dataProvider getBusyValues_Provider
+        * @param mixed $busyValue
+        * @param mixed $expected
+        */
+       public function testBusyValueTypes( $busyValue, $expected ) {
+               $cache = $this->cache;
+               $key = wfRandomString();
+
+               $mockWallClock = 1549343530.2053;
+               $cache->setMockTime( $mockWallClock );
+
+               $calls = 0;
+               $func = function () use ( &$calls ) {
+                       ++$calls;
+                       return 418;
+               };
+
+               // Acquire a lock to verify that getWithSetCallback uses busyValue properly
+               $this->internalCache->add( 'WANCache:m:' . $key, 1, 0 );
+
+               $ret = $cache->getWithSetCallback( $key, 30, $func, [ 'busyValue' => $busyValue ] );
+               $this->assertSame( $expected, $ret, 'busyValue used as expected' );
+               $this->assertSame( 0, $calls, 'busyValue was used' );
+       }
+
        /**
         * @covers WANObjectCache::getMulti()
         */
index 482ab4b..a775dd7 100644 (file)
@@ -568,62 +568,74 @@ class DatabaseTest extends PHPUnit\Framework\TestCase {
        public function testFlagSetting() {
                $db = $this->db;
                $origTrx = $db->getFlag( DBO_TRX );
-               $origSsl = $db->getFlag( DBO_SSL );
+               $origNoBuffer = $db->getFlag( DBO_NOBUFFER );
 
                $origTrx
                        ? $db->clearFlag( DBO_TRX, $db::REMEMBER_PRIOR )
                        : $db->setFlag( DBO_TRX, $db::REMEMBER_PRIOR );
                $this->assertEquals( !$origTrx, $db->getFlag( DBO_TRX ) );
 
-               $origSsl
-                       ? $db->clearFlag( DBO_SSL, $db::REMEMBER_PRIOR )
-                       : $db->setFlag( DBO_SSL, $db::REMEMBER_PRIOR );
-               $this->assertEquals( !$origSsl, $db->getFlag( DBO_SSL ) );
+               $origNoBuffer
+                       ? $db->clearFlag( DBO_NOBUFFER, $db::REMEMBER_PRIOR )
+                       : $db->setFlag( DBO_NOBUFFER, $db::REMEMBER_PRIOR );
+               $this->assertEquals( !$origNoBuffer, $db->getFlag( DBO_NOBUFFER ) );
 
                $db->restoreFlags( $db::RESTORE_INITIAL );
                $this->assertEquals( $origTrx, $db->getFlag( DBO_TRX ) );
-               $this->assertEquals( $origSsl, $db->getFlag( DBO_SSL ) );
+               $this->assertEquals( $origNoBuffer, $db->getFlag( DBO_NOBUFFER ) );
 
                $origTrx
                        ? $db->clearFlag( DBO_TRX, $db::REMEMBER_PRIOR )
                        : $db->setFlag( DBO_TRX, $db::REMEMBER_PRIOR );
-               $origSsl
-                       ? $db->clearFlag( DBO_SSL, $db::REMEMBER_PRIOR )
-                       : $db->setFlag( DBO_SSL, $db::REMEMBER_PRIOR );
+               $origNoBuffer
+                       ? $db->clearFlag( DBO_NOBUFFER, $db::REMEMBER_PRIOR )
+                       : $db->setFlag( DBO_NOBUFFER, $db::REMEMBER_PRIOR );
 
                $db->restoreFlags();
-               $this->assertEquals( $origSsl, $db->getFlag( DBO_SSL ) );
+               $this->assertEquals( $origNoBuffer, $db->getFlag( DBO_NOBUFFER ) );
                $this->assertEquals( !$origTrx, $db->getFlag( DBO_TRX ) );
 
                $db->restoreFlags();
-               $this->assertEquals( $origSsl, $db->getFlag( DBO_SSL ) );
+               $this->assertEquals( $origNoBuffer, $db->getFlag( DBO_NOBUFFER ) );
                $this->assertEquals( $origTrx, $db->getFlag( DBO_TRX ) );
        }
 
+       public function provideImmutableDBOFlags() {
+               return [
+                       [ Database::DBO_IGNORE ],
+                       [ Database::DBO_DEFAULT ],
+                       [ Database::DBO_PERSISTENT ]
+               ];
+       }
+
        /**
-        * @expectedException UnexpectedValueException
+        * @expectedException DBUnexpectedError
         * @covers Wikimedia\Rdbms\Database::setFlag
+        * @dataProvider provideImmutableDBOFlags
+        * @param int $flag
         */
-       public function testDBOIgnoreSet() {
+       public function testDBOCannotSet( $flag ) {
                $db = $this->getMockBuilder( DatabaseMysqli::class )
                        ->disableOriginalConstructor()
                        ->setMethods( null )
                        ->getMock();
 
-               $db->setFlag( Database::DBO_IGNORE );
+               $db->setFlag( $flag );
        }
 
        /**
-        * @expectedException UnexpectedValueException
+        * @expectedException DBUnexpectedError
         * @covers Wikimedia\Rdbms\Database::clearFlag
+        * @dataProvider provideImmutableDBOFlags
+        * @param int $flag
         */
-       public function testDBOIgnoreClear() {
+       public function testDBOCannotClear( $flag ) {
                $db = $this->getMockBuilder( DatabaseMysqli::class )
                        ->disableOriginalConstructor()
                        ->setMethods( null )
                        ->getMock();
 
-               $db->clearFlag( Database::DBO_IGNORE );
+               $db->clearFlag( $flag );
        }
 
        /**
index b6f8f9c..71cf558 100644 (file)
@@ -331,6 +331,81 @@ class BlockLogFormatterTest extends LogFormatterTestCase {
         * @dataProvider provideSuppressBlockLogDatabaseRows
         */
        public function testSuppressBlockLogDatabaseRows( $row, $extra ) {
+               $this->setMwGlobals(
+                       'wgGroupPermissions',
+                       [
+                               'oversight' => [
+                                       'viewsuppressed' => true,
+                                       'suppressionlog' => true,
+                               ],
+                       ]
+               );
+               $this->doTestLogFormatter( $row, $extra, [ 'oversight' ] );
+       }
+
+       /**
+        * Provide different rows from the logging table to test
+        * for backward compatibility.
+        * Do not change the existing data, just add a new database row
+        */
+       public static function provideSuppressBlockLogDatabaseRowsNonPrivileged() {
+               return [
+                       // Current log format
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'block',
+                                       'comment' => 'Block comment',
+                                       'user' => 0,
+                                       'user_text' => 'Sysop',
+                                       'namespace' => NS_USER,
+                                       'title' => 'Logtestuser',
+                                       'params' => [
+                                               '5::duration' => 'infinite',
+                                               '6::flags' => 'anononly',
+                                       ],
+                               ],
+                               [
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [
+                                               'duration' => 'infinite',
+                                               'flags' => [ 'anononly' ],
+                                       ],
+                               ],
+                       ],
+
+                       // legacy log
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'block',
+                                       'comment' => 'Block comment',
+                                       'user' => 0,
+                                       'user_text' => 'Sysop',
+                                       'namespace' => NS_USER,
+                                       'title' => 'Logtestuser',
+                                       'params' => [
+                                               'infinite',
+                                               'anononly',
+                                       ],
+                               ],
+                               [
+                                       'legacy' => true,
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [
+                                               'duration' => 'infinite',
+                                               'flags' => [ 'anononly' ],
+                                       ],
+                               ],
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideSuppressBlockLogDatabaseRowsNonPrivileged
+        */
+       public function testSuppressBlockLogDatabaseRowsNonPrivileged( $row, $extra ) {
+               $this->user = $this->getTestUser()->getUser();
                $this->doTestLogFormatter( $row, $extra );
        }
 
@@ -398,6 +473,81 @@ class BlockLogFormatterTest extends LogFormatterTestCase {
         * @dataProvider provideSuppressReblockLogDatabaseRows
         */
        public function testSuppressReblockLogDatabaseRows( $row, $extra ) {
+               $this->setMwGlobals(
+                       'wgGroupPermissions',
+                       [
+                               'oversight' => [
+                                       'viewsuppressed' => true,
+                                       'suppressionlog' => true,
+                               ],
+                       ]
+               );
+               $this->doTestLogFormatter( $row, $extra, [ 'oversight' ] );
+       }
+
+       /**
+        * Provide different rows from the logging table to test
+        * for backward compatibility.
+        * Do not change the existing data, just add a new database row
+        */
+       public static function provideSuppressReblockLogDatabaseRowsNonPrivileged() {
+               return [
+                       // Current log format
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'reblock',
+                                       'comment' => 'Block comment',
+                                       'user' => 0,
+                                       'user_text' => 'Sysop',
+                                       'namespace' => NS_USER,
+                                       'title' => 'Logtestuser',
+                                       'params' => [
+                                               '5::duration' => 'infinite',
+                                               '6::flags' => 'anononly',
+                                       ],
+                               ],
+                               [
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [
+                                               'duration' => 'infinite',
+                                               'flags' => [ 'anononly' ],
+                                       ],
+                               ],
+                       ],
+
+                       // Legacy format
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'reblock',
+                                       'comment' => 'Block comment',
+                                       'user' => 0,
+                                       'user_text' => 'Sysop',
+                                       'namespace' => NS_USER,
+                                       'title' => 'Logtestuser',
+                                       'params' => [
+                                               'infinite',
+                                               'anononly',
+                                       ],
+                               ],
+                               [
+                                       'legacy' => true,
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [
+                                               'duration' => 'infinite',
+                                               'flags' => [ 'anononly' ],
+                                       ],
+                               ],
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideSuppressReblockLogDatabaseRowsNonPrivileged
+        */
+       public function testSuppressReblockLogDatabaseRowsNonPrivileged( $row, $extra ) {
+               $this->user = $this->getTestUser()->getUser();
                $this->doTestLogFormatter( $row, $extra );
        }
 
index 6648c31..f1d58fd 100644 (file)
@@ -409,6 +409,109 @@ class DeleteLogFormatterTest extends LogFormatterTestCase {
         * @dataProvider provideSuppressRevisionLogDatabaseRows
         */
        public function testSuppressRevisionLogDatabaseRows( $row, $extra ) {
+               $this->setMwGlobals(
+                       'wgGroupPermissions',
+                       [
+                               'oversight' => [
+                                       'viewsuppressed' => true,
+                                       'suppressionlog' => true,
+                               ],
+                       ]
+               );
+               $this->doTestLogFormatter( $row, $extra, [ 'oversight' ] );
+       }
+
+       /**
+        * Provide different rows from the logging table to test
+        * for backward compatibility.
+        * Do not change the existing data, just add a new database row
+        */
+       public static function provideSuppressRevisionLogDatabaseRowsNonPrivileged() {
+               return [
+                       // Current format
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'revision',
+                                       'comment' => 'Suppress comment',
+                                       'namespace' => NS_MAIN,
+                                       'title' => 'Page',
+                                       'params' => [
+                                               '4::type' => 'archive',
+                                               '5::ids' => [ '1', '3', '4' ],
+                                               '6::ofield' => '1',
+                                               '7::nfield' => '10',
+                                       ],
+                               ],
+                               [
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [
+                                               'type' => 'archive',
+                                               'ids' => [ '1', '3', '4' ],
+                                               'old' => [
+                                                       'bitmask' => 1,
+                                                       'content' => true,
+                                                       'comment' => false,
+                                                       'user' => false,
+                                                       'restricted' => false,
+                                               ],
+                                               'new' => [
+                                                       'bitmask' => 10,
+                                                       'content' => false,
+                                                       'comment' => true,
+                                                       'user' => false,
+                                                       'restricted' => true,
+                                               ],
+                                       ],
+                               ],
+                       ],
+
+                       // Legacy format
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'revision',
+                                       'comment' => 'Suppress comment',
+                                       'namespace' => NS_MAIN,
+                                       'title' => 'Page',
+                                       'params' => [
+                                               'archive',
+                                               '1,3,4',
+                                               'ofield=1',
+                                               'nfield=10',
+                                       ],
+                               ],
+                               [
+                                       'legacy' => true,
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [
+                                               'type' => 'archive',
+                                               'ids' => [ '1', '3', '4' ],
+                                               'old' => [
+                                                       'bitmask' => 1,
+                                                       'content' => true,
+                                                       'comment' => false,
+                                                       'user' => false,
+                                                       'restricted' => false,
+                                               ],
+                                               'new' => [
+                                                       'bitmask' => 10,
+                                                       'content' => false,
+                                                       'comment' => true,
+                                                       'user' => false,
+                                                       'restricted' => true,
+                                               ],
+                                       ],
+                               ],
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideSuppressRevisionLogDatabaseRowsNonPrivileged
+        */
+       public function testSuppressRevisionLogDatabaseRowsNonPrivileged( $row, $extra ) {
+               $this->user = $this->getTestUser()->getUser();
                $this->doTestLogFormatter( $row, $extra );
        }
 
@@ -523,6 +626,107 @@ class DeleteLogFormatterTest extends LogFormatterTestCase {
         * @dataProvider provideSuppressEventLogDatabaseRows
         */
        public function testSuppressEventLogDatabaseRows( $row, $extra ) {
+               $this->setMwGlobals(
+                       'wgGroupPermissions',
+                       [
+                               'oversight' => [
+                                       'viewsuppressed' => true,
+                                       'suppressionlog' => true,
+                               ],
+                       ]
+               );
+               $this->doTestLogFormatter( $row, $extra, [ 'oversight' ] );
+       }
+
+       /**
+        * Provide different rows from the logging table to test
+        * for backward compatibility.
+        * Do not change the existing data, just add a new database row
+        */
+       public static function provideSuppressEventLogDatabaseRowsNonPrivileged() {
+               return [
+                       // Current format
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'event',
+                                       'comment' => 'Suppress comment',
+                                       'namespace' => NS_MAIN,
+                                       'title' => 'Page',
+                                       'params' => [
+                                               '4::ids' => [ '1', '3', '4' ],
+                                               '5::ofield' => '1',
+                                               '6::nfield' => '10',
+                                       ],
+                               ],
+                               [
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [
+                                               'type' => 'logging',
+                                               'ids' => [ '1', '3', '4' ],
+                                               'old' => [
+                                                       'bitmask' => 1,
+                                                       'content' => true,
+                                                       'comment' => false,
+                                                       'user' => false,
+                                                       'restricted' => false,
+                                               ],
+                                               'new' => [
+                                                       'bitmask' => 10,
+                                                       'content' => false,
+                                                       'comment' => true,
+                                                       'user' => false,
+                                                       'restricted' => true,
+                                               ],
+                                       ],
+                               ],
+                       ],
+
+                       // Legacy format
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'event',
+                                       'comment' => 'Suppress comment',
+                                       'namespace' => NS_MAIN,
+                                       'title' => 'Page',
+                                       'params' => [
+                                               '1,3,4',
+                                               'ofield=1',
+                                               'nfield=10',
+                                       ],
+                               ],
+                               [
+                                       'legacy' => true,
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [
+                                               'type' => 'logging',
+                                               'ids' => [ '1', '3', '4' ],
+                                               'old' => [
+                                                       'bitmask' => 1,
+                                                       'content' => true,
+                                                       'comment' => false,
+                                                       'user' => false,
+                                                       'restricted' => false,
+                                               ],
+                                               'new' => [
+                                                       'bitmask' => 10,
+                                                       'content' => false,
+                                                       'comment' => true,
+                                                       'user' => false,
+                                                       'restricted' => true,
+                                               ],
+                                       ],
+                               ],
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideSuppressEventLogDatabaseRowsNonPrivileged
+        */
+       public function testSuppressEventLogDatabaseRowsNonPrivileged( $row, $extra ) {
+               $this->user = $this->getTestUser()->getUser();
                $this->doTestLogFormatter( $row, $extra );
        }
 
@@ -572,6 +776,65 @@ class DeleteLogFormatterTest extends LogFormatterTestCase {
         * @dataProvider provideSuppressDeleteLogDatabaseRows
         */
        public function testSuppressDeleteLogDatabaseRows( $row, $extra ) {
+               $this->setMwGlobals(
+                       'wgGroupPermissions',
+                       [
+                               'oversight' => [
+                                       'viewsuppressed' => true,
+                                       'suppressionlog' => true,
+                               ],
+                       ]
+               );
+               $this->doTestLogFormatter( $row, $extra, [ 'oversight' ] );
+       }
+
+       /**
+        * Provide different rows from the logging table to test
+        * for backward compatibility.
+        * Do not change the existing data, just add a new database row
+        */
+       public static function provideSuppressDeleteLogDatabaseRowsNonPrivileged() {
+               return [
+                       // Current format
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'delete',
+                                       'comment' => 'delete comment',
+                                       'namespace' => NS_MAIN,
+                                       'title' => 'Page',
+                                       'params' => [],
+                               ],
+                               [
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [],
+                               ],
+                       ],
+
+                       // Legacy format
+                       [
+                               [
+                                       'type' => 'suppress',
+                                       'action' => 'delete',
+                                       'comment' => 'delete comment',
+                                       'namespace' => NS_MAIN,
+                                       'title' => 'Page',
+                                       'params' => [],
+                               ],
+                               [
+                                       'legacy' => true,
+                                       'text' => '(username removed) (log details removed)',
+                                       'api' => [],
+                               ],
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideSuppressDeleteLogDatabaseRowsNonPrivileged
+        */
+       public function testSuppressDeleteLogDatabaseRowsNonPrivileged( $row, $extra ) {
+               $this->user = $this->getTestUser()->getUser();
                $this->doTestLogFormatter( $row, $extra );
        }
 }
index fc2ab91..a24065e 100644 (file)
@@ -6,11 +6,15 @@ use MediaWiki\Linker\LinkTarget;
  */
 abstract class LogFormatterTestCase extends MediaWikiLangTestCase {
 
-       public function doTestLogFormatter( $row, $extra ) {
+       public function doTestLogFormatter( $row, $extra, $userGroups = [] ) {
                RequestContext::resetMain();
                $row = $this->expandDatabaseRow( $row, $this->isLegacy( $extra ) );
 
+               $context = new RequestContext();
+               $context->setUser( $this->getTestUser( $userGroups )->getUser() );
+
                $formatter = LogFormatter::newFromRow( $row );
+               $formatter->setContext( $context );
 
                $this->assertEquals(
                        $extra['text'],
diff --git a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php
deleted file mode 100644 (file)
index c84efa1..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-<?php
-
-/**
- * @group Media
- * @covers SVGMetadataExtractor
- */
-class SVGMetadataExtractorTest extends \MediaWikiIntegrationTestCase {
-
-       /**
-        * @dataProvider provideSvgFiles
-        */
-       public function testGetMetadata( $infile, $expected ) {
-               $this->assertMetadata( $infile, $expected );
-       }
-
-       /**
-        * @dataProvider provideSvgFilesWithXMLMetadata
-        */
-       public function testGetXMLMetadata( $infile, $expected ) {
-               $r = new XMLReader();
-               $this->assertMetadata( $infile, $expected );
-       }
-
-       /**
-        * @dataProvider provideSvgUnits
-        */
-       public function testScaleSVGUnit( $inUnit, $expected ) {
-               $this->assertEquals(
-                       $expected,
-                       SVGReader::scaleSVGUnit( $inUnit ),
-                       'SVG unit conversion and scaling failure'
-               );
-       }
-
-       function assertMetadata( $infile, $expected ) {
-               try {
-                       $data = SVGMetadataExtractor::getMetadata( $infile );
-                       $this->assertEquals( $expected, $data, 'SVG metadata extraction test' );
-               } catch ( MWException $e ) {
-                       if ( $expected === false ) {
-                               $this->assertTrue( true, 'SVG metadata extracted test (expected failure)' );
-                       } else {
-                               throw $e;
-                       }
-               }
-       }
-
-       public static function provideSvgFiles() {
-               $base = __DIR__ . '/../../data/media';
-
-               return [
-                       [
-                               "$base/Wikimedia-logo.svg",
-                               [
-                                       'width' => 1024,
-                                       'height' => 1024,
-                                       'originalWidth' => '1024',
-                                       'originalHeight' => '1024',
-                                       'translations' => [],
-                               ]
-                       ],
-                       [
-                               "$base/QA_icon.svg",
-                               [
-                                       'width' => 60,
-                                       'height' => 60,
-                                       'originalWidth' => '60',
-                                       'originalHeight' => '60',
-                                       'translations' => [],
-                               ]
-                       ],
-                       [
-                               "$base/Gtk-media-play-ltr.svg",
-                               [
-                                       'width' => 60,
-                                       'height' => 60,
-                                       'originalWidth' => '60.0000000',
-                                       'originalHeight' => '60.0000000',
-                                       'translations' => [],
-                               ]
-                       ],
-                       [
-                               "$base/Toll_Texas_1.svg",
-                               // This file triggered T33719, needs entity expansion in the xmlns checks
-                               [
-                                       'width' => 385,
-                                       'height' => 385,
-                                       'originalWidth' => '385',
-                                       'originalHeight' => '385.0004883',
-                                       'translations' => [],
-                               ]
-                       ],
-                       [
-                               "$base/Tux.svg",
-                               [
-                                       'width' => 512,
-                                       'height' => 594,
-                                       'originalWidth' => '100%',
-                                       'originalHeight' => '100%',
-                                       'title' => 'Tux',
-                                       'translations' => [],
-                                       'description' => 'For more information see: http://commons.wikimedia.org/wiki/Image:Tux.svg',
-                               ]
-                       ],
-                       [
-                               "$base/Speech_bubbles.svg",
-                               [
-                                       'width' => 627,
-                                       'height' => 461,
-                                       'originalWidth' => '17.7cm',
-                                       'originalHeight' => '13cm',
-                                       'translations' => [
-                                               'de' => SVGReader::LANG_FULL_MATCH,
-                                               'fr' => SVGReader::LANG_FULL_MATCH,
-                                               'nl' => SVGReader::LANG_FULL_MATCH,
-                                               'tlh-ca' => SVGReader::LANG_FULL_MATCH,
-                                               'tlh' => SVGReader::LANG_PREFIX_MATCH
-                                       ],
-                               ]
-                       ],
-                       [
-                               "$base/Soccer_ball_animated.svg",
-                               [
-                                       'width' => 150,
-                                       'height' => 150,
-                                       'originalWidth' => '150',
-                                       'originalHeight' => '150',
-                                       'animated' => true,
-                                       'translations' => []
-                               ],
-                       ],
-                       [
-                               "$base/comma_separated_viewbox.svg",
-                               [
-                                       'width' => 512,
-                                       'height' => 594,
-                                       'originalWidth' => '100%',
-                                       'originalHeight' => '100%',
-                                       'translations' => []
-                               ],
-                       ],
-               ];
-       }
-
-       public static function provideSvgFilesWithXMLMetadata() {
-               $base = __DIR__ . '/../../data/media';
-               // phpcs:disable Generic.Files.LineLength
-               $metadata = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-      <ns4:Work xmlns:ns4="http://creativecommons.org/ns#" rdf:about="">
-        <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format>
-        <ns5:type xmlns:ns5="http://purl.org/dc/elements/1.1/" rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-      </ns4:Work>
-    </rdf:RDF>';
-               // phpcs:enable
-
-               $metadata = str_replace( "\r", '', $metadata ); // Windows compat
-               return [
-                       [
-                               "$base/US_states_by_total_state_tax_revenue.svg",
-                               [
-                                       'height' => 593,
-                                       'metadata' => $metadata,
-                                       'width' => 959,
-                                       'originalWidth' => '958.69',
-                                       'originalHeight' => '592.78998',
-                                       'translations' => [],
-                               ]
-                       ],
-               ];
-       }
-
-       public static function provideSvgUnits() {
-               return [
-                       [ '1' , 1 ],
-                       [ '1.1' , 1.1 ],
-                       [ '0.1' , 0.1 ],
-                       [ '.1' , 0.1 ],
-                       [ '1e2' , 100 ],
-                       [ '1E2' , 100 ],
-                       [ '+1' , 1 ],
-                       [ '-1' , -1 ],
-                       [ '-1.1' , -1.1 ],
-                       [ '1e+2' , 100 ],
-                       [ '1e-2' , 0.01 ],
-                       [ '10px' , 10 ],
-                       [ '10pt' , 10 * 1.25 ],
-                       [ '10pc' , 10 * 15 ],
-                       [ '10mm' , 10 * 3.543307 ],
-                       [ '10cm' , 10 * 35.43307 ],
-                       [ '10in' , 10 * 90 ],
-                       [ '10em' , 10 * 16 ],
-                       [ '10ex' , 10 * 12 ],
-                       [ '10%' , 51.2 ],
-                       [ '10 px' , 10 ],
-                       // Invalid values
-                       [ '1e1.1', 10 ],
-                       [ '10bp', 10 ],
-                       [ 'p10', null ],
-               ];
-       }
-}
diff --git a/tests/phpunit/includes/media/SVGReaderTest.php b/tests/phpunit/includes/media/SVGReaderTest.php
new file mode 100644 (file)
index 0000000..7063a57
--- /dev/null
@@ -0,0 +1,203 @@
+<?php
+
+/**
+ * @group Media
+ * @covers SVGReader
+ */
+class SVGReaderTest extends \MediaWikiIntegrationTestCase {
+
+       /**
+        * @dataProvider provideSvgFiles
+        */
+       public function testGetMetadata( $infile, $expected ) {
+               $this->assertMetadata( $infile, $expected );
+       }
+
+       /**
+        * @dataProvider provideSvgFilesWithXMLMetadata
+        */
+       public function testGetXMLMetadata( $infile, $expected ) {
+               $r = new XMLReader();
+               $this->assertMetadata( $infile, $expected );
+       }
+
+       /**
+        * @dataProvider provideSvgUnits
+        */
+       public function testScaleSVGUnit( $inUnit, $expected ) {
+               $this->assertEquals(
+                       $expected,
+                       SVGReader::scaleSVGUnit( $inUnit ),
+                       'SVG unit conversion and scaling failure'
+               );
+       }
+
+       function assertMetadata( $infile, $expected ) {
+               try {
+                       $svgReader = new SVGReader( $infile );
+                       $data = $svgReader->getMetadata();
+
+                       $this->assertEquals( $expected, $data, 'SVG metadata extraction test' );
+               } catch ( MWException $e ) {
+                       if ( $expected === false ) {
+                               $this->assertTrue( true, 'SVG metadata extracted test (expected failure)' );
+                       } else {
+                               throw $e;
+                       }
+               }
+       }
+
+       public static function provideSvgFiles() {
+               $base = __DIR__ . '/../../data/media';
+
+               return [
+                       [
+                               "$base/Wikimedia-logo.svg",
+                               [
+                                       'width' => 1024,
+                                       'height' => 1024,
+                                       'originalWidth' => '1024',
+                                       'originalHeight' => '1024',
+                                       'translations' => [],
+                               ]
+                       ],
+                       [
+                               "$base/QA_icon.svg",
+                               [
+                                       'width' => 60,
+                                       'height' => 60,
+                                       'originalWidth' => '60',
+                                       'originalHeight' => '60',
+                                       'translations' => [],
+                               ]
+                       ],
+                       [
+                               "$base/Gtk-media-play-ltr.svg",
+                               [
+                                       'width' => 60,
+                                       'height' => 60,
+                                       'originalWidth' => '60.0000000',
+                                       'originalHeight' => '60.0000000',
+                                       'translations' => [],
+                               ]
+                       ],
+                       [
+                               "$base/Toll_Texas_1.svg",
+                               // This file triggered T33719, needs entity expansion in the xmlns checks
+                               [
+                                       'width' => 385,
+                                       'height' => 385,
+                                       'originalWidth' => '385',
+                                       'originalHeight' => '385.0004883',
+                                       'translations' => [],
+                               ]
+                       ],
+                       [
+                               "$base/Tux.svg",
+                               [
+                                       'width' => 512,
+                                       'height' => 594,
+                                       'originalWidth' => '100%',
+                                       'originalHeight' => '100%',
+                                       'title' => 'Tux',
+                                       'translations' => [],
+                                       'description' => 'For more information see: http://commons.wikimedia.org/wiki/Image:Tux.svg',
+                               ]
+                       ],
+                       [
+                               "$base/Speech_bubbles.svg",
+                               [
+                                       'width' => 627,
+                                       'height' => 461,
+                                       'originalWidth' => '17.7cm',
+                                       'originalHeight' => '13cm',
+                                       'translations' => [
+                                               'de' => SVGReader::LANG_FULL_MATCH,
+                                               'fr' => SVGReader::LANG_FULL_MATCH,
+                                               'nl' => SVGReader::LANG_FULL_MATCH,
+                                               'tlh-ca' => SVGReader::LANG_FULL_MATCH,
+                                               'tlh' => SVGReader::LANG_PREFIX_MATCH
+                                       ],
+                               ]
+                       ],
+                       [
+                               "$base/Soccer_ball_animated.svg",
+                               [
+                                       'width' => 150,
+                                       'height' => 150,
+                                       'originalWidth' => '150',
+                                       'originalHeight' => '150',
+                                       'animated' => true,
+                                       'translations' => []
+                               ],
+                       ],
+                       [
+                               "$base/comma_separated_viewbox.svg",
+                               [
+                                       'width' => 512,
+                                       'height' => 594,
+                                       'originalWidth' => '100%',
+                                       'originalHeight' => '100%',
+                                       'translations' => []
+                               ],
+                       ],
+               ];
+       }
+
+       public static function provideSvgFilesWithXMLMetadata() {
+               $base = __DIR__ . '/../../data/media';
+               // phpcs:disable Generic.Files.LineLength
+               $metadata = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+      <ns4:Work xmlns:ns4="http://creativecommons.org/ns#" rdf:about="">
+        <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format>
+        <ns5:type xmlns:ns5="http://purl.org/dc/elements/1.1/" rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+      </ns4:Work>
+    </rdf:RDF>';
+               // phpcs:enable
+
+               $metadata = str_replace( "\r", '', $metadata ); // Windows compat
+               return [
+                       [
+                               "$base/US_states_by_total_state_tax_revenue.svg",
+                               [
+                                       'height' => 593,
+                                       'metadata' => $metadata,
+                                       'width' => 959,
+                                       'originalWidth' => '958.69',
+                                       'originalHeight' => '592.78998',
+                                       'translations' => [],
+                               ]
+                       ],
+               ];
+       }
+
+       public static function provideSvgUnits() {
+               return [
+                       [ '1' , 1 ],
+                       [ '1.1' , 1.1 ],
+                       [ '0.1' , 0.1 ],
+                       [ '.1' , 0.1 ],
+                       [ '1e2' , 100 ],
+                       [ '1E2' , 100 ],
+                       [ '+1' , 1 ],
+                       [ '-1' , -1 ],
+                       [ '-1.1' , -1.1 ],
+                       [ '1e+2' , 100 ],
+                       [ '1e-2' , 0.01 ],
+                       [ '10px' , 10 ],
+                       [ '10pt' , 10 * 1.25 ],
+                       [ '10pc' , 10 * 15 ],
+                       [ '10mm' , 10 * 3.543307 ],
+                       [ '10cm' , 10 * 35.43307 ],
+                       [ '10in' , 10 * 90 ],
+                       [ '10em' , 10 * 16 ],
+                       [ '10ex' , 10 * 12 ],
+                       [ '10%' , 51.2 ],
+                       [ '10 px' , 10 ],
+                       // Invalid values
+                       [ '1e1.1', 10 ],
+                       [ '10bp', 10 ],
+                       [ 'p10', null ],
+               ];
+       }
+}
index 34ddb1f..ec60383 100644 (file)
@@ -939,4 +939,24 @@ EOF
                $this->assertSame( $time, $po->getCacheTime() );
        }
 
+       public static function provideOldSerialized() {
+               return [
+                       // phpcs:ignore Generic.Files.LineLength
+                       '1.34.0-wmf.15' => [ 'O:12:"ParserOutput":43:{s:5:"mText";s:0:"";s:14:"mLanguageLinks";a:0:{}s:11:"mCategories";a:0:{}s:11:"mIndicators";a:0:{}s:10:"mTitleText";s:0:"";s:6:"mLinks";a:0:{}s:10:"mTemplates";a:0:{}s:12:"mTemplateIds";a:0:{}s:7:"mImages";a:0:{}s:18:"mFileSearchOptions";a:0:{}s:14:"mExternalLinks";a:0:{}s:15:"mInterwikiLinks";a:0:{}s:11:"mNewSection";b:0;s:15:"mHideNewSection";b:0;s:10:"mNoGallery";b:0;s:10:"mHeadItems";a:0:{}s:8:"mModules";a:0:{}s:13:"mModuleStyles";a:0:{}s:13:"mJsConfigVars";a:0:{}s:12:"mOutputHooks";a:0:{}s:9:"mWarnings";a:0:{}s:9:"mSections";a:0:{}s:11:"mProperties";a:0:{}s:8:"mTOCHTML";s:0:"";s:10:"mTimestamp";N;s:11:"mEnableOOUI";b:0;s:26:"\\000ParserOutput\\000mIndexPolicy";s:0:"";s:30:"\\000ParserOutput\\000mAccessedOptions";a:0:{}s:28:"\\000ParserOutput\\000mExtensionData";a:0:{}s:30:"\\000ParserOutput\\000mLimitReportData";a:0:{}s:32:"\\000ParserOutput\\000mLimitReportJSData";a:0:{}s:34:"\\000ParserOutput\\000mPreventClickjacking";b:0;s:20:"\\000ParserOutput\\000mFlags";a:0:{}s:31:"\\000ParserOutput\\000mSpeculativeRevId";N;s:35:"\\000ParserOutput\\000revisionTimestampUsed";N;s:36:"\\000ParserOutput\\000revisionUsedSha1Base36";N;s:32:"\\000ParserOutput\\000mWrapperDivClasses";a:0:{}s:32:"\\000ParserOutput\\000mMaxAdaptiveExpiry";d:INF;s:12:"mUsedOptions";N;s:8:"mVersion";s:5:"1.6.4";s:10:"mCacheTime";s:0:"";s:12:"mCacheExpiry";N;s:16:"mCacheRevisionId";N;}' ]
+               ];
+       }
+
+       /**
+        * Ensure that old ParserOutput objects can be unserialized and reserialized without an error
+        * (T229366).
+        *
+        * @dataProvider provideOldSerialized
+        * @covers ParserOutput::__sleep()
+        */
+       public function testOldSerialized( $serialized ) {
+               $po = unserialize( stripcslashes( $serialized ) );
+               $reserialized = serialize( $po );
+               $this->assertStringStartsWith( 'O:', $reserialized );
+       }
+
 }
index 5964915..089431e 100644 (file)
@@ -311,37 +311,41 @@ class ResourceLoaderWikiModuleTest extends ResourceLoaderTestCase {
 
        public static function provideGetContent() {
                yield 'Bad title' => [ null, '[x]' ];
-               yield 'Dead redirect' => [ null, [
-                       'text' => 'Dead redirect',
-                       'title' => 'Dead_redirect',
-                       'redirect' => 1,
-               ] ];
-               yield 'Bad content model' => [ null, [
-                       'text' => 'MediaWiki:Wikitext',
-                       'ns' => NS_MEDIAWIKI,
-                       'title' => 'Wikitext',
-               ] ];
+
                yield 'No JS content found' => [ null, [
-                       'text' => 'MediaWiki:Script.js',
+                       'text' => 'MediaWiki:Foo.js',
                        'ns' => NS_MEDIAWIKI,
-                       'title' => 'Script.js',
+                       'title' => 'Foo.js',
                ] ];
-               yield 'No CSS content found' => [ null, [
-                       'text' => 'MediaWiki:Styles.css',
+
+               yield 'JS content' => [ 'code;', [
+                       'text' => 'MediaWiki:Foo.js',
                        'ns' => NS_MEDIAWIKI,
-                       'title' => 'Script.css',
-               ] ];
+                       'title' => 'Foo.js',
+               ], new JavaScriptContent( 'code;' ) ];
+
+               yield 'CSS content' => [ 'code {}', [
+                       'text' => 'MediaWiki:Foo.css',
+                       'ns' => NS_MEDIAWIKI,
+                       'title' => 'Foo.css',
+               ], new CssContent( 'code {}' ) ];
+
+               yield 'Wikitext content' => [ null, [
+                       'text' => 'MediaWiki:Foo',
+                       'ns' => NS_MEDIAWIKI,
+                       'title' => 'Foo',
+               ], new WikitextContent( 'code;' ) ];
        }
 
        /**
         * @dataProvider provideGetContent
         */
-       public function testGetContent( $expected, $title ) {
+       public function testGetContent( $expected, $title, Content $contentObj = null ) {
                $context = $this->getResourceLoaderContext( [], new EmptyResourceLoader );
                $module = $this->getMockBuilder( ResourceLoaderWikiModule::class )
                        ->setMethods( [ 'getContentObj' ] )->getMock();
                $module->method( 'getContentObj' )
-                       ->willReturn( null );
+                       ->willReturn( $contentObj );
 
                if ( is_array( $title ) ) {
                        $title += [ 'ns' => NS_MAIN, 'id' => 1, 'len' => 1, 'redirect' => 0 ];
index 774e023..e9efb22 100644 (file)
@@ -3,8 +3,8 @@
 class SearchResultSetTest extends MediaWikiTestCase {
        /**
         * @covers SearchResultSet::getIterator
-        * @covers SearchResultSet::next
-        * @covers SearchResultSet::rewind
+        * @covers BaseSearchResultSet::next
+        * @covers BaseSearchResultSet::rewind
         */
        public function testIterate() {
                $result = SearchResult::newFromTitle( Title::newMainPage() );
@@ -17,8 +17,8 @@ class SearchResultSetTest extends MediaWikiTestCase {
                }
                $this->assertEquals( 1, $count );
 
-               $this->hideDeprecated( 'SearchResultSet::rewind' );
-               $this->hideDeprecated( 'SearchResultSet::next' );
+               $this->hideDeprecated( 'BaseSearchResultSet::rewind' );
+               $this->hideDeprecated( 'BaseSearchResultSet::next' );
                $resultSet->rewind();
                $count = 0;
                while ( ( $iterResult = $resultSet->next() ) !== false ) {
@@ -29,8 +29,8 @@ class SearchResultSetTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers SearchResultSet::augmentResult
-        * @covers SearchResultSet::setAugmentedData
+        * @covers SearchResultSetTrait::augmentResult
+        * @covers SearchResultSetTrait::setAugmentedData
         */
        public function testDelayedResultAugment() {
                $result = SearchResult::newFromTitle( Title::newMainPage() );
index bb72315..62e8e23 100644 (file)
@@ -1021,18 +1021,6 @@ class UserTest extends MediaWikiTestCase {
                        ]
                );
                $this->assertTrue( User::isLocallyBlockedProxy( $ip ) );
-
-               $this->hideDeprecated(
-                       'IP addresses in the keys of $wgProxyList (found the following IP ' .
-                       'addresses in keys: ' . $blockListEntry . ', please move them to values)'
-               );
-               $this->setMwGlobals(
-                       'wgProxyList',
-                       [
-                               $blockListEntry => 'test'
-                       ]
-               );
-               $this->assertTrue( User::isLocallyBlockedProxy( $ip ) );
        }
 
        /**
index 28547d1..f318df1 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
 use Wikimedia\ScopedCallback;
 
 /**
@@ -137,7 +138,8 @@ class ParserTestTopLevelSuite extends PHPUnit_Framework_TestSuite {
        public function setUp() {
                wfDebug( __METHOD__ );
 
-               $db = wfGetDB( DB_MASTER );
+               $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
+               $db = $lb->getConnection( DB_MASTER );
                $type = $db->getType();
                $prefix = $type === 'oracle' ?
                        MediaWikiTestCase::ORA_DB_PREFIX : MediaWikiTestCase::DB_PREFIX;