Merge "Add SkinTemplateGetLanguageLink hook"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 6 Feb 2014 15:26:56 +0000 (15:26 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 6 Feb 2014 15:26:56 +0000 (15:26 +0000)
186 files changed:
CREDITS
HISTORY
INSTALL
RELEASE-NOTES-1.23
UPGRADE
docs/database.txt
docs/design.txt
docs/distributors.txt
docs/language.txt
docs/magicword.txt
docs/schema.txt
docs/scripts.txt
docs/skin.txt
includes/AjaxResponse.php
includes/AutoLoader.php
includes/DefaultSettings.php
includes/EditPage.php
includes/Exception.php
includes/GlobalFunctions.php
includes/OutputPage.php
includes/Preferences.php
includes/QueryPage.php
includes/Setup.php
includes/SquidPurgeClient.php
includes/User.php
includes/WikiPage.php
includes/actions/RawAction.php
includes/api/ApiBase.php
includes/api/ApiMain.php
includes/api/ApiOptions.php
includes/api/ApiPageSet.php
includes/api/ApiProtect.php
includes/api/ApiPurge.php
includes/api/ApiQueryAllCategories.php
includes/api/ApiQueryAllLinks.php
includes/api/ApiQueryAllPages.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryContributors.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryFileRepoInfo.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryUserContributions.php
includes/api/ApiRevisionDelete.php [new file with mode: 0644]
includes/api/ApiWatch.php
includes/cache/HTMLFileCache.php
includes/cache/LocalisationCache.php
includes/changes/ChangesList.php
includes/changes/OldChangesList.php
includes/changes/RCCacheEntry.php
includes/clientpool/RedisConnectionPool.php
includes/config/Config.php
includes/config/GlobalConfig.php
includes/content/WikitextContent.php
includes/context/RequestContext.php
includes/db/Database.php
includes/db/DatabaseMssql.php
includes/db/DatabaseMysqlBase.php
includes/db/DatabaseMysqli.php
includes/db/DatabasePostgres.php
includes/db/LoadBalancer.php
includes/debug/Debug.php
includes/deferred/LinksUpdate.php
includes/deferred/SquidUpdate.php
includes/diff/DifferenceEngine.php
includes/externalstore/ExternalStoreDB.php
includes/filebackend/FSFile.php
includes/filebackend/FileBackend.php
includes/filebackend/FileBackendMultiWrite.php
includes/filebackend/FileBackendStore.php
includes/filebackend/FileOpBatch.php
includes/filebackend/MemoryFileBackend.php
includes/filebackend/SwiftFileBackend.php
includes/filebackend/lockmanager/QuorumLockManager.php
includes/filerepo/FileRepo.php
includes/filerepo/ForeignAPIRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/RepoGroup.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/File.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/UnregisteredLocalFile.php
includes/gallery/ImageGalleryBase.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/installer/Installer.php
includes/installer/LocalSettingsGenerator.php
includes/installer/MysqlUpdater.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/installer/WebInstallerPage.php
includes/job/JobQueueRedis.php
includes/logging/LogFormatter.php
includes/media/Exif.php
includes/objectcache/RedisBagOStuff.php
includes/resourceloader/ResourceLoader.php
includes/revisiondelete/RevisionDelete.php
includes/revisiondelete/RevisionDeleteAbstracts.php
includes/search/SearchEngine.php
includes/specialpage/SpecialPageFactory.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialJavaScriptTest.php
includes/specials/SpecialPasswordReset.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialSearch.php
includes/upload/UploadFromChunks.php
languages/messages/MessagesAr.php
languages/messages/MessagesArc.php
languages/messages/MessagesAst.php
languages/messages/MessagesBe_tarask.php
languages/messages/MessagesBn.php
languages/messages/MessagesBr.php
languages/messages/MessagesCa.php
languages/messages/MessagesCe.php
languages/messages/MessagesCs.php
languages/messages/MessagesDa.php
languages/messages/MessagesDe.php
languages/messages/MessagesDiq.php
languages/messages/MessagesEgl.php
languages/messages/MessagesEl.php
languages/messages/MessagesEn.php
languages/messages/MessagesEt.php
languages/messages/MessagesFa.php
languages/messages/MessagesFr.php
languages/messages/MessagesFrr.php
languages/messages/MessagesGl.php
languages/messages/MessagesGv.php
languages/messages/MessagesHe.php
languages/messages/MessagesIs.php
languages/messages/MessagesIt.php
languages/messages/MessagesJa.php
languages/messages/MessagesKiu.php
languages/messages/MessagesKk_cyrl.php
languages/messages/MessagesKo.php
languages/messages/MessagesLad.php
languages/messages/MessagesLb.php
languages/messages/MessagesLrc.php
languages/messages/MessagesMg.php
languages/messages/MessagesMk.php
languages/messages/MessagesMl.php
languages/messages/MessagesMt.php
languages/messages/MessagesNb.php
languages/messages/MessagesNl.php
languages/messages/MessagesPl.php
languages/messages/MessagesPms.php
languages/messages/MessagesQqq.php
languages/messages/MessagesQu.php
languages/messages/MessagesRo.php
languages/messages/MessagesRu.php
languages/messages/MessagesSl.php
languages/messages/MessagesSr_ec.php
languages/messages/MessagesSr_el.php
languages/messages/MessagesSv.php
languages/messages/MessagesTe.php
languages/messages/MessagesUg_arab.php
languages/messages/MessagesUk.php
languages/messages/MessagesUz.php
languages/messages/MessagesVi.php
languages/messages/MessagesYi.php
languages/messages/MessagesZh_hans.php
maintenance/benchmarks/benchmarkParse.php [new file with mode: 0644]
maintenance/getConfiguration.php
maintenance/jsduck/categories.json
maintenance/jsduck/config.json
maintenance/language/messages.inc
maintenance/updateSpecialPages.php
resources/Resources.php
resources/jquery.tipsy/jquery.tipsy.js
resources/jquery/jquery.client.js
resources/jquery/jquery.fullscreen.js
resources/mediawiki.page/mediawiki.page.watch.ajax.js
resources/mediawiki.ui/components/default/buttons.less
resources/mediawiki/mediawiki.htmlform.js
resources/mediawiki/mediawiki.searchSuggest.js
resources/mediawiki/mediawiki.util.js
skins/Vector.php
skins/vector/components/search.less
skins/vector/images/search-ltr.svg
skins/vector/images/search-rtl.svg
skins/vector/screen-hd.less
skins/vector/variables.less
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/api/ApiOptionsTest.php
tests/qunit/QUnitTestResources.php
tests/qunit/data/testrunner.js

diff --git a/CREDITS b/CREDITS
index eee4794..6e28d6d 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -129,6 +129,7 @@ following names for their contribution to the product.
 * Ebrahim Byagowi
 * Edward Z. Yang
 * Elvis Stansvik
+* Eranroz
 * Erwin Dokter
 * Federico Leva
 * FunPika
diff --git a/HISTORY b/HISTORY
index 672cb64..b2705f1 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -1831,7 +1831,7 @@ Selected changes since MediaWiki 1.17 that may be of interest:
   output.
 * (bug 14202) $wgUseTeX has been superseded by the Math extension. To re-enable
   math conversion after upgrading, obtain the Math extension from SVN or from
-  http://www.mediawiki.org/wiki/Extension:Math and add to LocalSettings.php:
+  https://www.mediawiki.org/wiki/Extension:Math and add to LocalSettings.php:
   require_once "$IP/extensions/Math/Math.php";
 * $wgProfiler is now a configuration array, see StartProfiler.sample for
   details.
@@ -1850,8 +1850,8 @@ Selected changes since MediaWiki 1.17 that may be of interest:
   whether a page is an article or not. $wgUseCommaCount is now deprecated.
 * $wgEnableDublinCoreRdf and $wgEnableCreativeCommonsRdf no longer work in core,
   and the functionality has been moved to the relevant extensions. See
-  http://www.mediawiki.org/wiki/Extension:DublinCoreRdf and
-  http://www.mediawiki.org/wiki/Extension:CreativeCommonsRdf as appropriate.
+  https://www.mediawiki.org/wiki/Extension:DublinCoreRdf and
+  https://www.mediawiki.org/wiki/Extension:CreativeCommonsRdf as appropriate.
 * (bug 21107) Split error "customcssjsprotected" into separate messages for JS and CSS
 * Removed $wgCheckCopyrightUpload from DefaultSettings, since the relevant feature
   was removed in about 1.5.
@@ -5787,7 +5787,7 @@ from first release, but nonessential bugfixes and feature developments
 will be made on the development trunk and appear in the next quarterly release.
 
 Those wishing to use the latest code instead of a branch release can obtain
-it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
+it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 
 === Configuration changes in 1.12 ===
 * Marking edits as bot edits with Special:Contributions?bot=1 now requires the
@@ -6240,7 +6240,7 @@ extensions which make use of the parser state may need compatibility changes.
 
 The new preprocessor syntax has been documented in Backus-Naur Form at:
 
-http://www.mediawiki.org/wiki/Preprocessor_ABNF
+https://www.mediawiki.org/wiki/Preprocessor_ABNF
 
 The ExpandTemplates extension now has the ability to generate an XML parse
 tree from wikitext source. This parse tree corresponds closely to the grammar
@@ -6248,7 +6248,7 @@ documented on that page.
 
 === API changes in 1.12 ===
 
-Full API documentation is available at http://www.mediawiki.org/wiki/API
+Full API documentation is available at https://www.mediawiki.org/wiki/API
 
 * (bug 11275) Enable descending sort in categorymembers
 * (bug 11308) Allow the API to output the image metadata
@@ -6339,7 +6339,7 @@ from first release, but nonessential bugfixes and feature developments
 will be made on the development trunk and appear in the next quarterly release.
 
 Those wishing to use the latest code instead of a branch release can obtain
-it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
+it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 
 == Configuration changes since 1.10 ==
 
@@ -6761,7 +6761,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 
 == API changes since 1.10 ==
 
-Full API documentation is available at http://www.mediawiki.org/wiki/API
+Full API documentation is available at https://www.mediawiki.org/wiki/API
 
 * New properties: links, templates, images, langlinks, categories, external
   links
@@ -6927,7 +6927,7 @@ from first release, but nonessential bugfixes and feature developments
 will be made on the development trunk and appear in the next quarterly release.
 
 Those wishing to use the latest code instead of a branch release can obtain
-it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
+it from source control: https://www.mediawiki.org/wiki/Download_from_SVN
 
 == Configuration changes ==
 
@@ -9945,7 +9945,7 @@ User accounts:
   groups. Note that this does *not* allow you to make pages which are only
   accessible to certain groups.
 
-  For details see: http://www.mediawiki.org/wiki/Manual:User_rights
+  For details see: https://www.mediawiki.org/wiki/Manual:User_rights
 
 E-mail:
   User-to-user e-mail can now be restricted to require a mail-back confirmation
@@ -10195,8 +10195,8 @@ Various bugfixes, small features, and a few experimental things:
 
 * 'live preview' reduces preview reload burden on supported browsers
 * support for external editors for files and wiki pages:
-  http://www.mediawiki.org/wiki/Manual:External_editors
-* Schema reworking: http://www.mediawiki.org/wiki/Proposed_Database_Schema_Changes/October_2004
+  https://www.mediawiki.org/wiki/Manual:External_editors
+* Schema reworking: https://www.mediawiki.org/wiki/Proposed_Database_Schema_Changes/October_2004
 * (bug 15) Allow editors to view diff of their change before actually submitting an edit
 * (bug 190) Hide your own edits on the watchlist
 * (bug 510): Special:Randompage now works for other namespaces than NS_MAIN.
@@ -10879,7 +10879,7 @@ release for relevant bug fixes; see the changelog later in this file.
 If you have trouble, remember to read this whole file and the online FAQ page
 before asking for help:
 
-http://www.mediawiki.org/wiki/Manual:FAQ
+https://www.mediawiki.org/wiki/Manual:FAQ
 
 
 === READ THIS FIRST: Upgrading ===
@@ -10973,7 +10973,7 @@ For background information on nofollow see:
 * More extension hooks have been added.
 * Authentication plugin hook.
 * More internal code documentation, generated with phpdoc:
-  http://www.mediawiki.org/docs/html/
+  https://doc.wikimedia.org/mediawiki-core/master/php/html/
 
 
 === Optimization ===
@@ -11418,7 +11418,7 @@ Documentation for both end-users and site administrators is currently being
 built up on MediaWiki.org, and is covered under the GNU Free Documentation
 License:
 
-  http://www.mediawiki.org/
+  https://www.mediawiki.org/
 
 
 === Mailing list ===
diff --git a/INSTALL b/INSTALL
index 891be73..e8731a1 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -21,7 +21,7 @@ experience problems, as this configuration is not well tested. safe_mode is also
 not tested and unlikely to work.
 
 Support for rendering mathematical formulas requires installing the Math extension,
-see http://www.mediawiki.org/wiki/Extension:Math
+see https://www.mediawiki.org/wiki/Extension:Math
 
 Don't forget to check the RELEASE-NOTES file...
 
@@ -30,7 +30,7 @@ Additional documentation is available online, which may include more detailed
 notes on particular operating systems and workarounds for difficult hosting
 environments:
 
-http://www.mediawiki.org/wiki/Manual:Installation_guide
+https://www.mediawiki.org/wiki/Manual:Installation_guide
 
 
 ******************* WARNING *******************
@@ -56,7 +56,7 @@ ie. /wiki/index.php/Article.
   |  will appear. It is common in this case to use w as the folder name and  |
   |  /wiki/ as the virtual article path where your articles pretend to be.   |
   |                                                                          |
-  |    See: http://www.mediawiki.org/wiki/Manual:Short_URL                   |
+  |    See: https://www.mediawiki.org/wiki/Manual:Short_URL                  |
   +--------------------------------------------------------------------------+
 
 Hop into your browser and surf into the wiki directory. It'll direct you into
index fe0eabf..e64c4aa 100644 (file)
@@ -119,6 +119,8 @@ production.
 * (bug 56199) Raw option of parser functions must now match complete word,
   to take effect.
 * (bug 60543) Special:PrefixIndex forgot stripprefix=1 for "Next page" link
+* (bug 29762) Undoing an already-undone edit will now display an appropriate
+  message instead of leading the user to make a null edit.
 
 === Web API changes in 1.23 ===
 * (bug 54884) action=parse&prop=categories now indicates hidden and missing
@@ -155,6 +157,9 @@ production.
   list=usercontribs.
 * list=watchlist now uses the querying user's rights rather than the wlowner's
   rights when checking whether wlprop=patrol is allowed.
+* (bug 32151) ApiWatch now has pageset capabilities (titles/pageids/generators).
+  Title parameter is now deprecated.
+* (bug 23005) Added action=revisiondelete.
 
 === Languages updated in 1.23 ===
 
diff --git a/UPGRADE b/UPGRADE
index 96b5836..1ff98cd 100644 (file)
--- a/UPGRADE
+++ b/UPGRADE
@@ -2,7 +2,7 @@
 This file provides an overview of the MediaWiki upgrade process. For help with
 specific problems, check
 
-* the documentation at http://www.mediawiki.org
+* the documentation at https://www.mediawiki.org
 * the mediawiki-l mailing list archive at
   http://lists.wikimedia.org/pipermail/mediawiki-l/
 * the bug tracker at https://bugzilla.wikimedia.org
@@ -12,7 +12,7 @@ for information and workarounds to common issues.
 == Overview ==
 
 Comprehensive documentation on upgrading to the latest version of the software
-is available at http://www.mediawiki.org/wiki/Manual:Upgrading.
+is available at https://www.mediawiki.org/wiki/Manual:Upgrading.
 
 === Consult the release notes ===
 
@@ -28,7 +28,7 @@ you take a complete backup of your wiki database and files and verify it. While
 the upgrade scripts are somewhat robust, there is no guarantee that things will
 not fail, leaving the database in an inconsistent state.
 
-http://www.mediawiki.org/wiki/Manual:Backing_up_a_wiki provides an overview of
+https://www.mediawiki.org/wiki/Manual:Backing_up_a_wiki provides an overview of
 the backup process. You should also refer to the documentation for your
 database management system for information on backing up a database, and to
 your operating system documentation for information on making copies of files.
index 65a597b..735f26b 100644 (file)
@@ -7,7 +7,7 @@ By Tim Starling, January 2006.
 
 For information about the MediaWiki database layout, such as a 
 description of the tables and their contents, please see:
-  http://www.mediawiki.org/wiki/Manual:Database_layout
+  https://www.mediawiki.org/wiki/Manual:Database_layout
   https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/core.git;a=blob_plain;f=maintenance/tables.sql;hb=HEAD
 
 
index f95ef0f..5c04add 100644 (file)
@@ -3,7 +3,7 @@ design.txt
 This is a brief overview of the new design.
 
 More thorough and up-to-date information is available on the documentation
-wiki at http://www.mediawiki.org/
+wiki at https://www.mediawiki.org/
 
 Primary classes:
 
index 4a65431..efa573d 100644 (file)
@@ -52,7 +52,7 @@ root, is /w (so, e.g., /var/www/w).  Rewrite rules can then be used to enable
 is the convention Wikipedia uses.)  In theory, it should be possible to enable
 the appropriate rewrite rules by default, if you can reconfigure the web
 server, but you'd need to alter LocalSettings.php too.  See
-<http://www.mediawiki.org/wiki/Manual:Short_URL> for details on short URLs.
+<https://www.mediawiki.org/wiki/Manual:Short_URL> for details on short URLs.
 
 If you really must mess around with the directory structure, note that the
 following files *must* all be web-accessible for MediaWiki to function
@@ -122,7 +122,7 @@ needed to rename LocalSettings.php in order to upgrade using the installer).
 == Documentation ==
 
 MediaWiki's official documentation is split between two places: the source
-code, and <http://www.mediawiki.org/>.  The source code documentation is written
+code, and <https://www.mediawiki.org/>.  The source code documentation is written
 exclusively by developers, and so is likely to be reliable (at worst,
 outdated).  However, it can be pretty sparse.  mediawiki.org documentation is
 often much more thorough, but it's maintained by a wiki that's open to
@@ -135,7 +135,7 @@ MediaWiki is a project hosted and led by the Wikimedia Foundation, the
 not-for-profit charity that operates Wikipedia.  Wikimedia employs the lead
 developer and several other paid developers, but commit access is given out
 liberally and there are multiple very active volunteer developers as well.  A
-list of developers can be found at <http://www.mediawiki.org/wiki/Developers>.
+list of developers can be found at <https://www.mediawiki.org/wiki/Developers>.
 
 MediaWiki's bug tracker is at <https://bugzilla.wikimedia.org>.  However, most
 developers follow the bug tracker little or not at all.  The best place to
@@ -179,7 +179,7 @@ perhaps configure it to use them (see Configuration section of this document):
   * Squid: Can provide a drastic speedup and a major cut in resource
   consumption, but enabling it may interfere with other applications.  It might
   be suitable for a separate mediawiki-squid package.  For setup details, see:
-  <http://www.mediawiki.org/wiki/Manual:Squid_caching>
+  <https://www.mediawiki.org/wiki/Manual:Squid_caching>
   * rsvg or other SVG rasterizer: ImageMagick can be used for SVG support, but
   is not ideal.  Wikipedia (as of the time of this writing) uses rsvg.  To
   enable, set "$wgSVGConverter = 'rsvg';" (or other as appropriate).
index 42a6027..8f4cf75 100644 (file)
@@ -2,4 +2,4 @@ language.txt
 
 The Language object handles all readable text produced by the software.
 
-See http://www.mediawiki.org/wiki/Localisation#General_use_.28for_developers.29
+See https://www.mediawiki.org/wiki/Localisation#General_use_.28for_developers.29
index 1d9bf7d..46fcecc 100644 (file)
@@ -90,6 +90,6 @@ Note: the 'ParserFirstCallInit' hook is only aviable since 1.12. To work with
 an older version, you'll need to use an extension function.
 
 Online documentation (contains more informations):
-Magic words: http://www.mediawiki.org/wiki/Manual:Magic_words
-Variables: http://www.mediawiki.org/wiki/Manual:Variable
-Parser functions: http://www.mediawiki.org/wiki/Manual:Parser_functions
\ No newline at end of file
+Magic words: https://www.mediawiki.org/wiki/Manual:Magic_words
+Variables: https://www.mediawiki.org/wiki/Manual:Variable
+Parser functions: https://www.mediawiki.org/wiki/Manual:Parser_functions
\ No newline at end of file
index 365576c..7a92d0a 100644 (file)
@@ -6,4 +6,4 @@ That file has been commented with details of the usage for
 each table and field.
 
 Historical information and some other notes are available at
-http://www.mediawiki.org/wiki/Manual:Database_layout
+https://www.mediawiki.org/wiki/Manual:Database_layout
index 0b8ee8f..4f16709 100644 (file)
@@ -9,16 +9,16 @@ Primary scripts:
 
   index.php
     Main access point. It handles the most of requests.
-    See http://www.mediawiki.org/wiki/Manual:Index.php
+    See https://www.mediawiki.org/wiki/Manual:Index.php
 
   api.php
     Script to provide an API for bots to fetch content and informations about
-    the site and also modify it. See http://www.mediawiki.org/wiki/API
+    the site and also modify it. See https://www.mediawiki.org/wiki/API
     for more informations.
 
   img_auth.php
     Script that only serve images to logged in users. To configure the wiki
-    to use that script, see http://www.mediawiki.org/wiki/Manual:Image_Authorisation.
+    to use that script, see https://www.mediawiki.org/wiki/Manual:Image_Authorisation.
 
   load.php
     Used by ResourceLoader to serve minified, concatenated and gzipped CSS and JS.
@@ -40,7 +40,7 @@ Primary scripts:
 
     To enable the profileinfo.php itself, you'll need to set $wgDBadminuser
     and $wgDBadminpassword in your LocalSettings.php, as well as $wgEnableProfileInfo 
-    See also http://www.mediawiki.org/wiki/How_to_debug#Profiling.
+    See also https://www.mediawiki.org/wiki/How_to_debug#Profiling.
 
   thumb.php
     Script used to resize images if it is configured to be done when the web
index 1459d7a..58f77cf 100644 (file)
@@ -55,7 +55,7 @@ These can also be customised on a per-user basis, by editing
 
 This feature has led to a wide variety of "user styles" becoming available:
 
-http://www.mediawiki.org/wiki/Manual:Gallery_of_user_styles
+https://www.mediawiki.org/wiki/Manual:Gallery_of_user_styles
 
 If you want a different look for your wiki, that gallery is a good place to start.
 
@@ -76,7 +76,7 @@ This technique is used by the more ambitious MediaWiki site operators, to
 create complex custom skins for their wikis. It should be preferred over 
 editing the core Monobook skin directly.
 
-See http://www.mediawiki.org/wiki/Manual:Skinning for more information.
+See https://www.mediawiki.org/wiki/Manual:Skinning for more information.
 
 == Extension skins ==
 
index 037ef9a..ac8a9f0 100644 (file)
@@ -220,7 +220,7 @@ class AjaxResponse {
                }
 
                if ( !$wgCachePages ) {
-                       wfDebug( "$fname: CACHE DISABLED\n", false );
+                       wfDebug( "$fname: CACHE DISABLED\n", 'log' );
                        return false;
                }
 
@@ -234,8 +234,8 @@ class AjaxResponse {
                        $modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
                        $modsinceTime = strtotime( $modsince );
                        $ismodsince = wfTimestamp( TS_MW, $modsinceTime ? $modsinceTime : 1 );
-                       wfDebug( "$fname: -- client send If-Modified-Since: " . $modsince . "\n", false );
-                       wfDebug( "$fname: --  we might send Last-Modified : $lastmod\n", false );
+                       wfDebug( "$fname: -- client send If-Modified-Since: " . $modsince . "\n", 'log' );
+                       wfDebug( "$fname: --  we might send Last-Modified : $lastmod\n", 'log' );
 
                        if ( ( $ismodsince >= $timestamp ) && $wgUser->validateCache( $ismodsince ) && $ismodsince >= $wgCacheEpoch ) {
                                ini_set( 'zlib.output_compression', 0 );
@@ -243,15 +243,15 @@ class AjaxResponse {
                                $this->disable();
                                $this->mLastModified = $lastmod;
 
-                               wfDebug( "$fname: CACHED client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", false );
+                               wfDebug( "$fname: CACHED client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", 'log' );
 
                                return true;
                        } else {
-                               wfDebug( "$fname: READY  client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", false );
+                               wfDebug( "$fname: READY  client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", 'log' );
                                $this->mLastModified = $lastmod;
                        }
                } else {
-                       wfDebug( "$fname: client did not send If-Modified-Since header\n", false );
+                       wfDebug( "$fname: client did not send If-Modified-Since header\n", 'log' );
                        $this->mLastModified = $lastmod;
                }
                return false;
index 0f1cded..61e0941 100644 (file)
@@ -365,6 +365,7 @@ $wgAutoloadLocalClasses = array(
        'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php',
        'ApiQueryWatchlistRaw' => 'includes/api/ApiQueryWatchlistRaw.php',
        'ApiResult' => 'includes/api/ApiResult.php',
+       'ApiRevisionDelete' => 'includes/api/ApiRevisionDelete.php',
        'ApiRollback' => 'includes/api/ApiRollback.php',
        'ApiRsd' => 'includes/api/ApiRsd.php',
        'ApiSetNotificationTimestamp' => 'includes/api/ApiSetNotificationTimestamp.php',
index 326a1c2..d0ceafc 100644 (file)
@@ -6162,7 +6162,8 @@ $wgJobQueueAggregator = array(
  * Expensive Querypages are already updated.
  */
 $wgSpecialPageCacheUpdates = array(
-       'Statistics' => array( 'SiteStatsUpdate', 'cacheUpdate' )
+       'Statistics' => array( 'SiteStatsUpdate', 'cacheUpdate' ),
+       'Activeusers' => array( 'SpecialActiveUsers', 'cacheUpdate' ),
 );
 
 /**
index fbfe3ed..9a27d23 100644 (file)
@@ -892,7 +892,7 @@ class EditPage {
         * @since 1.21
         */
        protected function getContentObject( $def_content = null ) {
-               global $wgOut, $wgRequest;
+               global $wgOut, $wgRequest, $wgUser, $wgContLang;
 
                wfProfileIn( __METHOD__ );
 
@@ -947,34 +947,45 @@ class EditPage {
                                                        # Warn the user that something went wrong
                                                        $undoMsg = 'failure';
                                                } else {
-                                                       # Inform the user of our success and set an automatic edit summary
-                                                       $undoMsg = 'success';
-
-                                                       # If we just undid one rev, use an autosummary
-                                                       $firstrev = $oldrev->getNext();
-                                                       if ( $firstrev && $firstrev->getId() == $undo ) {
-                                                               $userText = $undorev->getUserText();
-                                                               if ( $userText === '' ) {
-                                                                       $undoSummary = wfMessage(
-                                                                               'undo-summary-username-hidden',
-                                                                               $undo
-                                                                       )->inContentLanguage()->text();
-                                                               } else {
-                                                                       $undoSummary = wfMessage(
-                                                                               'undo-summary',
-                                                                               $undo,
-                                                                               $userText
-                                                                       )->inContentLanguage()->text();
+                                                       $oldContent = $this->mArticle->getPage()->getContent( Revision::RAW );
+                                                       $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
+                                                       $newContent = $content->preSaveTransform( $this->mTitle, $wgUser, $popts );
+
+                                                       if ( $newContent->equals( $oldContent ) ) {
+                                                               # Tell the user that the undo results in no change,
+                                                               # i.e. the revisions were already undone.
+                                                               $undoMsg = 'nochange';
+                                                               $content = false;
+                                                       } else {
+                                                               # Inform the user of our success and set an automatic edit summary
+                                                               $undoMsg = 'success';
+
+                                                               # If we just undid one rev, use an autosummary
+                                                               $firstrev = $oldrev->getNext();
+                                                               if ( $firstrev && $firstrev->getId() == $undo ) {
+                                                                       $userText = $undorev->getUserText();
+                                                                       if ( $userText === '' ) {
+                                                                               $undoSummary = wfMessage(
+                                                                                       'undo-summary-username-hidden',
+                                                                                       $undo
+                                                                               )->inContentLanguage()->text();
+                                                                       } else {
+                                                                               $undoSummary = wfMessage(
+                                                                                       'undo-summary',
+                                                                                       $undo,
+                                                                                       $userText
+                                                                               )->inContentLanguage()->text();
+                                                                       }
+                                                                       if ( $this->summary === '' ) {
+                                                                               $this->summary = $undoSummary;
+                                                                       } else {
+                                                                               $this->summary = $undoSummary . wfMessage( 'colon-separator' )
+                                                                                       ->inContentLanguage()->text() . $this->summary;
+                                                                       }
+                                                                       $this->undidRev = $undo;
                                                                }
-                                                               if ( $this->summary === '' ) {
-                                                                       $this->summary = $undoSummary;
-                                                               } else {
-                                                                       $this->summary = $undoSummary . wfMessage( 'colon-separator' )
-                                                                               ->inContentLanguage()->text() . $this->summary;
-                                                               }
-                                                               $this->undidRev = $undo;
+                                                               $this->formtype = 'diff';
                                                        }
-                                                       $this->formtype = 'diff';
                                                }
                                        } else {
                                                // Failed basic sanity checks.
@@ -983,7 +994,7 @@ class EditPage {
                                                $undoMsg = 'norev';
                                        }
 
-                                       // Messages: undo-success, undo-failure, undo-norev
+                                       // Messages: undo-success, undo-failure, undo-norev, undo-nochange
                                        $class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
                                        $this->editFormPageTop .= $wgOut->parse( "<div class=\"{$class}\">" .
                                                wfMessage( 'undo-' . $undoMsg )->plain() . '</div>', true, /* interface */true );
index d8c7b6a..45b314d 100644 (file)
@@ -901,14 +901,14 @@ class MWExceptionHandler {
                if ( !( $e instanceof MWException ) || $e->isLoggable() ) {
                        $log = self::getLogMessage( $e );
                        if ( $wgLogExceptionBacktrace ) {
-                               wfDebugLog( 'exception', $log . "\n" . $e->getTraceAsString() . "\n" );
+                               wfDebugLog( 'exception', $log . "\n" . $e->getTraceAsString() );
                        } else {
                                wfDebugLog( 'exception', $log );
                        }
 
                        $json = self::jsonSerializeException( $e, false, FormatJson::ALL_OK );
                        if ( $json !== false ) {
-                               wfDebugLog( 'exception-json', $json, false );
+                               wfDebugLog( 'exception-json', $json, 'private' );
                        }
                }
 
index 2dda695..6785d0c 100644 (file)
@@ -924,21 +924,33 @@ function wfMatchesDomainList( $url, $domains ) {
  * $wgDebugComments - if on, some debug items may appear in comments in the HTML output.
  *
  * @param $text String
- * @param bool $logonly set true to avoid appearing in HTML when $wgDebugComments is set
- */
-function wfDebug( $text, $logonly = false ) {
+ * @param string|bool $dest Destination of the message:
+ *     - 'all': both to the log and HTML (debug toolbar or HTML comments)
+ *     - 'log': only to the log and not in HTML
+ *   For backward compatibility, it can also take a boolean:
+ *     - true: same as 'all'
+ *     - false: same as 'log'
+ */
+function wfDebug( $text, $dest = 'all' ) {
        global $wgDebugLogFile, $wgProfileOnly, $wgDebugRawPage, $wgDebugLogPrefix;
 
        if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
                return;
        }
 
+       // Turn $dest into a string if it's a boolean (for b/c)
+       if ( $dest === true ) {
+               $dest = 'all';
+       } elseif ( $dest === false ) {
+               $dest = 'log';
+       }
+
        $timer = wfDebugTimer();
        if ( $timer !== '' ) {
                $text = preg_replace( '/[^\n]/', $timer . '\0', $text, 1 );
        }
 
-       if ( !$logonly ) {
+       if ( $dest === 'all' ) {
                MWDebug::debugMsg( $text );
        }
 
@@ -1019,18 +1031,38 @@ function wfDebugMem( $exact = false ) {
  * @param $text String
  * @param bool $public whether to log the event in the public log if no private
  *                     log file is specified, (default true)
- */
-function wfDebugLog( $logGroup, $text, $public = true ) {
+ * @param string|bool $dest Destination of the message:
+ *     - 'all': both to the log and HTML (debug toolbar or HTML comments)
+ *     - 'log': only to the log and not in HTML
+ *     - 'private': only to the specifc log if set in $wgDebugLogGroups and
+ *       discarded otherwise
+ *   For backward compatibility, it can also take a boolean:
+ *     - true: same as 'all'
+ *     - false: same as 'private'
+ */
+function wfDebugLog( $logGroup, $text, $dest = 'all' ) {
        global $wgDebugLogGroups;
+
        $text = trim( $text ) . "\n";
 
+       // Turn $dest into a string if it's a boolean (for b/c)
+       if ( $dest === true ) {
+               $dest = 'all';
+       } elseif ( $dest === false ) {
+               $dest = 'private';
+       }
+
        if ( !isset( $wgDebugLogGroups[$logGroup] ) ) {
-               if ( $public === true ) {
-                       wfDebug( "[$logGroup] $text", false );
+               if ( $dest !== 'private' ) {
+                       wfDebug( "[$logGroup] $text", $dest );
                }
                return;
        }
 
+       if ( $dest === 'all' ) {
+               MWDebug::debugMsg( "[$logGroup] $text" );
+       }
+
        $logConfig = $wgDebugLogGroups[$logGroup];
        if ( is_array( $logConfig ) ) {
                if ( isset( $logConfig['sample'] ) && mt_rand( 1, $logConfig['sample'] ) !== 1 ) {
@@ -2836,7 +2868,7 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(),
        $pipes = null;
        $proc = proc_open( $cmd, $desc, $pipes );
        if ( !$proc ) {
-               wfDebugLog( 'exec', "proc_open() failed: $cmd\n" );
+               wfDebugLog( 'exec', "proc_open() failed: $cmd" );
                $retval = -1;
                return '';
        }
@@ -2951,7 +2983,7 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(),
        }
 
        if ( $logMsg !== false ) {
-               wfDebugLog( 'exec', "$logMsg: $cmd\n" );
+               wfDebugLog( 'exec', "$logMsg: $cmd" );
        }
 
        return $outBuffer;
index 1972d2d..aff4b16 100644 (file)
@@ -685,7 +685,7 @@ class OutputPage extends ContextSource {
                        return false;
                }
                if ( !$wgCachePages ) {
-                       wfDebug( __METHOD__ . ": CACHE DISABLED\n", false );
+                       wfDebug( __METHOD__ . ": CACHE DISABLED\n", 'log' );
                        return false;
                }
 
@@ -706,7 +706,7 @@ class OutputPage extends ContextSource {
 
                $clientHeader = $this->getRequest()->getHeader( 'If-Modified-Since' );
                if ( $clientHeader === false ) {
-                       wfDebug( __METHOD__ . ": client did not send If-Modified-Since header\n", false );
+                       wfDebug( __METHOD__ . ": client did not send If-Modified-Since header\n", 'log' );
                        return false;
                }
 
@@ -734,17 +734,17 @@ class OutputPage extends ContextSource {
                }
 
                wfDebug( __METHOD__ . ": client sent If-Modified-Since: " .
-                       wfTimestamp( TS_ISO_8601, $clientHeaderTime ) . "\n", false );
+                       wfTimestamp( TS_ISO_8601, $clientHeaderTime ) . "\n", 'log' );
                wfDebug( __METHOD__ . ": effective Last-Modified: " .
-                       wfTimestamp( TS_ISO_8601, $maxModified ) . "\n", false );
+                       wfTimestamp( TS_ISO_8601, $maxModified ) . "\n", 'log' );
                if ( $clientHeaderTime < $maxModified ) {
-                       wfDebug( __METHOD__ . ": STALE, $info\n", false );
+                       wfDebug( __METHOD__ . ": STALE, $info\n", 'log' );
                        return false;
                }
 
                # Not modified
                # Give a 304 response code and disable body output
-               wfDebug( __METHOD__ . ": NOT MODIFIED, $info\n", false );
+               wfDebug( __METHOD__ . ": NOT MODIFIED, $info\n", 'log' );
                ini_set( 'zlib.output_compression', 0 );
                $this->getRequest()->response()->header( "HTTP/1.1 304 Not Modified" );
                $this->sendCacheControl();
@@ -1919,7 +1919,7 @@ class OutputPage extends ContextSource {
                                        # We'll purge the proxy cache explicitly, but require end user agents
                                        # to revalidate against the proxy on each visit.
                                        # Surrogate-Control controls our Squid, Cache-Control downstream caches
-                                       wfDebug( __METHOD__ . ": proxy caching with ESI; {$this->mLastModified} **\n", false );
+                                       wfDebug( __METHOD__ . ": proxy caching with ESI; {$this->mLastModified} **\n", 'log' );
                                        # start with a shorter timeout for initial testing
                                        # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
                                        $response->header( 'Surrogate-Control: max-age=' . $wgSquidMaxage . '+' . $this->mSquidMaxage . ', content="ESI/1.0"' );
@@ -1929,7 +1929,7 @@ class OutputPage extends ContextSource {
                                        # to revalidate against the proxy on each visit.
                                        # IMPORTANT! The Squid needs to replace the Cache-Control header with
                                        # Cache-Control: s-maxage=0, must-revalidate, max-age=0
-                                       wfDebug( __METHOD__ . ": local proxy caching; {$this->mLastModified} **\n", false );
+                                       wfDebug( __METHOD__ . ": local proxy caching; {$this->mLastModified} **\n", 'log' );
                                        # start with a shorter timeout for initial testing
                                        # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
                                        $response->header( 'Cache-Control: s-maxage=' . $this->mSquidMaxage . ', must-revalidate, max-age=0' );
@@ -1937,7 +1937,7 @@ class OutputPage extends ContextSource {
                        } else {
                                # We do want clients to cache if they can, but they *must* check for updates
                                # on revisiting the page.
-                               wfDebug( __METHOD__ . ": private caching; {$this->mLastModified} **\n", false );
+                               wfDebug( __METHOD__ . ": private caching; {$this->mLastModified} **\n", 'log' );
                                $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
                                $response->header( "Cache-Control: private, must-revalidate, max-age=0" );
                        }
@@ -1945,7 +1945,7 @@ class OutputPage extends ContextSource {
                                $response->header( "Last-Modified: {$this->mLastModified}" );
                        }
                } else {
-                       wfDebug( __METHOD__ . ": no caching **\n", false );
+                       wfDebug( __METHOD__ . ": no caching **\n", 'log' );
 
                        # In general, the absence of a last modified header should be enough to prevent
                        # the client from using its cache. We send a few other things just to make sure.
index 44520e8..ba1aae8 100644 (file)
@@ -62,6 +62,13 @@ class Preferences {
                'emailaddress',
        );
 
+       /**
+        * @return array
+        */
+       static function getSaveBlacklist() {
+               return self::$saveBlacklist;
+       }
+
        /**
         * @throws MWException
         * @param $user User
index 7c2f8f7..bb6a0c3 100644 (file)
@@ -543,9 +543,9 @@ abstract class QueryPage extends SpecialPage {
                if ( $this->shownavigation ) {
                        $out->addHTML( $this->getPageHeader() );
                        if ( $this->numRows > 0 ) {
-                               $out->addHTML( $this->msg( 'showingresults' )->numParams(
+                               $out->addHTML( $this->msg( 'showingresultsinrange' )->numParams(
                                        min( $this->numRows, $this->limit ), # do not show the one extra row, if exist
-                                       $this->offset + 1 )->parseAsBlock() );
+                                       $this->offset + 1, (min( $this->numRows, $this->limit ) + $this->offset) )->parseAsBlock() );
                                # Disable the "next" link when we reach the end
                                $paging = $this->getLanguage()->viewPrevNext( $this->getPageTitle( $par ), $this->offset,
                                        $this->limit, $this->linkParameters(), ( $this->numRows <= $this->limit ) );
index d1269ad..531d1a4 100644 (file)
@@ -417,8 +417,8 @@ MWExceptionHandler::installHandler();
 wfProfileOut( $fname . '-exception' );
 
 wfProfileIn( $fname . '-includes' );
-require_once "$IP/includes/GlobalFunctions.php";
 require_once "$IP/includes/normal/UtfNormalUtil.php";
+require_once "$IP/includes/GlobalFunctions.php";
 require_once "$IP/includes/normal/UtfNormalDefines.php";
 wfProfileOut( $fname . '-includes' );
 
@@ -457,8 +457,6 @@ if ( !$wgHTCPRouting && $wgHTCPMulticastAddress ) {
        );
 }
 
-$wgDeferredUpdateList = array(); // b/c
-
 wfProfileOut( $fname . '-defaults2' );
 wfProfileIn( $fname . '-misc1' );
 
@@ -503,22 +501,21 @@ if ( $wgCommandLineMode ) {
 }
 
 wfProfileOut( $fname . '-misc1' );
-if ( !defined( 'MW_SETUP_NO_CACHE' ) ) {
-       wfProfileIn( $fname . '-memcached' );
+wfProfileIn( $fname . '-memcached' );
 
-       $wgMemc = wfGetMainCache();
-       $messageMemc = wfGetMessageCacheStorage();
-       $parserMemc = wfGetParserCacheStorage();
-       $wgLangConvMemc = wfGetLangConverterCacheStorage();
+$wgMemc = wfGetMainCache();
+$messageMemc = wfGetMessageCacheStorage();
+$parserMemc = wfGetParserCacheStorage();
+$wgLangConvMemc = wfGetLangConverterCacheStorage();
 
-       wfDebug( 'CACHES: ' . get_class( $wgMemc ) . '[main] ' .
-               get_class( $messageMemc ) . '[message] ' .
-               get_class( $parserMemc ) . "[parser]\n" );
+wfDebug( 'CACHES: ' . get_class( $wgMemc ) . '[main] ' .
+       get_class( $messageMemc ) . '[message] ' .
+       get_class( $parserMemc ) . "[parser]\n" );
 
-       wfProfileOut( $fname . '-memcached' );
-       # # Most of the config is out, some might want to run hooks here.
-       wfRunHooks( 'SetupAfterCache' );
-}
+wfProfileOut( $fname . '-memcached' );
+
+# # Most of the config is out, some might want to run hooks here.
+wfRunHooks( 'SetupAfterCache' );
 
 wfProfileIn( $fname . '-session' );
 
@@ -537,44 +534,42 @@ if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
 }
 
 wfProfileOut( $fname . '-session' );
+wfProfileIn( $fname . '-globals' );
 
-if ( !defined( 'MW_SETUP_NO_CONTEXT' ) ) {
-       wfProfileIn( $fname . '-globals' );
-
-       $wgContLang = Language::factory( $wgLanguageCode );
-       $wgContLang->initEncoding();
-       $wgContLang->initContLang();
+$wgContLang = Language::factory( $wgLanguageCode );
+$wgContLang->initEncoding();
+$wgContLang->initContLang();
 
-       // Now that variant lists may be available...
-       $wgRequest->interpolateTitle();
-       $wgUser = RequestContext::getMain()->getUser(); # BackCompat
+// Now that variant lists may be available...
+$wgRequest->interpolateTitle();
+$wgUser = RequestContext::getMain()->getUser(); # BackCompat
 
-       /**
       * @var $wgLang Language
       */
-       $wgLang = new StubUserLang;
+/**
+ * @var $wgLang Language
+ */
+$wgLang = new StubUserLang;
 
-       /**
       * @var OutputPage
       */
-       $wgOut = RequestContext::getMain()->getOutput(); # BackCompat
+/**
+ * @var OutputPage
+ */
+$wgOut = RequestContext::getMain()->getOutput(); # BackCompat
 
-       /**
       * @var $wgParser Parser
       */
-       $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) );
+/**
+ * @var $wgParser Parser
+ */
+$wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) );
 
-       if ( !is_object( $wgAuth ) ) {
-               $wgAuth = new StubObject( 'wgAuth', 'AuthPlugin' );
-               wfRunHooks( 'AuthPluginSetup', array( &$wgAuth ) );
-       }
+if ( !is_object( $wgAuth ) ) {
+       $wgAuth = new StubObject( 'wgAuth', 'AuthPlugin' );
+       wfRunHooks( 'AuthPluginSetup', array( &$wgAuth ) );
+}
 
-       # Placeholders in case of DB error
-       $wgTitle = null;
+# Placeholders in case of DB error
+$wgTitle = null;
 
-       wfProfileOut( $fname . '-globals' );
-}
+$wgDeferredUpdateList = array();
 
+wfProfileOut( $fname . '-globals' );
 wfProfileIn( $fname . '-extensions' );
 
 # Extension setup functions for extensions other than skins
index f5fd195..eadf256 100644 (file)
@@ -373,7 +373,7 @@ class SquidPurgeClient {
         * @param $msg string
         */
        protected function log( $msg ) {
-               wfDebugLog( 'squid', __CLASS__ . " ($this->host): $msg\n" );
+               wfDebugLog( 'squid', __CLASS__ . " ($this->host): $msg" );
        }
 }
 
index ca3f79b..d863a06 100644 (file)
@@ -1418,11 +1418,11 @@ class User {
                                $ipList = gethostbynamel( $host );
 
                                if ( $ipList ) {
-                                       wfDebugLog( 'dnsblacklist', "Hostname $host is {$ipList[0]}, it's a proxy says $base!\n" );
+                                       wfDebugLog( 'dnsblacklist', "Hostname $host is {$ipList[0]}, it's a proxy says $base!" );
                                        $found = true;
                                        break;
                                } else {
-                                       wfDebugLog( 'dnsblacklist', "Requested $host, not found in $base.\n" );
+                                       wfDebugLog( 'dnsblacklist', "Requested $host, not found in $base." );
                                }
                        }
                }
@@ -2450,6 +2450,8 @@ class User {
         * - 'registered-checkmatrix' - as above, using the 'checkmatrix' type.
         * - 'userjs' - preferences with names starting with 'userjs-', intended to
         *              be used by user scripts.
+        * - 'special' - "preferences" that are not accessible via User::getOptions
+        *               or User::setOptions.
         * - 'unused' - preferences about which MediaWiki doesn't know anything.
         *              These are usually legacy options, removed in newer versions.
         *
@@ -2466,6 +2468,7 @@ class User {
                        'registered-multiselect',
                        'registered-checkmatrix',
                        'userjs',
+                       'special',
                        'unused'
                );
        }
@@ -2490,6 +2493,13 @@ class User {
                $prefs = Preferences::getPreferences( $this, $context );
                $mapping = array();
 
+               // Pull out the "special" options, so they don't get converted as
+               // multiselect or checkmatrix.
+               $specialOptions = array_fill_keys( Preferences::getSaveBlacklist(), true );
+               foreach ( $specialOptions as $name => $value ) {
+                       unset( $prefs[$name] );
+               }
+
                // Multiselect and checkmatrix options are stored in the database with
                // one key per option, each having a boolean value. Extract those keys.
                $multiselectOptions = array();
@@ -2532,6 +2542,8 @@ class User {
                                $mapping[$key] = 'registered-multiselect';
                        } elseif ( isset( $checkmatrixOptions[$key] ) ) {
                                $mapping[$key] = 'registered-checkmatrix';
+                       } elseif ( isset( $specialOptions[$key] ) ) {
+                               $mapping[$key] = 'special';
                        } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) {
                                $mapping[$key] = 'userjs';
                        } else {
index 99a70d9..a191983 100644 (file)
@@ -3608,12 +3608,12 @@ class PoolWorkArticleView extends PoolCounterWork {
                $this->parserOutput = ParserCache::singleton()->getDirty( $this->page, $this->parserOptions );
 
                if ( $this->parserOutput === false ) {
-                       wfDebugLog( 'dirty', "dirty missing\n" );
+                       wfDebugLog( 'dirty', 'dirty missing' );
                        wfDebug( __METHOD__ . ": no dirty cache\n" );
                        return false;
                } else {
                        wfDebug( __METHOD__ . ": sending dirty output\n" );
-                       wfDebugLog( 'dirty', "dirty output {$this->cacheKey}\n" );
+                       wfDebugLog( 'dirty', "dirty output {$this->cacheKey}" );
                        $this->isDirty = true;
                        return true;
                }
index bab2f93..b753407 100644 (file)
@@ -165,7 +165,7 @@ class RawAction extends FormlessAction {
                                } elseif ( !$content instanceof TextContent ) {
                                        // non-text content
                                        wfHttpError( 415, "Unsupported Media Type", "The requested page uses the content model `"
-                                                                               . $content->getModel() . "` which is not supported via this interface." );
+                                               . $content->getModel() . "` which is not supported via this interface." );
                                        die();
                                } else {
                                        // want a section?
index e610d19..72b1f88 100644 (file)
@@ -1372,13 +1372,13 @@ abstract class ApiBase extends ContextSource {
        }
 
        /**
-        * Throw a UsageException based on the errors in the Status object.
+        * Get error (as code, string) from a Status object.
         *
-        * @since 1.22
+        * @since 1.23
         * @param Status $status Status object
-        * @throws MWException
+        * @return array of code and error string
         */
-       public function dieStatus( $status ) {
+       public function getErrorFromStatus( $status ) {
                if ( $status->isGood() ) {
                        throw new MWException( 'Successful status passed to ApiBase::dieStatus' );
                }
@@ -1406,7 +1406,21 @@ abstract class ApiBase extends ContextSource {
                        // Translate message to code, for backwards compatability
                        $code = ApiBase::$messageMap[$code]['code'];
                }
-               $this->dieUsage( $msg->inLanguage( 'en' )->useDatabase( false )->plain(), $code );
+
+               return array( $code, $msg->inLanguage( 'en' )->useDatabase( false )->plain() );
+       }
+
+       /**
+        * Throw a UsageException based on the errors in the Status object.
+        *
+        * @since 1.22
+        * @param Status $status Status object
+        * @throws MWException
+        */
+       public function dieStatus( $status ) {
+
+               list( $code, $msg ) = $this->getErrorFromStatus( $status );
+               $this->dieUsage( $msg, $code );
        }
 
        // @codingStandardsIgnoreStart Allow long lines. Cannot split these.
index ea61932..2684f51 100644 (file)
@@ -39,7 +39,6 @@
  * @ingroup API
  */
 class ApiMain extends ApiBase {
-
        /**
         * When no format parameter is given, this format will be used
         */
@@ -84,6 +83,7 @@ class ApiMain extends ApiBase {
                'userrights' => 'ApiUserrights',
                'options' => 'ApiOptions',
                'imagerotate' => 'ApiImageRotate',
+               'revisiondelete' => 'ApiRevisionDelete',
        );
 
        /**
@@ -899,7 +899,7 @@ class ApiMain extends ApiBase {
                        }
                }
                $s .= "\n";
-               wfDebugLog( 'api', $s, false );
+               wfDebugLog( 'api', $s, 'private' );
        }
 
        /**
@@ -1147,7 +1147,10 @@ class ApiMain extends ApiBase {
                        array( 'code' => 'maxlag', 'info' => 'Waiting for host: x seconds lagged' ),
                        array( 'code' => 'maxlag', 'info' => 'Waiting for a database server: x seconds lagged' ),
                        array( 'code' => 'assertuserfailed', 'info' => 'Assertion that the user is logged in failed' ),
-                       array( 'code' => 'assertbotfailed', 'info' => 'Assertion that the user has the bot right failed' ),
+                       array(
+                               'code' => 'assertbotfailed',
+                               'info' => 'Assertion that the user has the bot right failed'
+                       ),
                ) );
        }
 
index 929b0b6..fb441a3 100644 (file)
@@ -98,6 +98,9 @@ class ApiOptions extends ApiBase {
                                                $validation = true;
                                        }
                                        break;
+                               case 'special':
+                                       $validation = "cannot be set by this module";
+                                       break;
                                case 'unused':
                                default:
                                        $validation = "not a valid preference";
index 4095fe6..c712539 100644 (file)
@@ -39,7 +39,6 @@
  * @since 1.21 derives from ApiBase instead of ApiQueryBase
  */
 class ApiPageSet extends ApiBase {
-
        /**
         * Constructor flag: The new instance of ApiPageSet will ignore the 'generator=' parameter
         * @since 1.21
@@ -74,6 +73,30 @@ class ApiPageSet extends ApiBase {
         */
        private $mDefaultNamespace = NS_MAIN;
 
+       /**
+        * Add all items from $values into the result
+        * @param array $result output
+        * @param array $values values to add
+        * @param string $flag the name of the boolean flag to mark this element
+        * @param string $name if given, name of the value
+        */
+       private static function addValues( array &$result, $values, $flag = null, $name = null ) {
+               foreach ( $values as $val ) {
+                       if ( $val instanceof Title ) {
+                               $v = array();
+                               ApiQueryBase::addTitleInfo( $v, $val );
+                       } elseif ( $name !== null ) {
+                               $v = array( $name => $val );
+                       } else {
+                               $v = $val;
+                       }
+                       if ( $flag !== null ) {
+                               $v[$flag] = '';
+                       }
+                       $result[] = $v;
+               }
+       }
+
        /**
         * Constructor
         * @param $dbSource ApiBase Module implementing getDB().
@@ -498,6 +521,46 @@ class ApiPageSet extends ApiBase {
                return $values;
        }
 
+       /**
+        * Get an array of invalid/special/missing titles.
+        *
+        * @param $invalidChecks List of types of invalid titles to include.
+        *   Recognized values are:
+        *   - invalidTitles: Titles from $this->getInvalidTitles()
+        *   - special: Titles from $this->getSpecialTitles()
+        *   - missingIds: ids from $this->getMissingPageIDs()
+        *   - missingRevIds: ids from $this->getMissingRevisionIDs()
+        *   - missingTitles: Titles from $this->getMissingTitles()
+        *   - interwikiTitles: Titles from $this->getInterwikiTitlesAsResult()
+        * @return array Array suitable for inclusion in the response
+        * @since 1.23
+        */
+       public function getInvalidTitlesAndRevisions( $invalidChecks = array( 'invalidTitles',
+               'special', 'missingIds', 'missingRevIds', 'missingTitles', 'interwikiTitles' )
+       ) {
+               $result = array();
+               if ( in_array( "invalidTitles", $invalidChecks ) ) {
+                       self::addValues( $result, $this->getInvalidTitles(), 'invalid', 'title' );
+               }
+               if ( in_array( "special", $invalidChecks ) ) {
+                       self::addValues( $result, $this->getSpecialTitles(), 'special', 'title' );
+               }
+               if ( in_array( "missingIds", $invalidChecks ) ) {
+                       self::addValues( $result, $this->getMissingPageIDs(), 'missing', 'pageid' );
+               }
+               if ( in_array( "missingRevIds", $invalidChecks ) ) {
+                       self::addValues( $result, $this->getMissingRevisionIDs(), 'missing', 'revid' );
+               }
+               if ( in_array( "missingTitles", $invalidChecks ) ) {
+                       self::addValues( $result, $this->getMissingTitles(), 'missing' );
+               }
+               if ( in_array( "interwikiTitles", $invalidChecks ) ) {
+                       self::addValues( $result, $this->getInterwikiTitlesAsResult() );
+               }
+
+               return $result;
+       }
+
        /**
         * Get the list of revision IDs (requested with the revids= parameter)
         * @return array revID (int) => pageID (int)
index 80c76b3..644e97e 100644 (file)
@@ -92,10 +92,13 @@ class ApiProtect extends ApiBase {
                                }
                                $expiryarray[$p[0]] = $exp;
                        }
-                       $resultProtections[] = array( $p[0] => $protections[$p[0]],
-                               'expiry' => ( $expiryarray[$p[0]] == $db->getInfinity() ?
-                                       'infinite' :
-                                       wfTimestamp( TS_ISO_8601, $expiryarray[$p[0]] ) ) );
+                       $resultProtections[] = array(
+                               $p[0] => $protections[$p[0]],
+                               'expiry' => ( $expiryarray[$p[0]] == $db->getInfinity()
+                                       ? 'infinite'
+                                       : wfTimestamp( TS_ISO_8601, $expiryarray[$p[0]] )
+                               )
+                       );
                }
 
                $cascade = $params['cascade'];
index c0dd808..e5d6a3c 100644 (file)
 class ApiPurge extends ApiBase {
        private $mPageSet;
 
-       /**
-        * Add all items from $values into the result
-        * @param array $result output
-        * @param array $values values to add
-        * @param string $flag the name of the boolean flag to mark this element
-        * @param string $name if given, name of the value
-        */
-       private static function addValues( array &$result, $values, $flag = null, $name = null ) {
-               foreach ( $values as $val ) {
-                       if ( $val instanceof Title ) {
-                               $v = array();
-                               ApiQueryBase::addTitleInfo( $v, $val );
-                       } elseif ( $name !== null ) {
-                               $v = array( $name => $val );
-                       } else {
-                               $v = $val;
-                       }
-                       if ( $flag !== null ) {
-                               $v[$flag] = '';
-                       }
-                       $result[] = $v;
-               }
-       }
-
        /**
         * Purges the cache of a page
         */
@@ -67,13 +43,7 @@ class ApiPurge extends ApiBase {
                $pageSet = $this->getPageSet();
                $pageSet->execute();
 
-               $result = array();
-               self::addValues( $result, $pageSet->getInvalidTitles(), 'invalid', 'title' );
-               self::addValues( $result, $pageSet->getSpecialTitles(), 'special', 'title' );
-               self::addValues( $result, $pageSet->getMissingPageIDs(), 'missing', 'pageid' );
-               self::addValues( $result, $pageSet->getMissingRevisionIDs(), 'missing', 'revid' );
-               self::addValues( $result, $pageSet->getMissingTitles(), 'missing' );
-               self::addValues( $result, $pageSet->getInterwikiTitlesAsResult() );
+               $result = $pageSet->getInvalidTitlesAndRevisions();
 
                foreach ( $pageSet->getGoodTitles() as $title ) {
                        $r = array();
index 6bf8075..44bf0cb 100644 (file)
@@ -67,8 +67,12 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
                }
 
                $dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
-               $from = ( $params['from'] === null ? null : $this->titlePartToKey( $params['from'], NS_CATEGORY ) );
-               $to = ( $params['to'] === null ? null : $this->titlePartToKey( $params['to'], NS_CATEGORY ) );
+               $from = ( $params['from'] === null
+                       ? null
+                       : $this->titlePartToKey( $params['from'], NS_CATEGORY ) );
+               $to = ( $params['to'] === null
+                       ? null
+                       : $this->titlePartToKey( $params['to'], NS_CATEGORY ) );
                $this->addWhereRange( 'cat_title', $dir, $from, $to );
 
                $min = $params['min'];
index 5be304d..13f766e 100644 (file)
@@ -154,7 +154,6 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
                        $this->titlePartToKey( $params['to'], $params['namespace'] ) );
                $this->addWhereRange( $pfx . $fieldTitle, 'newer', $from, $to );
 
-
                if ( isset( $params['prefix'] ) ) {
                        $this->addWhere( $pfx . $fieldTitle . $db->buildLike( $this->titlePartToKey(
                                $params['prefix'], $params['namespace'] ), $db->anyString() ) );
index 430dd51..501154a 100644 (file)
@@ -87,8 +87,12 @@ class ApiQueryAllPages extends ApiQueryGeneratorBase {
 
                $this->addWhereFld( 'page_namespace', $params['namespace'] );
                $dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
-               $from = ( $params['from'] === null ? null : $this->titlePartToKey( $params['from'], $params['namespace'] ) );
-               $to = ( $params['to'] === null ? null : $this->titlePartToKey( $params['to'], $params['namespace'] ) );
+               $from = ( $params['from'] === null
+                       ? null
+                       : $this->titlePartToKey( $params['from'], $params['namespace'] ) );
+               $to = ( $params['to'] === null
+                       ? null
+                       : $this->titlePartToKey( $params['to'], $params['namespace'] ) );
                $this->addWhereRange( 'page_title', $dir, $from, $to );
 
                if ( isset( $params['prefix'] ) ) {
index eb51095..9d9f7c3 100644 (file)
@@ -501,6 +501,7 @@ abstract class ApiQueryBase extends ApiBase {
                        // prefix.
                        $this->dieUsageMsg( array( 'invalidtitle', $titlePart ) );
                }
+
                return substr( $t->getDbKey(), 0, -1 );
        }
 
index 6b896e3..37fb489 100644 (file)
@@ -98,6 +98,7 @@ class ApiQueryContributors extends ApiQueryBase {
                                $this->setContinueEnumParameter( 'continue',
                                        $params['continue'] !== null ? $params['continue'] : '0|0'
                                );
+
                                return;
                        }
                }
@@ -144,6 +145,7 @@ class ApiQueryContributors extends ApiQueryBase {
                                        // of anoncontributors
                                        $this->setContinueEnumParameter( 'continue', $continuePages );
                                }
+
                                return;
                        }
                } elseif ( $params['excluderights'] ) {
@@ -182,6 +184,7 @@ class ApiQueryContributors extends ApiQueryBase {
                                // We've reached the one extra which shows that
                                // there are additional pages to be had. Stop here...
                                $this->setContinueEnumParameter( 'continue', $row->page . '|' . $row->user );
+
                                return;
                        }
 
@@ -191,6 +194,7 @@ class ApiQueryContributors extends ApiQueryBase {
                        );
                        if ( !$fit ) {
                                $this->setContinueEnumParameter( 'continue', $row->page . '|' . $row->user );
+
                                return;
                        }
                }
@@ -269,7 +273,6 @@ class ApiQueryContributors extends ApiQueryBase {
                );
        }
 
-
        public function getDescription() {
                return 'Get the list of logged-in contributors and ' .
                        'the count of anonymous contributors to a page';
index 7585ba7..365fe3f 100644 (file)
@@ -176,8 +176,12 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                } elseif ( $mode == 'all' ) {
                        $this->addWhereFld( 'ar_namespace', $params['namespace'] );
 
-                       $from = $params['from'] === null ? null : $this->titlePartToKey( $params['from'], $params['namespace'] );
-                       $to = $params['to'] === null ? null : $this->titlePartToKey( $params['to'], $params['namespace'] );
+                       $from = $params['from'] === null
+                               ? null
+                               : $this->titlePartToKey( $params['from'], $params['namespace'] );
+                       $to = $params['to'] === null
+                               ? null
+                               : $this->titlePartToKey( $params['to'], $params['namespace'] );
                        $this->addWhereRange( 'ar_title', $dir, $from, $to );
 
                        if ( isset( $params['prefix'] ) ) {
index dffe301..d9579a1 100644 (file)
@@ -36,6 +36,7 @@ class ApiQueryFileRepoInfo extends ApiQueryBase {
        protected function getInitialisedRepoGroup() {
                $repoGroup = RepoGroup::singleton();
                $repoGroup->initialiseRepos();
+
                return $repoGroup;
        }
 
index baee9b1..95c1420 100644 (file)
@@ -677,7 +677,8 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                ' (requires url and param ' . $modulePrefix . 'urlwidth)',
                        'mediatype' =>      ' mediatype     - Adds the media type of the image',
                        'metadata' =>       ' metadata      - Lists Exif metadata for the version of the image',
-                       'commonmetadata' => ' commonmetadata - Lists file format generic metadata for the version of the image',
+                       'commonmetadata' => ' commonmetadata - Lists file format generic metadata ' .
+                               'for the version of the image',
                        'extmetadata' =>    ' extmetadata   - Lists formatted metadata combined ' .
                                'from multiple sources. Results are HTML formatted.',
                        'archivename' =>    ' archivename   - Adds the file name of the archive ' .
index 07561ca..9cf3afd 100644 (file)
@@ -562,7 +562,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                        $vcsVersion = $gitInfo->getHeadSHA1();
                                        if ( $vcsVersion !== false ) {
                                                $ret['vcs-system'] = 'git';
-                                               $ret['vcs-version'] =  $vcsVersion;
+                                               $ret['vcs-version'] = $vcsVersion;
                                                $ret['vcs-url'] = $gitInfo->getHeadViewUrl();
                                                $ret['vcs-date'] = wfTimestamp( TS_ISO_8601, $gitInfo->getHeadCommitDate() );
                                        } else {
@@ -573,12 +573,20 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                                        $ret['vcs-url'] = isset( $svnInfo['viewvc-url'] ) ? $svnInfo['viewvc-url'] : '';
                                                }
                                        }
+
                                        if ( SpecialVersion::getExtLicenseFileName( $extensionPath ) ) {
                                                $ret['license-name'] = isset( $ext['license-name'] ) ? $ext['license-name'] : '';
-                                               $ret['license'] = SpecialPage::getTitleFor( 'Version', "License/{$ext['name']}" )->getLinkURL();
+                                               $ret['license'] = SpecialPage::getTitleFor(
+                                                       'Version',
+                                                       "License/{$ext['name']}"
+                                               )->getLinkURL();
                                        }
+
                                        if ( SpecialVersion::getExtAuthorsFileName( $extensionPath ) ) {
-                                               $ret['credits'] = SpecialPage::getTitleFor( 'Version', "Credits/{$ext['name']}" )->getLinkURL();
+                                               $ret['credits'] = SpecialPage::getTitleFor(
+                                                       'Version',
+                                                       "Credits/{$ext['name']}"
+                                               )->getLinkURL();
                                        }
                                }
                                $data[] = $ret;
index 7896a2c..b492d9a 100644 (file)
@@ -360,7 +360,13 @@ class ApiQueryContributions extends ApiQueryBase {
                                $vals['commenthidden'] = '';
                                $anyHidden = true;
                        }
-                       if ( Revision::userCanBitfield( $row->rev_deleted, Revision::DELETED_COMMENT, $this->getUser() ) ) {
+
+                       $userCanView = Revision::userCanBitfield(
+                               $row->rev_deleted,
+                               Revision::DELETED_COMMENT, $this->getUser()
+                       );
+
+                       if ( $userCanView ) {
                                if ( $this->fld_comment ) {
                                        $vals['comment'] = $row->rev_comment;
                                }
diff --git a/includes/api/ApiRevisionDelete.php b/includes/api/ApiRevisionDelete.php
new file mode 100644 (file)
index 0000000..05457b3
--- /dev/null
@@ -0,0 +1,254 @@
+<?php
+/**
+ * Created on Jun 25, 2013
+ *
+ * Copyright © 2013 Brad Jorsch <bjorsch@wikimedia.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.23
+ */
+
+/**
+ * API interface to RevDel. The API equivalent of Special:RevisionDelete.
+ * Requires API write mode to be enabled.
+ *
+ * @ingroup API
+ */
+class ApiRevisionDelete extends ApiBase {
+
+       public function execute() {
+               $params = $this->extractRequestParams();
+               $user = $this->getUser();
+
+               if ( !$user->isAllowed( RevisionDeleter::getRestriction( $params['type'] ) ) ) {
+                       $this->dieUsageMsg( 'badaccess-group0' );
+               }
+
+               if ( !$params['ids'] ) {
+                       $this->dieUsage( "At least one value is required for 'ids'", 'badparams' );
+               }
+
+               $hide = $params['hide'] ?: array();
+               $show = $params['show'] ?: array();
+               if ( array_intersect( $hide, $show ) ) {
+                       $this->dieUsage( "Mutually exclusive values for 'hide' and 'show'", 'badparams' );
+               } elseif ( !$hide && !$show ) {
+                       $this->dieUsage( "At least one value is required for 'hide' or 'show'", 'badparams' );
+               }
+               $bits = array(
+                       'content' => RevisionDeleter::getRevdelConstant( $params['type'] ),
+                       'comment' => Revision::DELETED_COMMENT,
+                       'user' => Revision::DELETED_USER,
+               );
+               $bitfield = array();
+               foreach ( $bits as $key => $bit ) {
+                       if ( in_array( $key, $hide ) ) {
+                               $bitfield[$bit] = 1;
+                       } elseif ( in_array( $key, $show ) ) {
+                               $bitfield[$bit] = 0;
+                       } else {
+                               $bitfield[$bit] = -1;
+                       }
+               }
+
+               if ( $params['suppress'] === 'yes' ) {
+                       if ( !$user->isAllowed( 'suppressrevision' ) ) {
+                               $this->dieUsageMsg( 'badaccess-group0' );
+                       }
+                       $bitfield[Revision::DELETED_RESTRICTED] = 1;
+               } elseif ( $params['suppress'] === 'no' ) {
+                       $bitfield[Revision::DELETED_RESTRICTED] = 0;
+               } else {
+                       $bitfield[Revision::DELETED_RESTRICTED] = -1;
+               }
+
+               $targetObj = null;
+               if ( $params['target'] ) {
+                       $targetObj = Title::newFromText( $params['target'] );
+               }
+               $targetObj = RevisionDeleter::suggestTarget( $params['type'], $targetObj, $params['ids'] );
+               if ( $targetObj === null ) {
+                       $this->dieUsage( 'A target title is required for this RevDel type', 'needtarget' );
+               }
+
+               $list = RevisionDeleter::createList(
+                       $params['type'], $this->getContext(), $targetObj, $params['ids']
+               );
+               $status = $list->setVisibility(
+                       array( 'value' => $bitfield, 'comment' => $params['reason'], 'perItemStatus' => true )
+               );
+
+               $result = $this->getResult();
+               $data = $this->extractStatusInfo( $status );
+               $data['target'] = $targetObj->getFullText();
+               $data['items'] = array();
+
+               foreach ( $status->itemStatuses as $id => $s ) {
+                       $data['items'][$id] = $this->extractStatusInfo( $s );
+                       $data['items'][$id]['id'] = $id;
+               }
+
+               $list->reloadFromMaster();
+               // @codingStandardsIgnoreStart Avoid function calls in a FOR loop test part
+               for ( $item = $list->reset(); $list->current(); $item = $list->next() ) {
+                       $data['items'][$item->getId()] += $item->getApiData( $this->getResult() );
+               }
+               // @codingStandardsIgnoreEnd
+
+               $data['items'] = array_values( $data['items'] );
+               $result->setIndexedTagName( $data['items'], 'i' );
+               $result->addValue( null, $this->getModuleName(), $data );
+       }
+
+       private function extractStatusInfo( $status ) {
+               $ret = array(
+                       'status' => $status->isOK() ? 'Success' : 'Fail',
+               );
+               $errors = $this->formatStatusMessages( $status->getErrorsByType( 'error' ) );
+               if ( $errors ) {
+                       $this->getResult()->setIndexedTagName( $errors, 'e' );
+                       $ret['errors'] = $errors;
+               }
+               $warnings = $this->formatStatusMessages( $status->getErrorsByType( 'warning' ) );
+               if ( $warnings ) {
+                       $this->getResult()->setIndexedTagName( $warnings, 'w' );
+                       $ret['warnings'] = $warnings;
+               }
+
+               return $ret;
+       }
+
+       private function formatStatusMessages( $messages ) {
+               if ( !$messages ) {
+                       return array();
+               }
+               $result = $this->getResult();
+               $ret = array();
+               foreach ( $messages as $m ) {
+                       $message = array();
+                       if ( $m['message'] instanceof Message ) {
+                               $msg = $m['message'];
+                               $message = array( 'message' => $msg->getKey() );
+                               if ( $msg->getParams() ) {
+                                       $message['params'] = $msg->getParams();
+                                       $result->setIndexedTagName( $message['params'], 'p' );
+                               }
+                       } else {
+                               $message = array( 'message' => $m['message'] );
+                               $msg = wfMessage( $m['message'] );
+                               if ( isset( $m['params'] ) ) {
+                                       $message['params'] = $m['params'];
+                                       $result->setIndexedTagName( $message['params'], 'p' );
+                                       $msg->params( $m['params'] );
+                               }
+                       }
+                       $message['rendered'] = $msg->useDatabase( false )->inLanguage( 'en' )->plain();
+                       $ret[] = $message;
+               }
+
+               return $ret;
+       }
+
+       public function mustBePosted() {
+               return true;
+       }
+
+       public function isWriteMode() {
+               return true;
+       }
+
+       public function getAllowedParams() {
+               return array(
+                       'type' => array(
+                               ApiBase::PARAM_TYPE => RevisionDeleter::getTypes(),
+                               ApiBase::PARAM_REQUIRED => true
+                       ),
+                       'target' => null,
+                       'ids' => array(
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_REQUIRED => true
+                       ),
+                       'hide' => array(
+                               ApiBase::PARAM_TYPE => array( 'content', 'comment', 'user' ),
+                               ApiBase::PARAM_ISMULTI => true,
+                       ),
+                       'show' => array(
+                               ApiBase::PARAM_TYPE => array( 'content', 'comment', 'user' ),
+                               ApiBase::PARAM_ISMULTI => true,
+                       ),
+                       'suppress' => array(
+                               ApiBase::PARAM_TYPE => array( 'yes', 'no', 'nochange' ),
+                               ApiBase::PARAM_DFLT => 'nochange',
+                       ),
+                       'token' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => true
+                       ),
+                       'reason' => null,
+               );
+       }
+
+       public function getParamDescription() {
+               return array(
+                       'type' => 'Type of revision deletion being performed',
+                       'target' => 'Page title for the revision deletion, if required for the type',
+                       'ids' => 'Identifiers for the revisions to be deleted',
+                       'hide' => 'What to hide for each revision',
+                       'show' => 'What to unhide for each revision',
+                       'suppress' => 'Whether to suppress data from administrators as well as others',
+                       'token' => 'A delete token previously retrieved through action=tokens',
+                       'reason' => 'Reason for the deletion/undeletion',
+               );
+       }
+
+       public function getDescription() {
+               return 'Delete/undelete revisions';
+       }
+
+       public function getPossibleErrors() {
+               return array_merge( parent::getPossibleErrors(),
+                       array(
+                               'needtarget' => 'A target title is required for this RevDel type',
+                               'badparams' => 'Bad value for some parameter',
+                       )
+               );
+       }
+
+       public function needsToken() {
+               return true;
+       }
+
+       public function getTokenSalt() {
+               return '';
+       }
+
+       public function getExamples() {
+               return array(
+                       'api.php?action=revisiondelete&target=Main%20Page&type=revision&ids=12345&' .
+                               'hide=content&token=123ABC'
+                               => 'Hide content for revision 12345 on the Main Page',
+                       'api.php?action=revisiondelete&type=logging&ids=67890&hide=content|comment|user&' .
+                               'reason=BLP%20violation&token=123ABC'
+                               => 'Hide all data on log entry 67890 with the reason "BLP violation"',
+               );
+       }
+
+       public function getHelpUrls() {
+               return 'https://www.mediawiki.org/wiki/API:Revisiondelete';
+       }
+}
index 759afd7..100ee96 100644 (file)
  * @ingroup API
  */
 class ApiWatch extends ApiBase {
+       private $mPageSet = null;
 
        public function execute() {
                $user = $this->getUser();
                if ( !$user->isLoggedIn() ) {
                        $this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
                }
+
                if ( !$user->isAllowed( 'editmywatchlist' ) ) {
                        $this->dieUsage( 'You don\'t have permission to edit your watchlist', 'permissiondenied' );
                }
 
                $params = $this->extractRequestParams();
-               $title = Title::newFromText( $params['title'] );
+               $pageSet = $this->getPageSet();
+               // by default we use pageset to extract the page to work on.
+               // title is still supported for backward compatibility
+               if ( !isset( $params['title'] ) ) {
+                       $pageSet->execute();
+                       $res = $pageSet->getInvalidTitlesAndRevisions( array(
+                               'invalidTitles',
+                               'special',
+                               'missingIds',
+                               'missingRevIds',
+                               'interwikiTitles'
+                       ) );
+
+                       foreach ( $pageSet->getMissingTitles() as $title ) {
+                               $r = $this->watchTitle( $title, $user, $params );
+                               $r['missing'] = 1;
+                               $res[] = $r;
+                       }
+
+                       foreach ( $pageSet->getGoodTitles() as $title ) {
+                               $r = $this->watchTitle( $title, $user, $params );
+                               $res[] = $r;
+                       }
+                       $this->getResult()->setIndexedTagName( $res, 'w' );
+               } else {
+                       // dont allow use of old title parameter with new pageset parameters.
+                       $extraParams = array_keys( array_filter( $pageSet->extractRequestParams(), function ( $x ) {
+                               return $x !== null && $x !== false;
+                       } ) );
+
+                       if ( $extraParams ) {
+                               $p = $this->getModulePrefix();
+                               $this->dieUsage(
+                                       "The parameter {$p}title can not be used with " . implode( ", ", $extraParams ),
+                                       'invalidparammix'
+                               );
+                       }
+
+                       $title = Title::newFromText( $params['title'] );
+                       if ( !$title || !$title->isWatchable() ) {
+                               $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+                       }
+                       $res = $this->watchTitle( $title, $user, $params, true );
+               }
+               $this->getResult()->addValue( null, $this->getModuleName(), $res );
+       }
 
-               if ( !$title || !$title->isWatchable() ) {
-                       $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+       private function watchTitle( Title $title, User $user, array $params,
+               $compatibilityMode = false
+       ) {
+               if ( !$title->isWatchable() ) {
+                       return array( 'title' => $title->getPrefixedText(), 'watchable' => 0 );
                }
 
                $res = array( 'title' => $title->getPrefixedText() );
@@ -61,15 +111,19 @@ class ApiWatch extends ApiBase {
                }
 
                if ( $params['unwatch'] ) {
-                       $res['unwatched'] = '';
-                       $res['message'] = $this->msg( 'removedwatchtext', $title->getPrefixedText() )
-                               ->title( $title )->parseAsBlock();
                        $status = UnwatchAction::doUnwatch( $title, $user );
+                       if ( $status->isOK() ) {
+                               $res['unwatched'] = '';
+                               $res['message'] = $this->msg( 'removedwatchtext', $title->getPrefixedText() )
+                                       ->title( $title )->parseAsBlock();
+                       }
                } else {
-                       $res['watched'] = '';
-                       $res['message'] = $this->msg( 'addedwatchtext', $title->getPrefixedText() )
-                               ->title( $title )->parseAsBlock();
                        $status = WatchAction::doWatch( $title, $user );
+                       if ( $status->isOK() ) {
+                               $res['watched'] = '';
+                               $res['message'] = $this->msg( 'addedwatchtext', $title->getPrefixedText() )
+                                       ->title( $title )->parseAsBlock();
+                       }
                }
 
                if ( !is_null( $oldLang ) ) {
@@ -77,9 +131,25 @@ class ApiWatch extends ApiBase {
                }
 
                if ( !$status->isOK() ) {
-                       $this->dieStatus( $status );
+                       if ( $compatibilityMode ) {
+                               $this->dieStatus( $status );
+                       }
+                       $res['error'] = $this->getErrorFromStatus( $status );
                }
-               $this->getResult()->addValue( null, $this->getModuleName(), $res );
+
+               return $res;
+       }
+
+       /**
+        * Get a cached instance of an ApiPageSet object
+        * @return ApiPageSet
+        */
+       private function getPageSet() {
+               if ( $this->mPageSet === null ) {
+                       $this->mPageSet = new ApiPageSet( $this );
+               }
+
+               return $this->mPageSet;
        }
 
        public function mustBePosted() {
@@ -98,11 +168,11 @@ class ApiWatch extends ApiBase {
                return 'watch';
        }
 
-       public function getAllowedParams() {
-               return array(
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array(
                        'title' => array(
                                ApiBase::PARAM_TYPE => 'string',
-                               ApiBase::PARAM_REQUIRED => true
+                               ApiBase::PARAM_DEPRECATED => true
                        ),
                        'unwatch' => false,
                        'uselang' => null,
@@ -111,11 +181,18 @@ class ApiWatch extends ApiBase {
                                ApiBase::PARAM_REQUIRED => true
                        ),
                );
+               if ( $flags ) {
+                       $result += $this->getPageSet()->getFinalParams( $flags );
+               }
+
+               return $result;
        }
 
        public function getParamDescription() {
-               return array(
-                       'title' => 'The page to (un)watch',
+               $psModule = $this->getPageSet();
+
+               return $psModule->getParamDescription() + array(
+                       'title' => 'The page to (un)watch. use titles instead',
                        'unwatch' => 'If set the page will be unwatched rather than watched',
                        'uselang' => 'Language to show the message in',
                        'token' => 'A token previously acquired via prop=info',
@@ -134,7 +211,7 @@ class ApiWatch extends ApiBase {
        }
 
        public function getDescription() {
-               return 'Add or remove a page from/to the current user\'s watchlist';
+               return 'Add or remove pages from/to the current user\'s watchlist';
        }
 
        public function getPossibleErrors() {
@@ -147,8 +224,8 @@ class ApiWatch extends ApiBase {
 
        public function getExamples() {
                return array(
-                       'api.php?action=watch&title=Main_Page' => 'Watch the page "Main Page"',
-                       'api.php?action=watch&title=Main_Page&unwatch=' => 'Unwatch the page "Main Page"',
+                       'api.php?action=watch&titles=Main_Page' => 'Watch the page "Main Page"',
+                       'api.php?action=watch&titles=Main_Page&unwatch=' => 'Unwatch the page "Main Page"',
                );
        }
 
index 2629995..3690b70 100644 (file)
@@ -166,7 +166,7 @@ class HTMLFileCache extends FileCacheBase {
                        return $text;
                }
 
-               wfDebug( __METHOD__ . "()\n", false );
+               wfDebug( __METHOD__ . "()\n", 'log' );
 
                $now = wfTimestampNow();
                if ( $this->useGzip() ) {
index 9047a47..409160c 100644 (file)
@@ -559,6 +559,7 @@ class LocalisationCache {
                                unset( $data[$key] );
                        }
                }
+
                // The JSON format only supports messages, none of the other variables, so wrap the data
                return array( 'messages' => $data );
        }
@@ -575,7 +576,7 @@ class LocalisationCache {
                try {
                        $compiledRules = CLDRPluralRuleEvaluator::compile( $rules );
                } catch ( CLDRPluralRuleError $e ) {
-                       wfDebugLog( 'l10n', $e->getMessage() . "\n" );
+                       wfDebugLog( 'l10n', $e->getMessage() );
 
                        return array();
                }
index 470b150..b996894 100644 (file)
@@ -248,6 +248,7 @@ class ChangesList extends ContextSource {
        public function endRecentChangesList() {
                $out = $this->rclistOpen ? "</ul>\n" : '';
                $out .= '</div>';
+
                return $out;
        }
 
index 56630a6..9cb1146 100644 (file)
@@ -19,6 +19,7 @@
  *
  * @file
  */
+
 class OldChangesList extends ChangesList {
        /**
         * Format a line using the old system (aka without any javascript).
index 271dd4a..07a9409 100644 (file)
@@ -17,6 +17,7 @@
  *
  * @file
  */
+
 class RCCacheEntry extends RecentChange {
        public $curlink;
        public $difflink;
index 8a6718f..983d90a 100644 (file)
@@ -210,7 +210,7 @@ class RedisConnectionPool {
                        }
                } catch ( RedisException $e ) {
                        $this->downServers[$server] = time() + self::SERVER_DOWN_TTL;
-                       wfDebugLog( 'redis', "Redis exception connecting to $server: " . $e->getMessage() . "\n" );
+                       wfDebugLog( 'redis', "Redis exception connecting to $server: " . $e->getMessage() );
 
                        return false;
                }
@@ -279,7 +279,7 @@ class RedisConnectionPool {
         * @param RedisException $e
         */
        public function handleException( $server, RedisConnRef $cref, RedisException $e ) {
-               wfDebugLog( 'redis', "Redis exception on server $server: " . $e->getMessage() . "\n" );
+               wfDebugLog( 'redis', "Redis exception on server $server: " . $e->getMessage() );
                foreach ( $this->connections[$server] as $key => $connection ) {
                        if ( $cref->isConnIdentical( $connection['conn'] ) ) {
                                $this->idlePoolSize -= $connection['free'] ? 1 : 0;
index 067b1e4..04afdda 100644 (file)
@@ -25,9 +25,7 @@
  *
  * @since 1.23
  */
-
 abstract class Config {
-
        /**
         * @param string $name configuration variable name without prefix
         * @param string $prefix of the variable name
index 1b1cd89..e16a9ee 100644 (file)
@@ -39,6 +39,7 @@ class GlobalConfig extends Config {
         */
        public function set( $name, $value, $prefix = 'wg' ) {
                $GLOBALS[$prefix . $name] = $value;
+
                return Status::newGood();
        }
 }
index a92699b..f495c56 100644 (file)
@@ -202,6 +202,7 @@ class WikitextContent extends TextContent {
         */
        public function getRedirectTarget() {
                list( $title, ) = $this->getRedirectTargetAndText();
+
                return $title;
        }
 
index 978ef03..aabdd9d 100644 (file)
@@ -86,6 +86,7 @@ class RequestContext implements IContextSource {
                if ( $this->config === null ) {
                        $this->config = Config::factory();
                }
+
                return $this->config;
        }
 
index 90e658f..c6f2611 100644 (file)
@@ -2696,7 +2696,10 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                if ( !count( $rows ) ) {
                        return true; // nothing to do
                }
-               $rows = is_array( reset( $rows ) ) ? $rows : array( $rows );
+
+               if ( !is_array( reset( $rows ) ) ) {
+                       $rows = array( $rows );
+               }
 
                if ( count( $uniqueIndexes ) ) {
                        $clauses = array(); // list WHERE clauses that each identify a single row
@@ -2755,7 +2758,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         * @param string $delTable The table to delete from.
         * @param string $joinTable The other table.
         * @param string $delVar The variable to join on, in the first table.
-        * @param string$joinVar The variable to join on, in the second table.
+        * @param string $joinVar The variable to join on, in the second table.
         * @param array $conds Condition array of field names mapped to variables,
         *   ANDed together in the WHERE clause
         * @param string $fname Calling function name (use __METHOD__) for logs/profiling
index 9636da5..8826683 100644 (file)
@@ -984,7 +984,9 @@ class DatabaseMssql extends DatabaseBase {
         * @param array $join_conds
         * @return string
         */
-       protected function tableNamesWithUseIndexOrJOIN( $tables, $use_index = array(), $join_conds = array() ) {
+       protected function tableNamesWithUseIndexOrJOIN( $tables, $use_index = array(),
+               $join_conds = array()
+       ) {
                $ret = array();
                $retJOIN = array();
                $use_index_safe = is_array( $use_index ) ? $use_index : array();
index 647a42a..85be31c 100644 (file)
@@ -996,7 +996,10 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                if ( !count( $rows ) ) {
                        return true; // nothing to do
                }
-               $rows = is_array( reset( $rows ) ) ? $rows : array( $rows );
+
+               if ( !is_array( reset( $rows ) ) ) {
+                       $rows = array( $rows );
+               }
 
                $table = $this->tableName( $table );
                $columns = array_keys( $rows[0] );
index d41f3e4..e202f8a 100644 (file)
@@ -244,6 +244,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
         */
        protected function mysqlFieldType( $res, $n ) {
                $field = $res->fetch_field_direct( $n );
+
                return $field->type;
        }
 
index 6475c8f..c8830d3 100644 (file)
@@ -827,7 +827,9 @@ __INDEXATTR__;
         * can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to do
         * so causes a DB error. This wrapper checks which tables can be locked and adjusts it accordingly.
         */
-       function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__, $options = array(), $join_conds = array() ) {
+       function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__,
+               $options = array(), $join_conds = array()
+       ) {
                if ( is_array( $options ) ) {
                        $forUpdateKey = array_search( 'FOR UPDATE', $options );
                        if ( $forUpdateKey !== false && $join_conds ) {
@@ -1063,7 +1065,7 @@ __INDEXATTR__;
 
        /**
         * Return the next in a sequence, save the value for retrieval via insertId()
-        * 
+        *
         * @param string $seqName
         * @return int|null
         */
@@ -1564,7 +1566,7 @@ SQL;
 
                if ( isset( $options['FOR UPDATE'] ) ) {
                        $postLimitTail .= ' FOR UPDATE OF ' . implode( ', ', $options['FOR UPDATE'] );
-               } else if ( isset( $noKeyOptions['FOR UPDATE'] ) ) {
+               } elseif ( isset( $noKeyOptions['FOR UPDATE'] ) ) {
                        $postLimitTail .= ' FOR UPDATE';
                }
 
index c622afe..e35c4c4 100644 (file)
@@ -144,10 +144,10 @@ class LoadBalancer {
                foreach ( $lags as $i => $lag ) {
                        if ( $i != 0 ) {
                                if ( $lag === false ) {
-                                       wfDebugLog( 'replication', "Server #$i is not replicating\n" );
+                                       wfDebugLog( 'replication', "Server #$i is not replicating" );
                                        unset( $loads[$i] );
                                } elseif ( isset( $this->mServers[$i]['max lag'] ) && $lag > $this->mServers[$i]['max lag'] ) {
-                                       wfDebugLog( 'replication', "Server #$i is excessively lagged ($lag seconds)\n" );
+                                       wfDebugLog( 'replication', "Server #$i is excessively lagged ($lag seconds)" );
                                        unset( $loads[$i] );
                                }
                        }
@@ -240,7 +240,7 @@ class LoadBalancer {
                                $i = $this->getRandomNonLagged( $currentLoads, $wiki );
                                if ( $i === false && count( $currentLoads ) != 0 ) {
                                        # All slaves lagged. Switch to read-only mode
-                                       wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode\n" );
+                                       wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode" );
                                        $wgReadOnly = 'The database has been automatically locked ' .
                                                'while the slave database servers catch up to the master';
                                        $i = ArrayUtils::pickRandom( $currentLoads );
@@ -252,17 +252,17 @@ class LoadBalancer {
                                # pickRandom() returned false
                                # This is permanent and means the configuration or the load monitor
                                # wants us to return false.
-                               wfDebugLog( 'connect', __METHOD__ . ": pickRandom() returned false\n" );
+                               wfDebugLog( 'connect', __METHOD__ . ": pickRandom() returned false" );
 
                                return false;
                        }
 
                        wfDebugLog( 'connect', __METHOD__ .
-                               ": Using reader #$i: {$this->mServers[$i]['host']}...\n" );
+                               ": Using reader #$i: {$this->mServers[$i]['host']}..." );
 
                        $conn = $this->openConnection( $i, $wiki );
                        if ( !$conn ) {
-                               wfDebugLog( 'connect', __METHOD__ . ": Failed connecting to $i/$wiki\n" );
+                               wfDebugLog( 'connect', __METHOD__ . ": Failed connecting to $i/$wiki" );
                                unset( $nonErrorLoads[$i] );
                                unset( $currentLoads[$i] );
                                continue;
@@ -280,7 +280,7 @@ class LoadBalancer {
 
                # If all servers were down, quit now
                if ( !count( $nonErrorLoads ) ) {
-                       wfDebugLog( 'connect', "All servers down\n" );
+                       wfDebugLog( 'connect', "All servers down" );
                }
 
                if ( $i !== false ) {
index d0f8916..d105bd0 100644 (file)
@@ -134,7 +134,7 @@ class MWDebug {
         * @since 1.19
         * @param $msg string
         * @param $callerOffset int
-        * @param $level int A PHP error level. See sendWarning()
+        * @param $level int A PHP error level. See sendMessage()
         * @param $log string: 'production' will always trigger a php error, 'auto'
         *        will trigger an error if $wgDevelopmentWarnings is true, and 'debug'
         *        will only write to the debug log(s).
@@ -154,7 +154,7 @@ class MWDebug {
 
                $callerDescription = self::getCallerDescription( $callerOffset );
 
-               self::sendWarning( $msg, $callerDescription, $level );
+               self::sendMessage( $msg, $callerDescription, 'warning', $level );
 
                if ( self::$enabled ) {
                        self::$log[] = array(
@@ -228,9 +228,10 @@ class MWDebug {
 
                if ( $sendToLog ) {
                        global $wgDevelopmentWarnings; // we could have a more specific $wgDeprecationWarnings setting.
-                       self::sendWarning(
+                       self::sendMessage(
                                $msg,
                                $callerDescription,
+                               'deprecated',
                                $wgDevelopmentWarnings ? E_USER_DEPRECATED : false
                        );
                }
@@ -287,21 +288,22 @@ class MWDebug {
        }
 
        /**
-        * Send a warning to the debug log and optionally also trigger a PHP
+        * Send a message to the debug log and optionally also trigger a PHP
         * error, depending on the $level argument.
         *
         * @param $msg string Message to send
         * @param $caller array caller description get from getCallerDescription()
+        * @param $group string log group on which to send the message
         * @param $level int|bool error level to use; set to false to not trigger an error
         */
-       private static function sendWarning( $msg, $caller, $level ) {
+       private static function sendMessage( $msg, $caller, $group, $level ) {
                $msg .= ' [Called from ' . $caller['func'] . ' in ' . $caller['file'] . ']';
 
                if ( $level !== false ) {
                        trigger_error( $msg, $level );
                }
 
-               wfDebug( "$msg\n" );
+               wfDebugLog( $group, $msg, 'log' );
        }
 
        /**
index 01555ff..79232e5 100644 (file)
@@ -256,7 +256,7 @@ class LinksUpdate extends SqlDataUpdate {
                        $job = new RefreshLinksJob(
                                $title,
                                array(
-                                       'table'     => $table,
+                                       'table' => $table,
                                        'recursive' => true,
                                ) + Job::newRootJobParams( // "overall" refresh links job info
                                        "refreshlinks:{$table}:{$title->getPrefixedText()}"
index 85592e8..0dcff44 100644 (file)
@@ -139,7 +139,7 @@ class SquidUpdate {
                        return;
                }
 
-               wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) . "\n" );
+               wfDebugLog( 'squid', __METHOD__ . ': ' . implode( ' ', $urlArr ) );
 
                if ( $wgHTCPRouting ) {
                        self::HTCPPurge( $urlArr );
@@ -200,7 +200,7 @@ class SquidUpdate {
                if ( !$conn ) {
                        $errstr = socket_strerror( socket_last_error() );
                        wfDebugLog( 'squid', __METHOD__ .
-                               ": Error opening UDP socket: $errstr\n" );
+                               ": Error opening UDP socket: $errstr" );
                        wfProfileOut( __METHOD__ );
 
                        return;
@@ -230,7 +230,7 @@ class SquidUpdate {
                        $conf = self::getRuleForURL( $url, $wgHTCPRouting );
                        if ( !$conf ) {
                                wfDebugLog( 'squid', __METHOD__ .
-                                       "No HTCP rule configured for URL {$url} , skipping\n" );
+                                       "No HTCP rule configured for URL {$url} , skipping" );
                                continue;
                        }
 
@@ -266,7 +266,7 @@ class SquidUpdate {
                                $htcpTransID, $htcpSpecifier, 2 );
 
                        wfDebugLog( 'squid', __METHOD__ .
-                               "Purging URL $url via HTCP\n" );
+                               "Purging URL $url via HTCP" );
                        foreach ( $conf as $subconf ) {
                                socket_sendto( $conn, $htcpPacket, $htcpLen, 0,
                                        $subconf['host'], $subconf['port'] );
index 47135a3..d6cf694 100644 (file)
@@ -88,7 +88,7 @@ class DifferenceEngine extends ContextSource {
         */
        protected $mReducedLineNumbers = false;
 
-       /** @var string Link to action=markpatrolled  */
+       /** @var string Link to action=markpatrolled */
        protected $mMarkPatrolledLink = null;
 
        /** @var bool Show rev_deleted content if allowed */
@@ -965,7 +965,8 @@ class DifferenceEngine extends ContextSource {
                        $limit = 100; // use diff-multi-manyusers if too many users
                        $users = $this->mNewPage->getAuthorsBetween( $oldRev, $newRev, $limit );
                        $numUsers = count( $users );
-                       if( $numUsers == 1 && $users[0] == $newRev->getRawUserText() ) {
+
+                       if ( $numUsers == 1 && $users[0] == $newRev->getRawUserText() ) {
                                $numUsers = 0; // special case to say "by the same user" instead of "by one other user"
                        }
 
index b7e5469..5e7b323 100644 (file)
@@ -187,27 +187,27 @@ class ExternalStoreDB extends ExternalStoreMedium {
                $cacheID = ( $itemID === false ) ? "$cluster/$id" : "$cluster/$id/";
                if ( isset( $externalBlobCache[$cacheID] ) ) {
                        wfDebugLog( 'ExternalStoreDB-cache',
-                               "ExternalStoreDB::fetchBlob cache hit on $cacheID\n" );
+                               "ExternalStoreDB::fetchBlob cache hit on $cacheID" );
 
                        return $externalBlobCache[$cacheID];
                }
 
                wfDebugLog( 'ExternalStoreDB-cache',
-                       "ExternalStoreDB::fetchBlob cache miss on $cacheID\n" );
+                       "ExternalStoreDB::fetchBlob cache miss on $cacheID" );
 
                $dbr = $this->getSlave( $cluster );
                $ret = $dbr->selectField( $this->getTable( $dbr ),
                        'blob_text', array( 'blob_id' => $id ), __METHOD__ );
                if ( $ret === false ) {
                        wfDebugLog( 'ExternalStoreDB',
-                               "ExternalStoreDB::fetchBlob master fallback on $cacheID\n" );
+                               "ExternalStoreDB::fetchBlob master fallback on $cacheID" );
                        // Try the master
                        $dbw = $this->getMaster( $cluster );
                        $ret = $dbw->selectField( $this->getTable( $dbw ),
                                'blob_text', array( 'blob_id' => $id ), __METHOD__ );
                        if ( $ret === false ) {
                                wfDebugLog( 'ExternalStoreDB',
-                                       "ExternalStoreDB::fetchBlob master failed to find $cacheID\n" );
+                                       "ExternalStoreDB::fetchBlob master failed to find $cacheID" );
                        }
                }
                if ( $itemID !== false && $ret !== false ) {
@@ -239,7 +239,7 @@ class ExternalStoreDB extends ExternalStoreMedium {
                if ( $ids ) {
                        wfDebugLog( __CLASS__, __METHOD__ .
                                " master fallback on '$cluster' for: " .
-                               implode( ',', array_keys( $ids ) ) . "\n" );
+                               implode( ',', array_keys( $ids ) ) );
                        // Try the master
                        $dbw = $this->getMaster( $cluster );
                        $res = $dbw->select( $this->getTable( $dbr ),
@@ -247,7 +247,7 @@ class ExternalStoreDB extends ExternalStoreMedium {
                                array( 'blob_id' => array_keys( $ids ) ),
                                __METHOD__ );
                        if ( $res === false ) {
-                               wfDebugLog( __CLASS__, __METHOD__ . " master failed on '$cluster'\n" );
+                               wfDebugLog( __CLASS__, __METHOD__ . " master failed on '$cluster'" );
                        } else {
                                $this->mergeBatchResult( $ret, $ids, $res );
                        }
@@ -255,7 +255,7 @@ class ExternalStoreDB extends ExternalStoreMedium {
                if ( $ids ) {
                        wfDebugLog( __CLASS__, __METHOD__ .
                                " master on '$cluster' failed locating items: " .
-                               implode( ',', array_keys( $ids ) ) . "\n" );
+                               implode( ',', array_keys( $ids ) ) );
                }
 
                return $ret;
index 047aefd..34f6b51 100644 (file)
@@ -30,7 +30,7 @@ class FSFile {
        /** @var string Path to file */
        protected $path;
 
-       /** @var string File SHA-1 in base 36  */
+       /** @var string File SHA-1 in base 36 */
        protected $sha1Base36;
 
        /**
index f5d63b9..00a4d5e 100644 (file)
@@ -105,7 +105,7 @@ abstract class FileBackend {
        protected $fileJournal;
 
        /** Flags for supported features */
-       const ATTR_HEADERS  = 1;
+       const ATTR_HEADERS = 1;
        const ATTR_METADATA = 2;
 
        /**
index 1b2860a..81d088e 100644 (file)
@@ -45,7 +45,7 @@ class FileBackendMultiWrite extends FileBackend {
         */
        protected $backends = array();
 
-       /** @var int Index of master backend  */
+       /** @var int Index of master backend */
        protected $masterIndex = -1;
 
        /** @var int Bitfield */
@@ -569,6 +569,7 @@ class FileBackendMultiWrite extends FileBackend {
 
        public function getFileXAttributes( array $params ) {
                $realParams = $this->substOpPaths( $params, $this->backends[$this->masterIndex] );
+
                return $this->backends[$this->masterIndex]->getFileXAttributes( $realParams );
        }
 
index 13f6436..50371f8 100644 (file)
@@ -724,6 +724,7 @@ abstract class FileBackendStore extends FileBackend {
                wfProfileOut( __METHOD__ . '-miss-' . $this->name );
                wfProfileOut( __METHOD__ . '-miss' );
                $this->cheapCache->set( $path, 'xattr', array( 'map' => $fields, 'latest' => $latest ) );
+
                return $fields;
        }
 
@@ -1681,12 +1682,15 @@ abstract class FileBackendStore extends FileBackend {
         */
        final protected static function normalizeXAttributes( array $xattr ) {
                $newXAttr = array( 'headers' => array(), 'metadata' => array() );
+
                foreach ( $xattr['headers'] as $name => $value ) {
                        $newXAttr['headers'][strtolower( $name )] = $value;
                }
+
                foreach ( $xattr['metadata'] as $name => $value ) {
                        $newXAttr['metadata'][strtolower( $name )] = $value;
                }
+
                return $newXAttr;
        }
 
index 32b65ba..e90fcb7 100644 (file)
@@ -55,13 +55,12 @@ class FileOpBatch {
         * @return Status
         */
        public static function attempt( array $performOps, array $opts, FileJournal $journal ) {
-               wfProfileIn( __METHOD__ );
+               $section = new ProfileSection( __METHOD__ );
                $status = Status::newGood();
 
                $n = count( $performOps );
                if ( $n > self::MAX_BATCH_SIZE ) {
                        $status->fatal( 'backend-fail-batchsize', $n, self::MAX_BATCH_SIZE );
-                       wfProfileOut( __METHOD__ );
 
                        return $status;
                }
@@ -108,8 +107,6 @@ class FileOpBatch {
                                $status->success[$index] = false;
                                ++$status->failCount;
                                if ( !$ignoreErrors ) {
-                                       wfProfileOut( __METHOD__ );
-
                                        return $status; // abort
                                }
                        }
@@ -123,8 +120,6 @@ class FileOpBatch {
                if ( count( $entries ) ) {
                        $subStatus = $journal->logChangeBatch( $entries, $batchId );
                        if ( !$subStatus->isOK() ) {
-                               wfProfileOut( __METHOD__ );
-
                                return $subStatus; // abort
                        }
                }
@@ -136,8 +131,6 @@ class FileOpBatch {
                // Attempt each operation (in parallel if allowed and possible)...
                self::runParallelBatches( $pPerformOps, $status );
 
-               wfProfileOut( __METHOD__ );
-
                return $status;
        }
 
@@ -149,9 +142,8 @@ class FileOpBatch {
         * within any given sub-batch do not depend on each other.
         * This will abort remaining ops on failure.
         *
-        * @param array $pPerformOps
+        * @param array $pPerformOps Batches of file ops (batches use original indexes)
         * @param Status $status
-        * @return bool Success
         */
        protected static function runParallelBatches( array $pPerformOps, Status $status ) {
                $aborted = false; // set to true on unexpected errors
@@ -172,12 +164,8 @@ class FileOpBatch {
                        // If attemptAsync() returns a Status, it was either due to an error
                        // or the backend does not support async ops and did it synchronously.
                        foreach ( $performOpsBatch as $i => $fileOp ) {
-                               if ( !$fileOp->failed() ) { // failed => already has Status
-                                       // If the batch is just one operation, it's faster to avoid
-                                       // pipelining as that can involve creating new TCP connections.
-                                       $subStatus = ( count( $performOpsBatch ) > 1 )
-                                               ? $fileOp->attemptAsync()
-                                               : $fileOp->attempt();
+                               if ( !isset( $status->success[$i] ) ) { // didn't already fail in precheck()
+                                       $subStatus = $fileOp->attemptAsync();
                                        if ( $subStatus->value instanceof FileBackendStoreOpHandle ) {
                                                $opHandles[$i] = $subStatus->value; // deferred
                                        } else {
@@ -189,7 +177,7 @@ class FileOpBatch {
                        $statuses = $statuses + $backend->executeOpHandlesInternal( $opHandles );
                        // Marshall and merge all the responses (blocking)...
                        foreach ( $performOpsBatch as $i => $fileOp ) {
-                               if ( !$fileOp->failed() ) { // failed => already has Status
+                               if ( !isset( $status->success[$i] ) ) { // didn't already fail in precheck()
                                        $subStatus = $statuses[$i];
                                        $status->merge( $subStatus );
                                        if ( $subStatus->isOK() ) {
@@ -203,7 +191,5 @@ class FileOpBatch {
                                }
                        }
                }
-
-               return $status;
        }
 }
index 6f40957..7c2f825 100644 (file)
@@ -45,11 +45,12 @@ class MemoryFileBackend extends FileBackendStore {
                $dst = $this->resolveHashKey( $params['dst'] );
                if ( $dst === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
                        return $status;
                }
 
                $this->files[$dst] = array(
-                       'data'  => $params['content'],
+                       'data' => $params['content'],
                        'mtime' => wfTimestamp( TS_MW, time() )
                );
 
@@ -62,6 +63,7 @@ class MemoryFileBackend extends FileBackendStore {
                $dst = $this->resolveHashKey( $params['dst'] );
                if ( $dst === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
                        return $status;
                }
 
@@ -70,11 +72,12 @@ class MemoryFileBackend extends FileBackendStore {
                wfRestoreWarnings();
                if ( $data === false ) { // source doesn't exist?
                        $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
+
                        return $status;
                }
 
                $this->files[$dst] = array(
-                       'data'  => $data,
+                       'data' => $data,
                        'mtime' => wfTimestamp( TS_MW, time() )
                );
 
@@ -87,12 +90,14 @@ class MemoryFileBackend extends FileBackendStore {
                $src = $this->resolveHashKey( $params['src'] );
                if ( $src === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
                        return $status;
                }
 
                $dst = $this->resolveHashKey( $params['dst'] );
                if ( $dst === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['dst'] );
+
                        return $status;
                }
 
@@ -100,11 +105,12 @@ class MemoryFileBackend extends FileBackendStore {
                        if ( empty( $params['ignoreMissingSource'] ) ) {
                                $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
                        }
+
                        return $status;
                }
 
                $this->files[$dst] = array(
-                       'data'  => $this->files[$src]['data'],
+                       'data' => $this->files[$src]['data'],
                        'mtime' => wfTimestamp( TS_MW, time() )
                );
 
@@ -117,6 +123,7 @@ class MemoryFileBackend extends FileBackendStore {
                $src = $this->resolveHashKey( $params['src'] );
                if ( $src === null ) {
                        $status->fatal( 'backend-fail-invalidpath', $params['src'] );
+
                        return $status;
                }
 
@@ -124,6 +131,7 @@ class MemoryFileBackend extends FileBackendStore {
                        if ( empty( $params['ignoreMissingSource'] ) ) {
                                $status->fatal( 'backend-fail-delete', $params['src'] );
                        }
+
                        return $status;
                }
 
@@ -141,7 +149,7 @@ class MemoryFileBackend extends FileBackendStore {
                if ( isset( $this->files[$src] ) ) {
                        return array(
                                'mtime' => $this->files[$src]['mtime'],
-                               'size'  => strlen( $this->files[$src]['data'] ),
+                               'size' => strlen( $this->files[$src]['data'] ),
                        );
                }
 
@@ -167,6 +175,7 @@ class MemoryFileBackend extends FileBackendStore {
                        }
                        $tmpFiles[$srcPath] = $fsFile;
                }
+
                return $tmpFiles;
        }
 
@@ -176,6 +185,7 @@ class MemoryFileBackend extends FileBackendStore {
                $src = $this->resolveHashKey( $params['src'] );
                if ( $src === null || !isset( $this->files[$src] ) ) {
                        $status->fatal( 'backend-fail-stream', $params['src'] );
+
                        return $status;
                }
 
@@ -191,6 +201,7 @@ class MemoryFileBackend extends FileBackendStore {
                                return true;
                        }
                }
+
                return false;
        }
 
@@ -219,6 +230,7 @@ class MemoryFileBackend extends FileBackendStore {
                                }
                        }
                }
+
                return array_keys( $dirs );
        }
 
@@ -237,6 +249,7 @@ class MemoryFileBackend extends FileBackendStore {
                                $files[] = $relPath;
                        }
                }
+
                return $files;
        }
 
@@ -255,6 +268,7 @@ class MemoryFileBackend extends FileBackendStore {
                if ( $relPath === null ) {
                        return null; // invalid
                }
+
                return ( $relPath !== '' ) ? "$fullCont/$relPath" : $fullCont;
        }
 }
index d6bbfbe..d524cc2 100644 (file)
@@ -176,7 +176,7 @@ class SwiftFileBackend extends FileBackendStore {
                $headers = array();
 
                // Normalize casing, and strip out illegal headers
-               if ( isset( $params['headers'] )  ) {
+               if ( isset( $params['headers'] ) ) {
                        foreach ( $params['headers'] as $name => $value ) {
                                $name = strtolower( $name );
                                if ( preg_match( '/^content-(type|length)$/', $name ) ) {
@@ -220,20 +220,20 @@ class SwiftFileBackend extends FileBackendStore {
                $contentType = $this->getContentType( $params['dst'], $params['content'], null );
 
                $reqs = array( array(
-                       'method'  => 'PUT',
-                       'url'     => array( $dstCont, $dstRel ),
+                       'method' => 'PUT',
+                       'url' => array( $dstCont, $dstRel ),
                        'headers' => array(
-                               'content-length'           => strlen( $params['content'] ),
-                               'etag'                     => md5( $params['content'] ),
-                               'content-type'             => $contentType,
+                               'content-length' => strlen( $params['content'] ),
+                               'etag' => md5( $params['content'] ),
+                               'content-type' => $contentType,
                                'x-object-meta-sha1base36' => $sha1Hash
                        ) + $this->sanitizeHdrs( $params ),
-                       'body'    => $params['content']
+                       'body' => $params['content']
                ) );
 
                $be = $this;
                $method = __METHOD__;
-               $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+               $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
                        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
                        if ( $rcode === 201 ) {
                                // good
@@ -275,7 +275,7 @@ class SwiftFileBackend extends FileBackendStore {
                $sha1Hash = wfBaseConvert( $sha1Hash, 16, 36, 31 );
                $contentType = $this->getContentType( $params['dst'], null, $params['src'] );
 
-               $handle = fopen( $params['src'], 'rb+' );
+               $handle = fopen( $params['src'], 'rb' );
                if ( $handle === false ) { // source doesn't exist?
                        $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
 
@@ -283,20 +283,20 @@ class SwiftFileBackend extends FileBackendStore {
                }
 
                $reqs = array( array(
-                       'method'  => 'PUT',
-                       'url'     => array( $dstCont, $dstRel ),
+                       'method' => 'PUT',
+                       'url' => array( $dstCont, $dstRel ),
                        'headers' => array(
-                               'content-length'           => filesize( $params['src'] ),
-                               'etag'                     => md5_file( $params['src'] ),
-                               'content-type'             => $contentType,
+                               'content-length' => filesize( $params['src'] ),
+                               'etag' => md5_file( $params['src'] ),
+                               'content-type' => $contentType,
                                'x-object-meta-sha1base36' => $sha1Hash
                        ) + $this->sanitizeHdrs( $params ),
-                       'body'    => $handle // resource
+                       'body' => $handle // resource
                ) );
 
                $be = $this;
                $method = __METHOD__;
-               $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+               $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
                        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
                        if ( $rcode === 201 ) {
                                // good
@@ -335,8 +335,8 @@ class SwiftFileBackend extends FileBackendStore {
                }
 
                $reqs = array( array(
-                       'method'  => 'PUT',
-                       'url'     => array( $dstCont, $dstRel ),
+                       'method' => 'PUT',
+                       'url' => array( $dstCont, $dstRel ),
                        'headers' => array(
                                'x-copy-from' => '/' . rawurlencode( $srcCont ) .
                                        '/' . str_replace( "%2F", "/", rawurlencode( $srcRel ) )
@@ -345,7 +345,7 @@ class SwiftFileBackend extends FileBackendStore {
 
                $be = $this;
                $method = __METHOD__;
-               $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+               $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
                        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
                        if ( $rcode === 201 ) {
                                // good
@@ -385,8 +385,8 @@ class SwiftFileBackend extends FileBackendStore {
 
                $reqs = array(
                        array(
-                               'method'  => 'PUT',
-                               'url'     => array( $dstCont, $dstRel ),
+                               'method' => 'PUT',
+                               'url' => array( $dstCont, $dstRel ),
                                'headers' => array(
                                        'x-copy-from' => '/' . rawurlencode( $srcCont ) .
                                                '/' . str_replace( "%2F", "/", rawurlencode( $srcRel ) )
@@ -395,15 +395,15 @@ class SwiftFileBackend extends FileBackendStore {
                );
                if ( "{$srcCont}/{$srcRel}" !== "{$dstCont}/{$dstRel}" ) {
                        $reqs[] = array(
-                               'method'  => 'DELETE',
-                               'url'     => array( $srcCont, $srcRel ),
+                               'method' => 'DELETE',
+                               'url' => array( $srcCont, $srcRel ),
                                'headers' => array()
                        );
                }
 
                $be = $this;
                $method = __METHOD__;
-               $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+               $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
                        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
                        if ( $request['method'] === 'PUT' && $rcode === 201 ) {
                                // good
@@ -436,16 +436,15 @@ class SwiftFileBackend extends FileBackendStore {
                        return $status;
                }
 
-               $reqs = array(
-                       array(
-                               'method'  => 'DELETE',
-                               'url'     => array( $srcCont, $srcRel ),
-                               'headers' => array()
+               $reqs = array( array(
+                       'method' => 'DELETE',
+                       'url' => array( $srcCont, $srcRel ),
+                       'headers' => array()
                ) );
 
                $be = $this;
                $method = __METHOD__;
-               $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+               $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
                        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
                        if ( $rcode === 204 ) {
                                // good
@@ -497,14 +496,14 @@ class SwiftFileBackend extends FileBackendStore {
                $customHdrs = $this->sanitizeHdrs( $params ) + $stat['xattr']['headers'];
 
                $reqs = array( array(
-                       'method'  => 'POST',
-                       'url'     => array( $srcCont, $srcRel ),
+                       'method' => 'POST',
+                       'url' => array( $srcCont, $srcRel ),
                        'headers' => $metaHdrs + $customHdrs
                ) );
 
                $be = $this;
                $method = __METHOD__;
-               $handler = function( array $request, Status $status ) use ( $be, $method, $params ) {
+               $handler = function ( array $request, Status $status ) use ( $be, $method, $params ) {
                        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $request['response'];
                        if ( $rcode === 202 ) {
                                // good
@@ -534,6 +533,7 @@ class SwiftFileBackend extends FileBackendStore {
                        return $status; // already there
                } elseif ( $stat === null ) {
                        $status->fatal( 'backend-fail-internal', $this->name );
+
                        return $status;
                }
 
@@ -603,6 +603,7 @@ class SwiftFileBackend extends FileBackendStore {
                        return $status; // ok, nothing to do
                } elseif ( !is_array( $stat ) ) {
                        $status->fatal( 'backend-fail-internal', $this->name );
+
                        return $status;
                }
 
@@ -636,8 +637,8 @@ class SwiftFileBackend extends FileBackendStore {
 
                // (b) Check the file
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                       'method'  => 'HEAD',
-                       'url'     => $this->storageUrl( $auth, $srcCont, $srcRel ),
+                       'method' => 'HEAD',
+                       'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
                        'headers' => $this->authTokenHeaders( $auth ) + $this->headersFromParams( $params )
                ) );
                if ( $rcode === 200 || $rcode === 204 ) {
@@ -656,9 +657,9 @@ class SwiftFileBackend extends FileBackendStore {
                                // Convert various random Swift dates to TS_MW
                                'mtime' => $this->convertSwiftDate( $rhdrs['last-modified'], TS_MW ),
                                // Empty objects actually return no content-length header in Ceph
-                               'size'  => isset( $rhdrs['content-length'] ) ? (int)$rhdrs['content-length'] : 0,
-                               'sha1'  => $rhdrs[ 'x-object-meta-sha1base36'],
-                               'md5'   => ctype_xdigit( $rhdrs['etag'] ) ? $rhdrs['etag'] : null,
+                               'size' => isset( $rhdrs['content-length'] ) ? (int)$rhdrs['content-length'] : 0,
+                               'sha1' => $rhdrs['x-object-meta-sha1base36'],
+                               'md5' => ctype_xdigit( $rhdrs['etag'] ) ? $rhdrs['etag'] : null,
                                'xattr' => array( 'metadata' => $metadata, 'headers' => $headers )
                        );
                } elseif ( $rcode === 404 ) {
@@ -684,6 +685,7 @@ class SwiftFileBackend extends FileBackendStore {
        protected function convertSwiftDate( $ts, $format = TS_MW ) {
                try {
                        $timestamp = new MWTimestamp( $ts );
+
                        return $timestamp->getTimestamp( $format );
                } catch ( MWException $e ) {
                        throw new FileBackendError( $e->getMessage() );
@@ -708,6 +710,7 @@ class SwiftFileBackend extends FileBackendStore {
                $auth = $this->getAuthentication();
                if ( !$auth ) {
                        $objHdrs['x-object-meta-sha1base36'] = false;
+
                        return $objHdrs; // failed
                }
 
@@ -721,8 +724,8 @@ class SwiftFileBackend extends FileBackendStore {
                                        $objHdrs['x-object-meta-sha1base36'] = $hash;
                                        list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $path );
                                        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                                               'method'  => 'POST',
-                                               'url'     => $this->storageUrl( $auth, $srcCont, $srcRel ),
+                                               'method' => 'POST',
+                                               'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
                                                'headers' => $this->authTokenHeaders( $auth ) + $objHdrs
                                        ) );
                                        if ( $rcode >= 200 && $rcode <= 299 ) {
@@ -759,11 +762,11 @@ class SwiftFileBackend extends FileBackendStore {
                                $handle = fopen( 'php://temp', 'wb' );
                                if ( $handle ) {
                                        $reqs[$path] = array(
-                                               'method'  => 'GET',
-                                               'url'     => $this->storageUrl( $auth, $srcCont, $srcRel ),
+                                               'method' => 'GET',
+                                               'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
                                                'headers' => $this->authTokenHeaders( $auth )
                                                        + $this->headersFromParams( $params ),
-                                               'stream'  => $handle,
+                                               'stream' => $handle,
                                        );
                                } else {
                                        $data = false;
@@ -796,6 +799,7 @@ class SwiftFileBackend extends FileBackendStore {
                if ( $status->isOk() ) {
                        return ( count( $status->value ) );
                }
+
                return null; // error
        }
 
@@ -853,20 +857,25 @@ class SwiftFileBackend extends FileBackendStore {
                                        $dirs[] = $object; // directories end in '/'
                                }
                        }
-               // Recursive: list all dirs under $dir and its subdirs
                } else {
-                       $getParentDir = function( $path ) {
+                       // Recursive: list all dirs under $dir and its subdirs
+                       $getParentDir = function ( $path ) {
                                return ( strpos( $path, '/' ) !== false ) ? dirname( $path ) : false;
                        };
+
                        // Get directory from last item of prior page
                        $lastDir = $getParentDir( $after ); // must be first page
                        $status = $this->objectListing( $fullCont, 'names', $limit, $after, $prefix );
+
                        if ( !$status->isOk() ) {
                                return $dirs; // error
                        }
+
                        $objects = $status->value;
+
                        foreach ( $objects as $object ) { // files
                                $objectDir = $getParentDir( $object ); // directory of object
+
                                if ( $objectDir !== false && $objectDir !== $dir ) {
                                        // Swift stores paths in UTF-8, using binary sorting.
                                        // See function "create_container_table" in common/db.py.
@@ -924,20 +933,23 @@ class SwiftFileBackend extends FileBackendStore {
                        } else {
                                $status = $this->objectListing( $fullCont, 'names', $limit, $after, $prefix, '/' );
                        }
-               // Recursive: list all files under $dir and its subdirs
                } else {
+                       // Recursive: list all files under $dir and its subdirs
                        if ( !empty( $params['adviseStat'] ) ) {
                                $status = $this->objectListing( $fullCont, 'info', $limit, $after, $prefix );
                        } else {
                                $status = $this->objectListing( $fullCont, 'names', $limit, $after, $prefix );
                        }
                }
+
                // Reformat this list into a list of (name, stat array or null) entries
                if ( !$status->isOk() ) {
                        return $files; // error
                }
+
                $objects = $status->value;
                $files = $this->buildFileObjectListing( $params, $dir, $objects );
+
                // Page on the unfiltered object listing (what is returned may be filtered)
                if ( count( $objects ) < $limit ) {
                        $after = INF; // avoid a second RTT
@@ -967,9 +979,9 @@ class SwiftFileBackend extends FileBackendStore {
                                }
                                $stat = array(
                                        // Convert various random Swift dates to TS_MW
-                                       'mtime'  => $this->convertSwiftDate( $object->last_modified, TS_MW ),
-                                       'size'   => (int)$object->bytes,
-                                       'md5'    => ctype_xdigit( $object->hash ) ? $object->hash : null,
+                                       'mtime' => $this->convertSwiftDate( $object->last_modified, TS_MW ),
+                                       'size' => (int)$object->bytes,
+                                       'md5' => ctype_xdigit( $object->hash ) ? $object->hash : null,
                                        'latest' => false // eventually consistent
                                );
                                $names[] = array( $object->name, $stat );
@@ -1000,6 +1012,7 @@ class SwiftFileBackend extends FileBackendStore {
                                $this->clearCache( array( $params['src'] ) );
                                $stat = $this->getFileStat( $params );
                        }
+
                        return $stat['xattr'];
                } else {
                        return false;
@@ -1032,17 +1045,18 @@ class SwiftFileBackend extends FileBackendStore {
                $auth = $this->getAuthentication();
                if ( !$auth || !is_array( $this->getContainerStat( $srcCont ) ) ) {
                        $status->fatal( 'backend-fail-stream', $params['src'] );
+
                        return $status;
                }
 
                $handle = fopen( 'php://output', 'wb' );
 
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                       'method'  => 'GET',
-                       'url'     => $this->storageUrl( $auth, $srcCont, $srcRel ),
+                       'method' => 'GET',
+                       'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
                        'headers' => $this->authTokenHeaders( $auth )
                                + $this->headersFromParams( $params ),
-                       'stream'  => $handle,
+                       'stream' => $handle,
                ) );
 
                if ( $rcode >= 200 && $rcode <= 299 ) {
@@ -1082,11 +1096,11 @@ class SwiftFileBackend extends FileBackendStore {
                                        $handle = fopen( $tmpFile->getPath(), 'wb' );
                                        if ( $handle ) {
                                                $reqs[$path] = array(
-                                                       'method'  => 'GET',
-                                                       'url'     => $this->storageUrl( $auth, $srcCont, $srcRel ),
+                                                       'method' => 'GET',
+                                                       'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
                                                        'headers' => $this->authTokenHeaders( $auth )
                                                                + $this->headersFromParams( $params ),
-                                                       'stream'  => $handle,
+                                                       'stream' => $handle,
                                                );
                                        } else {
                                                $tmpFile = null;
@@ -1142,6 +1156,7 @@ class SwiftFileBackend extends FileBackendStore {
                                        "GET\n{$expires}\n{$contPath}/{$srcRel}",
                                        $this->swiftTempUrlKey
                                );
+
                                return "{$url}?temp_url_sig={$signature}&temp_url_expires={$expires}";
                        } else { // give S3 API URL for rgw
                                // Path for signature starts with the bucket
@@ -1199,6 +1214,7 @@ class SwiftFileBackend extends FileBackendStore {
                        foreach ( $fileOpHandles as $index => $fileOpHandle ) {
                                $statuses[$index] = Status::newFatal( 'backend-fail-connect', $this->name );
                        }
+
                        return $statuses;
                }
 
@@ -1218,7 +1234,8 @@ class SwiftFileBackend extends FileBackendStore {
                }
 
                // Run all requests for the first stage, then the next, and so on
-               for ( $stage = 0; $stage < count( $httpReqsByStage ); ++$stage ) {
+               $reqCount = count( $httpReqsByStage );
+               for ( $stage = 0; $stage < $reqCount; ++$stage ) {
                        $httpReqs = $this->http->runMulti( $httpReqsByStage[$stage] );
                        foreach ( $httpReqs as $index => $httpReq ) {
                                // Run the callback for each request of this operation
@@ -1262,18 +1279,19 @@ class SwiftFileBackend extends FileBackendStore {
         */
        protected function setContainerAccess( $container, array $readGrps, array $writeGrps ) {
                $status = Status::newGood();
-
                $auth = $this->getAuthentication();
+
                if ( !$auth ) {
                        $status->fatal( 'backend-fail-connect', $this->name );
+
                        return $status;
                }
 
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                       'method'  => 'POST',
-                       'url'     => $this->storageUrl( $auth, $container ),
+                       'method' => 'POST',
+                       'url' => $this->storageUrl( $auth, $container ),
                        'headers' => $this->authTokenHeaders( $auth ) + array(
-                               'x-container-read'  => implode( ',', $readGrps ),
+                               'x-container-read' => implode( ',', $readGrps ),
                                'x-container-write' => implode( ',', $writeGrps )
                        )
                ) );
@@ -1306,8 +1324,8 @@ class SwiftFileBackend extends FileBackendStore {
                        }
 
                        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                               'method'  => 'HEAD',
-                               'url'     => $this->storageUrl( $auth, $container ),
+                               'method' => 'HEAD',
+                               'url' => $this->storageUrl( $auth, $container ),
                                'headers' => $this->authTokenHeaders( $auth )
                        ) );
 
@@ -1326,6 +1344,7 @@ class SwiftFileBackend extends FileBackendStore {
                        } else {
                                $this->onError( null, __METHOD__,
                                        array( 'cont' => $container ), $rerr, $rcode, $rdesc );
+
                                return null;
                        }
                }
@@ -1346,6 +1365,7 @@ class SwiftFileBackend extends FileBackendStore {
                $auth = $this->getAuthentication();
                if ( !$auth ) {
                        $status->fatal( 'backend-fail-connect', $this->name );
+
                        return $status;
                }
 
@@ -1358,10 +1378,10 @@ class SwiftFileBackend extends FileBackendStore {
                $writeGrps = array( $this->swiftUser ); // sanity
 
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                       'method'  => 'PUT',
-                       'url'     => $this->storageUrl( $auth, $container ),
+                       'method' => 'PUT',
+                       'url' => $this->storageUrl( $auth, $container ),
                        'headers' => $this->authTokenHeaders( $auth ) + array(
-                               'x-container-read'  => implode( ',', $readGrps ),
+                               'x-container-read' => implode( ',', $readGrps ),
                                'x-container-write' => implode( ',', $writeGrps )
                        )
                ) );
@@ -1390,12 +1410,13 @@ class SwiftFileBackend extends FileBackendStore {
                $auth = $this->getAuthentication();
                if ( !$auth ) {
                        $status->fatal( 'backend-fail-connect', $this->name );
+
                        return $status;
                }
 
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                       'method'  => 'DELETE',
-                       'url'     => $this->storageUrl( $auth, $container ),
+                       'method' => 'DELETE',
+                       'url' => $this->storageUrl( $auth, $container ),
                        'headers' => $this->authTokenHeaders( $auth )
                ) );
 
@@ -1432,6 +1453,7 @@ class SwiftFileBackend extends FileBackendStore {
                $auth = $this->getAuthentication();
                if ( !$auth ) {
                        $status->fatal( 'backend-fail-connect', $this->name );
+
                        return $status;
                }
 
@@ -1450,9 +1472,9 @@ class SwiftFileBackend extends FileBackendStore {
                }
 
                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                       'method'  => 'GET',
-                       'url'     => $this->storageUrl( $auth, $fullCont ),
-                       'query'   => $query,
+                       'method' => 'GET',
+                       'url' => $this->storageUrl( $auth, $fullCont ),
+                       'query' => $query,
                        'headers' => $this->authTokenHeaders( $auth )
                ) );
 
@@ -1505,29 +1527,34 @@ class SwiftFileBackend extends FileBackendStore {
                                $this->authSessionTimestamp = time() - ceil( $this->authTTL / 2 );
                        } else { // cache miss
                                list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                                       'method'  => 'GET',
-                                       'url'     => "{$this->swiftAuthUrl}/v1.0",
+                                       'method' => 'GET',
+                                       'url' => "{$this->swiftAuthUrl}/v1.0",
                                        'headers' => array(
-                                               'x-auth-user' => $this->swiftUser, 'x-auth-key' => $this->swiftKey )
+                                               'x-auth-user' => $this->swiftUser,
+                                               'x-auth-key' => $this->swiftKey
+                                       )
                                ) );
 
                                if ( $rcode >= 200 && $rcode <= 299 ) { // OK
                                        $this->authCreds = array(
-                                               'auth_token'  => $rhdrs['x-auth-token'],
+                                               'auth_token' => $rhdrs['x-auth-token'],
                                                'storage_url' => $rhdrs['x-storage-url']
                                        );
                                        $this->authSessionTimestamp = time();
                                } elseif ( $rcode === 401 ) {
                                        $this->onError( null, __METHOD__, array(), "Authentication failed.", $rcode );
                                        $this->authErrorTimestamp = time();
+
                                        return null;
                                } else {
                                        $this->onError( null, __METHOD__, array(), "HTTP return code: $rcode", $rcode );
                                        $this->authErrorTimestamp = time();
+
                                        return null;
                                }
                        }
                }
+
                return $this->authCreds;
        }
 
@@ -1545,6 +1572,7 @@ class SwiftFileBackend extends FileBackendStore {
                if ( strlen( $object ) ) {
                        $parts[] = str_replace( "%2F", "/", rawurlencode( $object ) );
                }
+
                return implode( '/', $parts );
        }
 
index d17074e..a692012 100644 (file)
@@ -178,8 +178,8 @@ abstract class QuorumLockManager extends LockManager {
                foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
                        if ( !$this->isServerUp( $lockSrv ) ) {
                                $status->warning( 'lockmanager-fail-svr-release', $lockSrv );
-                       // Attempt to release the lock on this peer
                        } else {
+                               // Attempt to release the lock on this peer
                                $status->merge( $this->freeLocksOnServer( $lockSrv, $pathsByType ) );
                                ++$yesVotes; // success for this peer
                                // Normally the first peers form the quorum, and the others are ignored.
index ca8c219..534d7f2 100644 (file)
@@ -55,7 +55,7 @@ class FileRepo {
        /** @var Array Map of zones to config */
        protected $zones = array();
 
-       /** @var string URL of thumb.php  */
+       /** @var string URL of thumb.php */
        protected $thumbScriptUrl;
 
        /** @var bool Whether to skip media file transformation on parse and rely
@@ -111,7 +111,7 @@ class FileRepo {
         */
        protected $abbrvThreshold;
 
-       /** @var string The URL of the repo's favicon, if any  */
+       /** @var string The URL of the repo's favicon, if any */
        protected $favicon;
 
        /**
@@ -505,7 +505,7 @@ class FileRepo {
                                $searchName = File::normalizeTitle( $title )->getDBkey(); // must be valid
                                if ( $flags & self::NAME_AND_TIME_ONLY ) {
                                        $result[$searchName] = array(
-                                               'title'     => $file->getTitle()->getDBkey(),
+                                               'title' => $file->getTitle()->getDBkey(),
                                                'timestamp' => $file->getTimestamp()
                                        );
                                } else {
index 8ae53de..4e48932 100644 (file)
@@ -59,10 +59,10 @@ class ForeignAPIRepo extends FileRepo {
        /** @var int Redownload thumbnail files after a month (86400*30) */
        protected $fileCacheExpiry = 2592000;
 
-       /** @var array  */
+       /** @var array */
        protected $mFileExists = array();
 
-       /** @var array  */
+       /** @var array */
        private $mQueryCache = array();
 
        /**
index bcccb71..3f7adb0 100644 (file)
@@ -258,11 +258,12 @@ class LocalRepo extends FileRepo {
                        }
                }
 
-               $fileMatchesSearch = function( File $file, array $search ) {
+               $fileMatchesSearch = function ( File $file, array $search ) {
                        // Note: file name comparison done elsewhere (to handle redirects)
                        $user = ( !empty( $search['private'] ) && $search['private'] instanceof User )
                                ? $search['private']
                                : null;
+
                        return (
                                $file->exists() &&
                                (
@@ -275,7 +276,7 @@ class LocalRepo extends FileRepo {
                };
 
                $repo = $this;
-               $applyMatchingFiles = function( ResultWrapper $res, &$searchSet, &$finalFiles )
+               $applyMatchingFiles = function ( ResultWrapper $res, &$searchSet, &$finalFiles )
                        use ( $repo, $fileMatchesSearch, $flags )
                {
                        global $wgContLang;
@@ -290,7 +291,7 @@ class LocalRepo extends FileRepo {
                                        $dbKeysLook[] = $wgContLang->lcfirst( $file->getName() );
                                }
                                foreach ( $dbKeysLook as $dbKey ) {
-                                       if ( isset( $searchSet[$dbKey])
+                                       if ( isset( $searchSet[$dbKey] )
                                                && $fileMatchesSearch( $file, $searchSet[$dbKey] )
                                        ) {
                                                $finalFiles[$dbKey] = ( $flags & FileRepo::NAME_AND_TIME_ONLY )
@@ -309,6 +310,7 @@ class LocalRepo extends FileRepo {
                foreach ( array_keys( $searchSet ) as $dbKey ) {
                        $imgNames[] = $this->getNameFromTitle( File::normalizeTitle( $dbKey ) );
                }
+
                if ( count( $imgNames ) ) {
                        $res = $dbr->select( 'image',
                                LocalFile::selectFields(), array( 'img_name' => $imgNames ), __METHOD__ );
@@ -328,6 +330,7 @@ class LocalRepo extends FileRepo {
                                );
                        }
                }
+
                if ( count( $oiConds ) ) {
                        $res = $dbr->select( 'oldimage',
                                OldLocalFile::selectFields(), $dbr->makeList( $oiConds, LIST_OR ), __METHOD__ );
@@ -339,15 +342,17 @@ class LocalRepo extends FileRepo {
                        if ( !empty( $search['ignoreRedirect'] ) ) {
                                continue;
                        }
+
                        $title = File::normalizeTitle( $dbKey );
                        $redir = $this->checkRedirect( $title ); // hopefully hits memcached
+
                        if ( $redir && $redir->getNamespace() == NS_FILE ) {
                                $file = $this->newFile( $redir );
                                if ( $file && $fileMatchesSearch( $file, $search ) ) {
                                        $file->redirectedFrom( $title->getDBkey() );
                                        if ( $flags & FileRepo::NAME_AND_TIME_ONLY ) {
                                                $finalFiles[$dbKey] = array(
-                                                       'title'     => $file->getTitle()->getDBkey(),
+                                                       'title' => $file->getTitle()->getDBkey(),
                                                        'timestamp' => $file->getTimestamp()
                                                );
                                        } else {
@@ -503,6 +508,7 @@ class LocalRepo extends FileRepo {
         */
        function getInfo() {
                global $wgFavicon;
+
                return array_merge( parent::getInfo(), array(
                        'favicon' => wfExpandUrl( $wgFavicon ),
                ) );
index 33ab8ae..18432a1 100644 (file)
@@ -42,7 +42,7 @@ class RepoGroup {
        /** @var array */
        protected $foreignInfo;
 
-       /** @var ProcessCacheLRU  */
+       /** @var ProcessCacheLRU */
        protected $cache;
 
        /** @var RepoGroup */
index 26699c4..439c25f 100644 (file)
@@ -470,7 +470,6 @@ class ArchivedFile {
                }
 
                throw new MWException( "Unknown type '$type'." );
-
        }
 
        /**
index c9e435e..950baea 100644 (file)
@@ -97,10 +97,10 @@ abstract class File {
        /** @var Title|string|bool */
        protected $title;
 
-       /** @var string Text of last error  */
+       /** @var string Text of last error */
        protected $lastError;
 
-       /** @var string Main part of the title, with underscores (Title::getDBkey)  */
+       /** @var string Main part of the title, with underscores (Title::getDBkey) */
        protected $redirected;
 
        /** @var Title */
@@ -586,6 +586,7 @@ abstract class File {
                if ( !$handler ) {
                        return false;
                }
+
                return $handler->getCommonMetaArray( $this );
        }
 
@@ -1328,7 +1329,7 @@ abstract class File {
                $this->assertRepoDefined();
 
                return $this->repo->getZonePath( 'thumb' ) . '/' .
-                       $this->getArchiveThumbRel( $archiveName, $suffix );
+               $this->getArchiveThumbRel( $archiveName, $suffix );
        }
 
        /**
index 687c549..c7b257a 100644 (file)
@@ -2249,10 +2249,10 @@ class LocalFileRestoreBatch {
        /** @var array List of file IDs to restore */
        private $ids;
 
-       /** @var bool Add all revisions of the file  */
+       /** @var bool Add all revisions of the file */
        private $all;
 
-       /** @var bool Wether to remove all settings for suppressed fields  */
+       /** @var bool Wether to remove all settings for suppressed fields */
        private $unsuppress = false;
 
        /**
@@ -2620,16 +2620,12 @@ class LocalFileMoveBatch {
        /** @var Title */
        protected $target;
 
-       /** @var   */
        protected $cur;
 
-       /** @var   */
        protected $olds;
 
-       /** @var   */
        protected $oldCount;
 
-       /** @var   */
        protected $archive;
 
        /** @var DatabaseBase */
index 782e23a..5a3e4e9 100644 (file)
@@ -34,7 +34,7 @@
  * @ingroup FileAbstraction
  */
 class UnregisteredLocalFile extends File {
-       /** @var Title  */
+       /** @var Title */
        protected $title;
 
        /** @var string */
index a341601..d2e4689 100644 (file)
  * @ingroup Media
  */
 abstract class ImageGalleryBase extends ContextSource {
-       /** @var array Gallery images  */
+       /** @var array Gallery images */
        protected $mImages;
 
-       /** @var bool Whether to show the filesize in bytes in categories   */
+       /** @var bool Whether to show the filesize in bytes in categories */
        protected $mShowBytes;
 
        /** @var bool Whether to show the filename. Default: true */
@@ -242,7 +242,7 @@ abstract class ImageGalleryBase extends ContextSource {
         * @param string $html Additional HTML text to be shown. The name and size
         *   of the image are always shown.
         * @param string $alt Alt text for the image
-        * @param string $link  Override image link (optional)
+        * @param string $link Override image link (optional)
         * @param array $handlerOpts Array of options for image handler (aka page number)
         */
        function insert( $title, $html = '', $alt = '', $link = '', $handlerOpts = array() ) {
index 1e8da45..f3b7ce7 100644 (file)
@@ -812,8 +812,14 @@ class HTMLForm extends ContextSource {
                        if ( $this->isVForm() ) {
                                // mw-ui-block is necessary because the buttons aren't necessarily in an
                                // immediate child div of the vform.
-                               // TODO Let client specify if the primary submit button is progressive or destructive
-                               array_push( $attribs['class'], 'mw-ui-button', 'mw-ui-big', 'mw-ui-constructive', 'mw-ui-block' );
+                               // @todo Let client specify if the primary submit button is progressive or destructive
+                               array_push(
+                                       $attribs['class'],
+                                       'mw-ui-button',
+                                       'mw-ui-big',
+                                       'mw-ui-constructive',
+                                       'mw-ui-block'
+                               );
                        }
 
                        $html .= Xml::submitButton( $this->getSubmitText(), $attribs ) . "\n";
index 622dd94..dcdba1e 100644 (file)
@@ -495,7 +495,7 @@ abstract class HTMLFormField {
 
                $ret = array();
 
-               foreach( $list as $key ) {
+               foreach ( $list as $key ) {
                        if ( in_array( $key, $boolAttribs ) ) {
                                if ( !empty( $this->mParams[$key] ) ) {
                                        $ret[$key] = '';
index 79a42ba..edc0feb 100644 (file)
@@ -641,15 +641,19 @@ abstract class Installer {
                if ( !$status->isOK() ) {
                        return $status;
                }
-               $status->value->insert( 'site_stats', array(
-                       'ss_row_id' => 1,
-                       'ss_total_views' => 0,
-                       'ss_total_edits' => 0,
-                       'ss_good_articles' => 0,
-                       'ss_total_pages' => 0,
-                       'ss_users' => 0,
-                       'ss_images' => 0 ),
-                       __METHOD__, 'IGNORE' );
+               $status->value->insert(
+                       'site_stats',
+                       array(
+                               'ss_row_id' => 1,
+                               'ss_total_views' => 0,
+                               'ss_total_edits' => 0,
+                               'ss_good_articles' => 0,
+                               'ss_total_pages' => 0,
+                               'ss_users' => 0,
+                               'ss_images' => 0
+                       ),
+                       __METHOD__, 'IGNORE'
+               );
 
                return Status::newGood();
        }
index 68664c9..77c35b8 100644 (file)
@@ -223,7 +223,8 @@ class LocalSettingsGenerator {
                        }
                        if ( $this->groupPermissions['*']['edit'] === false
                                && $this->groupPermissions['*']['createaccount'] === false
-                               && $this->groupPermissions['*']['read'] !== false ) {
+                               && $this->groupPermissions['*']['read'] !== false
+                       ) {
                                $noFollow = "\n# Set \$wgNoFollowLinks to true if you open up your wiki to editing by\n"
                                        . "# the general public and wish to apply nofollow to external links as a\n"
                                        . "# deterrent to spammers. Nofollow is not a comprehensive anti-spam solution\n"
index 9dfbff8..33ff65e 100644 (file)
@@ -28,7 +28,6 @@
  * @since 1.17
  */
 class MysqlUpdater extends DatabaseUpdater {
-
        protected function getCoreUpdateList() {
                return array(
                        array( 'disableContentHandlerUseDB' ),
@@ -246,8 +245,9 @@ class MysqlUpdater extends DatabaseUpdater {
 
                        // 1.23
                        array( 'addField', 'recentchanges', 'rc_source', 'patch-rc_source.sql' ),
-                       array( 'addIndex', 'logging', 'log_user_text_type_time',  'patch-logging_user_text_type_time_index.sql' ),
-                       array( 'addIndex', 'logging', 'log_user_text_time',  'patch-logging_user_text_time_index.sql' ),
+                       array( 'addIndex', 'logging', 'log_user_text_type_time',
+                               'patch-logging_user_text_type_time_index.sql' ),
+                       array( 'addIndex', 'logging', 'log_user_text_time', 'patch-logging_user_text_time_index.sql' ),
                        array( 'addField', 'page', 'page_links_updated', 'patch-page_links_updated.sql' ),
                );
        }
index 88e5fbd..6c56b3a 100644 (file)
@@ -94,8 +94,8 @@ class OracleUpdater extends DatabaseUpdater {
                                'patch-ufg_group-length-increase-255.sql' ),
 
                        //1.23
-                       array( 'addIndex', 'logging', 'i06',  'patch-logging_user_text_type_time_index.sql' ),
-                       array( 'addIndex', 'logging', 'i07',  'patch-logging_user_text_time_index.sql' ),
+                       array( 'addIndex', 'logging', 'i06', 'patch-logging_user_text_type_time_index.sql' ),
+                       array( 'addIndex', 'logging', 'i07', 'patch-logging_user_text_time_index.sql' ),
 
                        // KEEP THIS AT THE BOTTOM!!
                        array( 'doRebuildDuplicateFunction' ),
index cd5a8ad..1e0651c 100644 (file)
@@ -27,7 +27,6 @@
  * @ingroup Deployment
  * @since 1.17
  */
-
 class PostgresUpdater extends DatabaseUpdater {
 
        /**
@@ -260,7 +259,8 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addPgIndex', 'job', 'job_cmd_token', '(job_cmd, job_token, job_random)' ),
                        array( 'addPgIndex', 'job', 'job_cmd_token_id', '(job_cmd, job_token, job_id)' ),
                        array( 'addPgIndex', 'filearchive', 'fa_sha1', '(fa_sha1)' ),
-                       array( 'addPgIndex', 'logging', 'logging_user_text_type_time', '(log_user_text, log_type, log_timestamp)' ),
+                       array( 'addPgIndex', 'logging', 'logging_user_text_type_time',
+                               '(log_user_text, log_type, log_timestamp)' ),
                        array( 'addPgIndex', 'logging', 'logging_user_text_time', '(log_user_text, log_timestamp)' ),
 
                        array( 'checkIndex', 'pagelink_unique', array(
index 3db3758..2869d1f 100644 (file)
@@ -123,8 +123,9 @@ class SqliteUpdater extends DatabaseUpdater {
 
                        // 1.23
                        array( 'addField', 'recentchanges', 'rc_source', 'patch-rc_source.sql' ),
-                       array( 'addIndex', 'logging', 'log_user_text_type_time',  'patch-logging_user_text_type_time_index.sql' ),
-                       array( 'addIndex', 'logging', 'log_user_text_time',  'patch-logging_user_text_time_index.sql' ),
+                       array( 'addIndex', 'logging', 'log_user_text_type_time',
+                               'patch-logging_user_text_type_time_index.sql' ),
+                       array( 'addIndex', 'logging', 'log_user_text_time', 'patch-logging_user_text_time_index.sql' ),
                        array( 'addField', 'page', 'page_links_updated', 'patch-page_links_updated.sql' ),
                );
        }
index 67236e5..131431a 100644 (file)
@@ -1291,7 +1291,7 @@ class WebInstaller_Complete extends WebInstallerPage {
                ) {
                        // JS appears to be the only method that works consistently with IE7+
                        $this->addHtml( "\n<script>jQuery( function () { document.location = " .
-                       Xml::encodeJsVar( $lsUrl ) . "; } );</script>\n" );
+                               Xml::encodeJsVar( $lsUrl ) . "; } );</script>\n" );
                } else {
                        $this->parent->request->response()->header( "Refresh: 0;url=$lsUrl" );
                }
index 212871e..e0641b5 100644 (file)
@@ -300,7 +300,7 @@ LUA;
                // Push ready delayed jobs into the queue every 10 jobs to spread the load.
                // This is also done as a periodic task, but we don't want too much done at once.
                if ( $this->checkDelay && mt_rand( 0, 9 ) == 0 ) {
-                       $this->releaseReadyDelayedJobs();
+                       $this->recyclePruneAndUndelayJobs();
                }
 
                $conn = $this->getConnection();
@@ -309,7 +309,7 @@ LUA;
                                if ( $this->claimTTL > 0 ) {
                                        // Keep the claimed job list down for high-traffic queues
                                        if ( mt_rand( 0, 99 ) == 0 ) {
-                                               $this->recycleAndDeleteStaleJobs();
+                                               $this->recyclePruneAndUndelayJobs();
                                        }
                                        $blob = $this->popAndAcquireBlob( $conn );
                                } else {
@@ -326,7 +326,7 @@ LUA;
                                        continue;
                                }
 
-                               // If $item is invalid, recycleAndDeleteStaleJobs() will cleanup as needed
+                               // If $item is invalid, recyclePruneAndUndelayJobs() will cleanup as needed
                                $job = $this->getJobFromFields( $item ); // may be false
                        } while ( !$job ); // job may be false if invalid
                } catch ( RedisException $e ) {
@@ -627,54 +627,14 @@ LUA;
                }
        }
 
-       /**
-        * Release any ready delayed jobs into the queue
-        *
-        * @return int Number of jobs released
-        * @throws JobQueueError
-        */
-       public function releaseReadyDelayedJobs() {
-               $count = 0;
-
-               $conn = $this->getConnection();
-               try {
-                       static $script =
-<<<LUA
-                       local kDelayed, kUnclaimed = unpack(KEYS)
-                       -- Get the list of ready delayed jobs, sorted by readiness
-                       local ids = redis.call('zRangeByScore',kDelayed,0,ARGV[1])
-                       -- Migrate the jobs from the "delayed" set to the "unclaimed" list
-                       for k,id in ipairs(ids) do
-                               redis.call('lPush',kUnclaimed,id)
-                               redis.call('zRem',kDelayed,id)
-                       end
-                       return #ids
-LUA;
-                       $count += (int)$conn->luaEval( $script,
-                               array(
-                                       $this->getQueueKey( 'z-delayed' ), // KEYS[1]
-                                       $this->getQueueKey( 'l-unclaimed' ), // KEYS[2]
-                                       time() // ARGV[1]; max "delay until" UNIX timestamp
-                               ),
-                               2 # first two arguments are keys
-                       );
-               } catch ( RedisException $e ) {
-                       $this->throwRedisException( $this->server, $conn, $e );
-               }
-
-               return $count;
-       }
-
        /**
         * Recycle or destroy any jobs that have been claimed for too long
+        * and release any ready delayed jobs into the queue
         *
-        * @return int Number of jobs recycled/deleted
+        * @return int Number of jobs recycled/deleted/undelayed
         * @throws MWException|JobQueueError
         */
-       public function recycleAndDeleteStaleJobs() {
-               if ( $this->claimTTL <= 0 ) { // sanity
-                       throw new MWException( "Cannot recycle jobs since acknowledgements are disabled." );
-               }
+       public function recyclePruneAndUndelayJobs() {
                $count = 0;
                // For each job item that can be retried, we need to add it back to the
                // main queue and remove it from the list of currenty claimed job items.
@@ -685,8 +645,8 @@ LUA;
                        $now = time();
                        static $script =
 <<<LUA
-                       local kClaimed, kAttempts, kUnclaimed, kData, kAbandoned = unpack(KEYS)
-                       local released,abandoned,pruned = 0,0,0
+                       local kClaimed, kAttempts, kUnclaimed, kData, kAbandoned, kDelayed = unpack(KEYS)
+                       local released,abandoned,pruned,undelayed = 0,0,0,0
                        -- Get all non-dead jobs that have an expired claim on them.
                        -- The score for each item is the last claim timestamp (UNIX).
                        local staleClaims = redis.call('zRangeByScore',kClaimed,0,ARGV[1])
@@ -715,7 +675,15 @@ LUA;
                                redis.call('hDel',kData,id)
                                pruned = pruned + 1
                        end
-                       return {released,abandoned,pruned}
+                       -- Get the list of ready delayed jobs, sorted by readiness (UNIX timestamp)
+                       local ids = redis.call('zRangeByScore',kDelayed,0,ARGV[4])
+                       -- Migrate the jobs from the "delayed" set to the "unclaimed" list
+                       for k,id in ipairs(ids) do
+                               redis.call('lPush',kUnclaimed,id)
+                               redis.call('zRem',kDelayed,id)
+                       end
+                       undelayed = #ids
+                       return {released,abandoned,pruned,undelayed}
 LUA;
                        $res = $conn->luaEval( $script,
                                array(
@@ -724,15 +692,17 @@ LUA;
                                        $this->getQueueKey( 'l-unclaimed' ), # KEYS[3]
                                        $this->getQueueKey( 'h-data' ), # KEYS[4]
                                        $this->getQueueKey( 'z-abandoned' ), # KEYS[5]
+                                       $this->getQueueKey( 'z-delayed' ), # KEYS[6]
                                        $now - $this->claimTTL, # ARGV[1]
                                        $now - self::MAX_AGE_PRUNE, # ARGV[2]
-                                       $this->maxTries # ARGV[3]
+                                       $this->maxTries, # ARGV[3]
+                                       $now # ARGV[4]
                                ),
-                               5 # number of first argument(s) that are keys
+                               6 # number of first argument(s) that are keys
                        );
                        if ( $res ) {
-                               list( $released, $abandoned, $pruned ) = $res;
-                               $count += $released + $pruned;
+                               list( $released, $abandoned, $pruned, $undelayed ) = $res;
+                               $count += $released + $pruned + $undelayed;
                                JobQueue::incrStats( 'job-recycle', $this->type, $released );
                                JobQueue::incrStats( 'job-abandon', $this->type, $abandoned );
                        }
@@ -747,21 +717,19 @@ LUA;
         * @return array
         */
        protected function doGetPeriodicTasks() {
-               $tasks = array();
+               $periods = array( 3600 ); // standard cleanup (useful on config change)
                if ( $this->claimTTL > 0 ) {
-                       $tasks['recycleAndDeleteStaleJobs'] = array(
-                               'callback' => array( $this, 'recycleAndDeleteStaleJobs' ),
-                               'period' => ceil( $this->claimTTL / 2 )
-                       );
+                       $periods[] = ceil( $this->claimTTL / 2 ); // avoid bad timing
                }
                if ( $this->checkDelay ) {
-                       $tasks['releaseReadyDelayedJobs'] = array(
-                               'callback' => array( $this, 'releaseReadyDelayedJobs' ),
-                               'period' => 300 // 5 minutes
-                       );
+                       $periods[] = 300; // 5 minutes
                }
-
-               return $tasks;
+               return array(
+                       'recyclePruneAndUndelayJobs' => array(
+                               'callback' => array( $this, 'recyclePruneAndUndelayJobs' ),
+                               'period'   => max( min( $periods ), 30 ) // sanity
+                       )
+               );
        }
 
        /**
index 9e7f056..4f44d75 100644 (file)
@@ -573,7 +573,7 @@ class LogFormatter {
        }
 
        /**
-        * Gets the luser provided comment
+        * Gets the user provided comment
         * @return string HTML
         */
        public function getComment() {
index 844aef2..1cb5542 100644 (file)
@@ -829,13 +829,13 @@ class Exif {
                }
 
                if ( $action === true ) {
-                       wfDebugLog( $this->log, "$class::$fname: accepted: '$in' (type: $type)\n" );
+                       wfDebugLog( $this->log, "$class::$fname: accepted: '$in' (type: $type)" );
                } elseif ( $action === false ) {
-                       wfDebugLog( $this->log, "$class::$fname: rejected: '$in' (type: $type)\n" );
+                       wfDebugLog( $this->log, "$class::$fname: rejected: '$in' (type: $type)" );
                } elseif ( $action === null ) {
-                       wfDebugLog( $this->log, "$class::$fname: input was: '$in' (type: $type)\n" );
+                       wfDebugLog( $this->log, "$class::$fname: input was: '$in' (type: $type)" );
                } else {
-                       wfDebugLog( $this->log, "$class::$fname: $action (type: $type; content: '$in')\n" );
+                       wfDebugLog( $this->log, "$class::$fname: $action (type: $type; content: '$in')" );
                }
        }
 
@@ -851,9 +851,9 @@ class Exif {
                }
                $class = ucfirst( __CLASS__ );
                if ( $io ) {
-                       wfDebugLog( $this->log, "$class::$fname: begin processing: '{$this->basename}'\n" );
+                       wfDebugLog( $this->log, "$class::$fname: begin processing: '{$this->basename}'" );
                } else {
-                       wfDebugLog( $this->log, "$class::$fname: end processing: '{$this->basename}'\n" );
+                       wfDebugLog( $this->log, "$class::$fname: end processing: '{$this->basename}'" );
                }
        }
 }
index 3c97480..56f2128 100644 (file)
@@ -343,7 +343,7 @@ class RedisBagOStuff extends BagOStuff {
         * Log a fatal error
         */
        protected function logError( $msg ) {
-               wfDebugLog( 'redis', "Redis error: $msg\n" );
+               wfDebugLog( 'redis', "Redis error: $msg" );
        }
 
        /**
index b6c9cec..557c1f6 100644 (file)
@@ -289,7 +289,7 @@ class ResourceLoader {
 
                // Get core test suites
                $testModules = array();
-               $testModules['qunit'] = include "$IP/tests/qunit/QUnitTestResources.php";
+               $testModules['qunit'] = array();
                // Get other test suites (e.g. from extensions)
                wfRunHooks( 'ResourceLoaderTestModules', array( &$testModules, &$this ) );
 
@@ -300,9 +300,11 @@ class ResourceLoader {
                        // on document-ready, it will run once and finish. If some tests arrive
                        // later (possibly after QUnit has already finished) they will be ignored.
                        $module['position'] = 'top';
-                       $module['dependencies'][] = 'mediawiki.tests.qunit.testrunner';
+                       $module['dependencies'][] = 'test.mediawiki.qunit.testrunner';
                }
 
+               $testModules['qunit'] = ( include "$IP/tests/qunit/QUnitTestResources.php" ) + $testModules['qunit'];
+
                foreach ( $testModules as $id => $names ) {
                        // Register test modules
                        $this->register( $testModules[$id] );
index 0c887e4..0509008 100644 (file)
@@ -279,6 +279,30 @@ class RevDel_RevisionItem extends RevDel_Item {
                }
                return "<li>$difflink $revlink $userlink $comment</li>";
        }
+
+       public function getApiData( ApiResult $result ) {
+               $rev = $this->revision;
+               $user = $this->list->getUser();
+               $ret = array(
+                       'id' => $rev->getId(),
+                       'timestamp' => wfTimestamp( TS_ISO_8601, $rev->getTimestamp() ),
+               );
+               $ret += $rev->isDeleted( Revision::DELETED_USER ) ? array( 'userhidden' => '' ) : array();
+               $ret += $rev->isDeleted( Revision::DELETED_COMMENT ) ? array( 'commenthidden' => '' ) : array();
+               $ret += $rev->isDeleted( Revision::DELETED_TEXT ) ? array( 'texthidden' => '' ) : array();
+               if ( $rev->userCan( Revision::DELETED_USER, $user ) ) {
+                       $ret += array(
+                               'userid' => $rev->getUser( Revision::FOR_THIS_USER ),
+                               'user' => $rev->getUserText( Revision::FOR_THIS_USER ),
+                       );
+               }
+               if ( $rev->userCan( Revision::DELETED_COMMENT, $user ) ) {
+                       $ret += array(
+                               'comment' => $rev->getComment( Revision::FOR_THIS_USER ),
+                       );
+               }
+               return $ret;
+       }
 }
 
 /**
@@ -708,6 +732,50 @@ class RevDel_FileItem extends RevDel_Item {
                return '<li>' . $this->getLink() . ' ' . $this->getUserTools() . ' ' .
                        $data . ' ' . $this->getComment() . '</li>';
        }
+
+       public function getApiData( ApiResult $result ) {
+               $file = $this->file;
+               $user = $this->list->getUser();
+               $ret = array(
+                       'title' => $this->list->title->getPrefixedText(),
+                       'archivename' => $file->getArchiveName(),
+                       'timestamp' => wfTimestamp( TS_ISO_8601, $file->getTimestamp() ),
+                       'width' => $file->getWidth(),
+                       'height' => $file->getHeight(),
+                       'size' => $file->getSize(),
+               );
+               $ret += $file->isDeleted( Revision::DELETED_USER ) ? array( 'userhidden' => '' ) : array();
+               $ret += $file->isDeleted( Revision::DELETED_COMMENT ) ? array( 'commenthidden' => '' ) : array();
+               $ret += $this->isDeleted() ? array( 'contenthidden' => '' ) : array();
+               if ( !$this->isDeleted() ) {
+                       $ret += array(
+                               'url' => $file->getUrl(),
+                       );
+               } elseif ( $this->canViewContent() ) {
+                       $ret += array(
+                               'url' => SpecialPage::getTitleFor( 'Revisiondelete' )->getLinkURL(
+                                       array(
+                                               'target' => $this->list->title->getPrefixedText(),
+                                               'file' => $file->getArchiveName(),
+                                               'token' => $user->getEditToken( $file->getArchiveName() )
+                                       ),
+                                       false, PROTO_RELATIVE
+                               ),
+                       );
+               }
+               if ( $file->userCan( Revision::DELETED_USER, $user ) ) {
+                       $ret += array(
+                               'userid' => $file->user,
+                               'user' => $file->user_text,
+                       );
+               }
+               if ( $file->userCan( Revision::DELETED_COMMENT, $user ) ) {
+                       $ret += array(
+                               'comment' => $file->description,
+                       );
+               }
+               return $ret;
+       }
 }
 
 /**
@@ -962,4 +1030,41 @@ class RevDel_LogItem extends RevDel_Item {
 
                return "<li>$loglink $date $action $comment</li>";
        }
+
+       public function getApiData( ApiResult $result ) {
+               $logEntry = DatabaseLogEntry::newFromRow( $this->row );
+               $user = $this->list->getUser();
+               $ret = array(
+                       'id' => $logEntry->getId(),
+                       'type' => $logEntry->getType(),
+                       'action' => $logEntry->getSubtype(),
+               );
+               $ret += $logEntry->isDeleted( LogPage::DELETED_USER ) ? array( 'userhidden' => '' ) : array();
+               $ret += $logEntry->isDeleted( LogPage::DELETED_COMMENT ) ? array( 'commenthidden' => '' ) : array();
+               $ret += $logEntry->isDeleted( LogPage::DELETED_ACTION ) ? array( 'actionhidden' => '' ) : array();
+
+               if ( LogEventsList::userCan( $this->row, LogPage::DELETED_ACTION, $user ) ) {
+                       ApiQueryLogEvents::addLogParams(
+                               $result,
+                               $ret,
+                               $logEntry->getParameters(),
+                               $logEntry->getType(),
+                               $logEntry->getSubtype(),
+                               $logEntry->getTimestamp(),
+                               $logEntry->isLegacy()
+                       );
+               }
+               if ( LogEventsList::userCan( $this->row, LogPage::DELETED_USER, $user ) ) {
+                       $ret += array(
+                               'userid' => $this->row->log_user,
+                               'user' => $this->row->log_user_text,
+                       );
+               }
+               if ( LogEventsList::userCan( $this->row, LogPage::DELETED_COMMENT, $user ) ) {
+                       $ret += array(
+                               'comment' => $this->row->log_comment,
+                       );
+               }
+               return $ret;
+       }
 }
index 803467e..3874602 100644 (file)
@@ -80,13 +80,16 @@ abstract class RevDel_List extends RevisionListBase {
         * transactions are done here.
         *
         * @param array $params Associative array of parameters. Members are:
-        *     value:       The integer value to set the visibility to
-        *     comment:     The log comment.
+        *     value:         The integer value to set the visibility to
+        *     comment:       The log comment.
+        *     perItemStatus: Set if you want per-item status reports
         * @return Status
+        * @since 1.23 Added 'perItemStatus' param
         */
        public function setVisibility( $params ) {
                $bitPars = $params['value'];
                $comment = $params['comment'];
+               $perItemStatus = isset( $params['perItemStatus'] ) ? $params['perItemStatus'] : false;
 
                $this->res = false;
                $dbw = wfGetDB( DB_MASTER );
@@ -98,16 +101,27 @@ abstract class RevDel_List extends RevisionListBase {
                $idsForLog = array();
                $authorIds = $authorIPs = array();
 
+               if ( $perItemStatus ) {
+                       $status->itemStatuses = array();
+               }
+
                for ( $this->reset(); $this->current(); $this->next() ) {
                        $item = $this->current();
                        unset( $missing[$item->getId()] );
 
+                       if ( $perItemStatus ) {
+                               $itemStatus = Status::newGood();
+                               $status->itemStatuses[$item->getId()] = $itemStatus;
+                       } else {
+                               $itemStatus = $status;
+                       }
+
                        $oldBits = $item->getBits();
                        // Build the actual new rev_deleted bitfield
                        $newBits = RevisionDeleter::extractBitfield( $bitPars, $oldBits );
 
                        if ( $oldBits == $newBits ) {
-                               $status->warning( 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
+                               $itemStatus->warning( 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
                                $status->failCount++;
                                continue;
                        } elseif ( $oldBits == 0 && $newBits != 0 ) {
@@ -120,7 +134,7 @@ abstract class RevDel_List extends RevisionListBase {
 
                        if ( $item->isHideCurrentOp( $newBits ) ) {
                                // Cannot hide current version text
-                               $status->error( 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
+                               $itemStatus->error( 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
                                $status->failCount++;
                                continue;
                        }
@@ -128,13 +142,13 @@ abstract class RevDel_List extends RevisionListBase {
                                // Cannot access this revision
                                $msg = ( $opType == 'show' ) ?
                                        'revdelete-show-no-access' : 'revdelete-modify-no-access';
-                               $status->error( $msg, $item->formatDate(), $item->formatTime() );
+                               $itemStatus->error( $msg, $item->formatDate(), $item->formatTime() );
                                $status->failCount++;
                                continue;
                        }
                        // Cannot just "hide from Sysops" without hiding any fields
                        if ( $newBits == Revision::DELETED_RESTRICTED ) {
-                               $status->warning( 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
+                               $itemStatus->warning( 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
                                $status->failCount++;
                                continue;
                        }
@@ -151,19 +165,22 @@ abstract class RevDel_List extends RevisionListBase {
                                        $authorIPs[] = $item->getAuthorName();
                                }
                        } else {
-                               $status->error( 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
+                               $itemStatus->error( 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
                                $status->failCount++;
                        }
                }
 
                // Handle missing revisions
                foreach ( $missing as $id => $unused ) {
-                       $status->error( 'revdelete-modify-missing', $id );
+                       if ( $perItemStatus ) {
+                               $status->itemStatuses[$id] = Status::newFatal( 'revdelete-modify-missing', $id );
+                       } else {
+                               $status->error( 'revdelete-modify-missing', $id );
+                       }
                        $status->failCount++;
                }
 
                if ( $status->successCount == 0 ) {
-                       $status->ok = false;
                        $dbw->rollback( __METHOD__ );
                        return $status;
                }
@@ -325,4 +342,12 @@ abstract class RevDel_Item extends RevisionItemBase {
         * @return boolean success
         */
        abstract public function setBits( $newBits );
+
+       /**
+        * Get the return information about the revision for the API
+        * @since 1.23
+        * @param ApiResult $result API result object
+        * @return array Data for the API result
+        */
+       abstract public function getApiData( ApiResult $result );
 }
index 4155635..882919f 100644 (file)
@@ -314,7 +314,7 @@ class SearchEngine {
                        $this->namespaces = null;
                        $parsed = substr( $query, strlen( $allkeyword ) );
                } elseif ( strpos( $query, ':' ) !== false ) {
-                       $prefix = substr( $query, 0, strpos( $query, ':' ) );
+                       $prefix = str_replace( ' ', '_', substr( $query, 0, strpos( $query, ':' ) ) );
                        $index = $wgContLang->getNsIndex( $prefix );
                        if ( $index !== false ) {
                                $this->namespaces = array( $index );
@@ -672,6 +672,15 @@ class SearchResultSet {
        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
+        * name would contain the search syntax.
+        */
+       public function searchContainedSyntax() {
+               return false;
+       }
 }
 
 /**
index 792d0a6..dea65f3 100644 (file)
@@ -180,7 +180,6 @@ class SpecialPageFactory {
                global $wgSpecialPages;
                global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication;
                global $wgEnableEmail, $wgEnableJavaScriptTest;
-               global $wgMiserMode;
 
                if ( !is_object( self::$list ) ) {
                        wfProfileIn( __METHOD__ );
@@ -206,9 +205,7 @@ class SpecialPageFactory {
                                self::$list['JavaScriptTest'] = 'SpecialJavaScriptTest';
                        }
 
-                       if ( !$wgMiserMode ) {
-                               self::$list['Activeusers'] = 'SpecialActiveUsers';
-                       }
+                       self::$list['Activeusers'] = 'SpecialActiveUsers';
 
                        // Add extension special pages
                        self::$list = array_merge( self::$list, $wgSpecialPages );
index 705dab5..641c046 100644 (file)
@@ -87,39 +87,31 @@ class ActiveUsersPager extends UsersPager {
        }
 
        function getIndexField() {
-               return 'rc_user_text';
+               return 'qcc_title';
        }
 
        function getQueryInfo() {
                $dbr = $this->getDatabase();
 
-               $conds = array( 'rc_user > 0' ); // Users - no anons
-               $conds[] = 'rc_log_type IS NULL OR rc_log_type != ' . $dbr->addQuotes( 'newusers' );
-               $conds[] = 'rc_timestamp >= ' . $dbr->addQuotes(
-                       $dbr->timestamp( wfTimestamp( TS_UNIX ) - $this->RCMaxAge * 24 * 3600 ) );
-
+               $conds = array(
+                       'qcc_type' => 'activeusers',
+                       'qcc_namespace' => NS_USER,
+                       'user_name = qcc_title',
+                       'rc_user_text = qcc_title'
+               );
                if ( $this->requestedUser != '' ) {
-                       $conds[] = 'rc_user_text >= ' . $dbr->addQuotes( $this->requestedUser );
+                       $conds[] = 'qcc_title >= ' . $dbr->addQuotes( $this->requestedUser );
                }
-
                if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
                        $conds[] = 'NOT EXISTS (' . $dbr->selectSQLText(
-                               'ipblocks', '1', array( 'rc_user=ipb_user', 'ipb_deleted' => 1 )
+                               'ipblocks', '1', array( 'ipb_user=user_id', 'ipb_deleted' => 1 )
                        ) . ')';
                }
 
                return array(
-                       'tables' => array( 'recentchanges' ),
-                       'fields' => array(
-                               'user_name' => 'rc_user_text', // for Pager inheritance
-                               'rc_user_text', // for Pager
-                               'user_id' => 'MAX(rc_user)', // Postgres
-                               'recentedits' => 'COUNT(*)'
-                       ),
-                       'options' => array(
-                               'GROUP BY' => array( 'rc_user_text' ),
-                               'USE INDEX' => array( 'recentchanges' => 'rc_user_text' )
-                       ),
+                       'tables' => array( 'querycachetwo', 'user', 'recentchanges' ),
+                       'fields' => array( 'user_name', 'user_id', 'recentedits' => 'COUNT(*)', 'qcc_title' ),
+                       'options' => array( 'GROUP BY' => array( 'qcc_title' ) ),
                        'conds' => $conds
                );
        }
@@ -249,6 +241,12 @@ class SpecialActiveUsers extends SpecialPage {
                $out->wrapWikiMsg( "<div class='mw-activeusers-intro'>\n$1\n</div>",
                        array( 'activeusers-intro', $this->getLanguage()->formatNum( $wgActiveUserDays ) ) );
 
+               // Occasionally merge in new updates
+               $seconds = self::mergeActiveUsers( 600 );
+               // Mention the level of staleness
+               $out->addWikiMsg( 'cachedspecial-viewing-cached-ttl',
+                       $this->getLanguage()->formatDuration( $seconds ) );
+
                $up = new ActiveUsersPager( $this->getContext(), null, $par );
 
                # getBody() first to check, if empty
@@ -269,4 +267,141 @@ class SpecialActiveUsers extends SpecialPage {
        protected function getGroupName() {
                return 'users';
        }
+
+       /**
+        * @param integer $period Seconds (do updates no more often than this)
+        * @return integer How many seconds old the cache is
+        */
+       public static function mergeActiveUsers( $period ) {
+               global $wgActiveUserDays;
+
+               $dbr = wfGetDB( DB_SLAVE );
+               $cTime = $dbr->selectField( 'querycache_info',
+                       'qci_timestamp',
+                       array( 'qci_type' => 'activeusers' )
+               );
+               if ( !wfReadOnly() ) {
+                       if ( !$cTime || ( time() - wfTimestamp( TS_UNIX, $cTime ) ) > $period ) {
+                               $dbw = wfGetDB( DB_MASTER );
+                               self::doQueryCacheUpdate( $dbw, 2 * $period );
+                       }
+               }
+               return ( time() -
+                       ( $cTime ? wfTimestamp( TS_UNIX, $cTime ) : $wgActiveUserDays * 86400 ) );
+       }
+
+       /**
+        * @param DatabaseBase $dbw Passed in from updateSpecialPages.php
+        * @return void
+        */
+       public static function cacheUpdate( DatabaseBase $dbw ) {
+               global $wgActiveUserDays;
+
+               self::doQueryCacheUpdate( $dbw, $wgActiveUserDays * 86400 );
+       }
+
+       /**
+        * Update the query cache as needed
+        *
+        * @param DatabaseBase $dbw
+        * @param integer $window Maximum time range of new data to scan (in seconds)
+        * @return bool Success
+        */
+       protected static function doQueryCacheUpdate( DatabaseBase $dbw, $window ) {
+               global $wgActiveUserDays;
+
+               $lockKey = wfWikiID() . '-activeusers';
+               if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) {
+                       return false; // exclusive update (avoids duplicate entries)
+               }
+
+               $now = time();
+               $cTime = $dbw->selectField( 'querycache_info',
+                       'qci_timestamp',
+                       array( 'qci_type' => 'activeusers' )
+               );
+               $cTimeUnix = $cTime ? wfTimestamp( TS_UNIX, $cTime ) : 1;
+
+               // Pick the date range to fetch from. This is normally from the last
+               // update to till the present time, but has a limited window for sanity.
+               // If the window is limited, multiple runs are need to fully populate it.
+               $sTimestamp = max( $cTimeUnix, $now - $wgActiveUserDays * 86400 );
+               $eTimestamp = min( $sTimestamp + $window, $now );
+
+               // Get all the users active since the last update
+               $res = $dbw->select(
+                       array( 'recentchanges' ),
+                       array( 'rc_user_text', 'lastedittime' => 'MAX(rc_timestamp)' ),
+                       array(
+                               'rc_user > 0', // actual accounts
+                               'rc_log_type IS NULL OR rc_log_type != ' . $dbw->addQuotes( 'newusers' ),
+                               'rc_timestamp >= ' . $dbw->addQuotes( $dbw->timestamp( $sTimestamp ) ),
+                               'rc_timestamp <= ' . $dbw->addQuotes( $dbw->timestamp( $eTimestamp ) )
+                       ),
+                       __METHOD__,
+                       array(
+                               'GROUP BY' => array( 'rc_user_text' ),
+                               'ORDER BY' => 'NULL' // avoid filesort
+                       )
+               );
+               $names = array();
+               foreach ( $res as $row ) {
+                       $names[$row->rc_user_text] = $row->lastedittime;
+               }
+
+               // Rotate out users that have not edited in too long (according to old data set)
+               $dbw->delete( 'querycachetwo',
+                       array(
+                               'qcc_type' => 'activeusers',
+                               'qcc_value < ' . $dbw->addQuotes( $now - $wgActiveUserDays * 86400 ) // TS_UNIX
+                       ),
+                       __METHOD__
+               );
+
+               // Find which of the recently active users are already accounted for
+               if ( count( $names ) ) {
+                       $res = $dbw->select( 'querycachetwo',
+                               array( 'user_name' => 'qcc_title' ),
+                               array(
+                                       'qcc_type' => 'activeusers',
+                                       'qcc_namespace' => NS_USER,
+                                       'qcc_title' => array_keys( $names ) ),
+                               __METHOD__
+                       );
+                       foreach ( $res as $row ) {
+                               unset( $names[$row->user_name] );
+                       }
+               }
+
+               // Insert the users that need to be added to the list (which their last edit time
+               if ( count( $names ) ) {
+                       $newRows = array();
+                       foreach ( $names as $name => $lastEditTime ) {
+                               $newRows[] = array(
+                                       'qcc_type'  => 'activeusers',
+                                       'qcc_namespace' => NS_USER,
+                                       'qcc_title' => $name,
+                                       'qcc_value' => wfTimestamp( TS_UNIX, $lastEditTime ),
+                                       'qcc_namespacetwo' => 0, // unused
+                                       'qcc_titletwo' => '' // unused
+                               );
+                       }
+                       foreach ( array_chunk( $newRows, 500 ) as $rowBatch ) {
+                               $dbw->insert( 'querycachetwo', $rowBatch, __METHOD__ );
+                               wfWaitForSlaves();
+                       }
+               }
+
+               // Touch the data freshness timestamp
+               $dbw->replace( 'querycache_info',
+                       array( 'qci_type' ),
+                       array( 'qci_type' => 'activeusers',
+                               'qci_timestamp' => $dbw->timestamp( $eTimestamp ) ), // not always $now
+                       __METHOD__
+               );
+
+               $dbw->unlock( $lockKey, __METHOD__ );
+
+               return true;
+       }
 }
index 57d314f..7982d5c 100644 (file)
@@ -139,7 +139,7 @@ class SpecialJavaScriptTest extends SpecialPage {
 
                $out = $this->getOutput();
 
-               $out->addModules( 'mediawiki.tests.qunit.testrunner' );
+               $out->addModules( 'test.mediawiki.qunit.testrunner' );
                $qunitTestModules = $out->getResourceLoader()->getTestModuleNames( 'qunit' );
                $out->addModules( $qunitTestModules );
 
index 8e56574..082eed0 100644 (file)
@@ -277,7 +277,7 @@ class SpecialPasswordReset extends FormSpecialPage {
 
                $title = $this->msg( 'passwordreset-emailtitle' );
 
-               $this->result = $firstUser->sendMail( $title->escaped(), $this->email->text() );
+               $this->result = $firstUser->sendMail( $title->text(), $this->email->text() );
 
                if ( isset( $data['Capture'] ) && $data['Capture'] ) {
                        // Save the user, will be used if an error occurs when sending the email
index 7352de7..d266e3f 100644 (file)
@@ -506,7 +506,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
        public function getFeedQuery() {
                global $wgFeedLimit;
 
-               $this->getOptions()->validateIntBounds( 'limit', 0, $wgFeedLimit );
                $options = $this->getOptions()->getChangedValues();
 
                // wfArrayToCgi() omits options set to null or false
@@ -517,6 +516,10 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                }
                unset( $value );
 
+               if ( isset( $options['limit'] ) && $options['limit'] > $wgFeedLimit ) {
+                       $options['limit'] = $wgFeedLimit;
+               }
+
                return wfArrayToCgi( $options );
        }
 
index 9e5143f..588a313 100644 (file)
@@ -199,7 +199,7 @@ class SpecialSearch extends SpecialPage {
                if ( !is_null( $t ) ) {
                        global $wgGoToEdit;
                        wfRunHooks( 'SpecialSearchNogomatch', array( &$t ) );
-                       wfDebugLog( 'nogomatch', $t->getText(), false );
+                       wfDebugLog( 'nogomatch', $t->getText(), 'private' );
 
                        # If the feature is enabled, go straight to the edit page
                        if ( $wgGoToEdit ) {
@@ -376,7 +376,7 @@ class SpecialSearch extends SpecialPage {
                // prev/next links
                if ( $num || $this->offset ) {
                        // Show the create link ahead
-                       $this->showCreateLink( $t, $num );
+                       $this->showCreateLink( $t, $num, $titleMatches, $textMatches );
                        $prevnext = $this->getLanguage()->viewPrevNext( $this->getPageTitle(), $this->offset, $this->limit,
                                $this->powerSearchOptions() + array( 'search' => $term ),
                                max( $titleMatchesNum, $textMatchesNum ) < $this->limit
@@ -422,7 +422,7 @@ class SpecialSearch extends SpecialPage {
                        } else {
                                $out->wrapWikiMsg( "<p class=\"mw-search-nonefound\">\n$1</p>",
                                        array( 'search-nonefound', wfEscapeWikiText( $term ) ) );
-                               $this->showCreateLink( $t, $num );
+                               $this->showCreateLink( $t, $num, $titleMatches, $textMatches );
                        }
                }
                $out->addHtml( "</div>" );
@@ -437,12 +437,16 @@ class SpecialSearch extends SpecialPage {
        /**
         * @param $t Title
         * @param int $num The number of search results found
+        * @param $titleMatches null|SearchResultSet results from title search
+        * @param $textMatches null|SearchResultSet results from text search
         */
-       protected function showCreateLink( $t, $num ) {
+       protected function showCreateLink( $t, $num, $titleMatches, $textMatches ) {
                // show direct page/create link if applicable
 
                // Check DBkey !== '' in case of fragment link only.
-               if ( is_null( $t ) || $t->getDBkey() === '' ) {
+               if ( is_null( $t ) || $t->getDBkey() === '' ||
+                               ( $titleMatches !== null && $titleMatches->searchContainedSyntax() ) ||
+                               ( $textMatches !== null && $textMatches->searchContainedSyntax() ) ) {
                        // invalid title
                        // preserve the paragraph for margins etc...
                        $this->getOutput()->addHtml( '<p></p>' );
index b572499..bdcc9a1 100644 (file)
@@ -139,7 +139,7 @@ class UploadFromChunks extends UploadFromFile {
                if ( !$status->isOk() ) {
                        return $status;
                }
-               wfDebugLog( 'fileconcatenate', "Combined $i chunks in $tAmount seconds.\n" );
+               wfDebugLog( 'fileconcatenate', "Combined $i chunks in $tAmount seconds." );
 
                // File system path
                $this->mTempPath = $tmpPath;
@@ -158,7 +158,7 @@ class UploadFromChunks extends UploadFromFile {
                $this->mLocalFile = parent::stashFile( $this->user );
                $tAmount = microtime( true ) - $tStart;
                $this->mLocalFile->setLocalReference( $tmpFile ); // reuse (e.g. for getImageInfo())
-               wfDebugLog( 'fileconcatenate', "Stashed combined file ($i chunks) in $tAmount seconds.\n" );
+               wfDebugLog( 'fileconcatenate', "Stashed combined file ($i chunks) in $tAmount seconds." );
 
                return $status;
        }
index 1b7c5bb..f2ec543 100644 (file)
@@ -687,7 +687,7 @@ $messages = array(
 'undelete_short' => 'استرجاع {{PLURAL:$1||تعديل واحد|تعديلين|$1 تعديلات|$1 تعديلاً|$1 تعديل}}',
 'viewdeleted_short' => 'استعرض {{PLURAL:$1||تعديل واحد|تعديلين|$1 تعديلات|$1 تعديلاً|$1 تعديل}}',
 'protect' => 'حماية',
-'protect_change' => 'غيّر',
+'protect_change' => 'غير',
 'protectthispage' => 'احم هذه الصفحة',
 'unprotect' => 'غير الحماية',
 'unprotectthispage' => 'غير حماية هذه الصفحة',
@@ -1910,7 +1910,7 @@ $1",
 'recentchanges-feed-description' => 'تابع أحدث التغييرات للويكي عبر هذه التلقيمة.',
 'recentchanges-label-newpage' => 'أنشأ هذا التعديل صفحة جديدة',
 'recentchanges-label-minor' => 'هذا تعديل طفيف',
-'recentchanges-label-bot' => 'Ø£Ù\8fجÙ\92رÙ\90Ù\8aÙ\8e Ù\87ذا Ø§Ù\84تعدÙ\8aÙ\84 Ø¨Ù\88اسطة بوت',
+'recentchanges-label-bot' => 'تعدÙ\8aÙ\84 Ø£Ø¬Ø±Ø§Ù\87 بوت',
 'recentchanges-label-unpatrolled' => 'لم يراجع هذا التعديل إلى الآن',
 'recentchanges-label-plusminus' => 'حجم الصفحة تغير بهذا العدد من وحدات البايت',
 'recentchanges-legend-heading' => 'شرح',
index cd64e76..3d2810c 100644 (file)
@@ -507,6 +507,7 @@ $1',
 'passwordreset-username' => 'ܫܡܐ ܕܡܦܠܚܢܐ:',
 'passwordreset-domain' => 'ܪܘܚܬܐ:',
 'passwordreset-email' => 'ܡܘܢܥܐ ܕܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ:',
+'passwordreset-emailsent' => 'ܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ ܐܫܬܕܪ ܠܣܘܝܡ ܡܠܬܐ ܕܥܠܠܐ ܙܒܢ ܐܚܪܝܢ',
 
 # Special:ChangeEmail
 'changeemail' => 'ܫܚܠܦ ܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ',
index 91edfec..02862e8 100644 (file)
@@ -917,8 +917,8 @@ Esta yá esiste.',
 'content-failed-to-parse' => 'Fallu al analizar el conteníu $2 pal modelu $1: $3',
 'invalid-content-data' => 'Datos del conteníu inválidos',
 'content-not-allowed-here' => 'El conteníu «$1» nun se permite na páxina [[$2]]',
-'editwarning-warning' => 'Salir d\'esta páxina pue causar la perda de cualesquier cambiu fechu.
-Si aniciasti sesión, pue desactivase esti avisu na seición "Edición" de les tos preferencies.',
+'editwarning-warning' => "Salir d'esta páxina pue causar la perda de cualesquier cambiu fechu.
+Si anició sesión, pue desactivar esti avisu na seición «{{int:prefs-editing}}» de les preferencies.",
 'editpage-notsupportedcontentformat-title' => 'El formatu del conteníu nun tien sofitu',
 'editpage-notsupportedcontentformat-text' => 'El formatu del conteníu, $1, nun tien sofitu del modelu de conteníu $2.',
 
@@ -1134,6 +1134,8 @@ Asegúrate de qu'esti cambéu caltenga la continuidá del históricu de la páxi
 'showhideselectedversions' => 'Amosar/anubrir les versiones seleicionaes',
 'editundo' => 'desfacer',
 'diff-empty' => '(Nun hai diferencies)',
+'diff-multi-sameuser' => "({{PLURAL:$1|Nun s'amuesa una revisión intermedia|Nun s'amuesen $1 revisiones intermedies}} del mesmu usuariu)",
+'diff-multi-otherusers' => "(Nun s'{{PLURAL:$1|amuesa una revisión intermedia|amuesen $1 revisiones intermedies}} {{PLURAL:$2|d'otru usuariu|de $2 usuarios}})",
 'diff-multi-manyusers' => "({{PLURAL:$1|Nun s'amuesa una revisión intermedia|Nun s'amuesen $1 revisiones intermedies}} de más de $2 {{PLURAL:$2|usuariu|usuarios}})",
 'difference-missing-revision' => "{{PLURAL:$2|Nun s'alcontró|Nun s'alcontraron}} {{PLURAL:$2|una revisión|$2 revisiones}} d'esta diferencia ($1).
 
@@ -1154,7 +1156,7 @@ Se puen alcontrar más detalles nel [{{fullurl:{{#Special:Log}}/delete|page={{FU
 'shown-title' => 'Amosar $1 {{PLURAL:$1|resultáu|resultaos}} por páxina',
 'viewprevnext' => 'Ver ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "'''Hai una páxina nomada \"[[\$1]]\" nesta wiki'''",
-'searchmenu-new' => "'''¡Crear la páxina \"[[:\$1]]\" nesta wiki!'''",
+'searchmenu-new' => "<strong>¡Crear la páxina «[[:$1]]» nesta wiki!</strong> {{PLURAL:$2|0=|Vea tamién la páxina que s'alcontró cola gueta.|Vea tamién los resultaos qu'alcontró la gueta.}}",
 'searchprofile-articles' => 'Páxines de conteníu',
 'searchprofile-project' => 'Páxines de proyeutu y ayuda',
 'searchprofile-images' => 'Multimedia',
index b3a7a14..42fcfb0 100644 (file)
@@ -1087,7 +1087,7 @@ $2
 'invalid-content-data' => 'Няслушныя зьвесткі',
 'content-not-allowed-here' => 'Зьмест тыпу «$1» на старонцы [[$2]] не дазволены',
 'editwarning-warning' => 'Пакінуўшы гэтую старонку, вы можаце страціць усе ўнесеныя зьмены.
-Калі вы ўвайшлі ў сыстэму, Вы можаце адключыць гэтае папярэджаньне ў сэкцыі «Рэдагаваньне» вашых наладаў.',
+Калі вы ўвайшлі ў сыстэму, Вы можаце адключыць гэтае папярэджаньне ў сэкцыі «{{int:prefs-editing}}» вашых наладаў.',
 'editpage-notsupportedcontentformat-title' => 'Фармат зьмесьціва не падтрымліваецца',
 'editpage-notsupportedcontentformat-text' => 'Фармат зьмесьціва $1 не падтрымліваецца мадэльлю зьмесьціва $2.',
 
@@ -1123,6 +1123,7 @@ $2
 'undo-success' => 'Рэдагаваньне можа быць адмененае. Калі ласка, параўнайце адрозьненьні паміж вэрсіямі, каб упэўніцца, што гэта адпаведныя зьмены, а потым запішыце зьмены для сканчэньня рэдагаваньня.',
 'undo-failure' => 'Рэдагаваньне ня можа быць скасаванае праз канфлікт паміж папярэднімі рэдагаваньнямі.',
 'undo-norev' => 'Рэдагаваньне ня можа быць адмененае, таму што яно не існуе альбо было выдаленае.',
+'undo-nochange' => 'Выглядае, што праўка ўжо была адмененая.',
 'undo-summary' => 'Скасаваньне праўкі $1 {{GENDER:$2|удзельніка|удзельніцы}} [[Special:Contributions/$2|$2]] ([[User talk:$2|гутаркі]])',
 'undo-summary-username-hidden' => 'Вэрсія $1 скасаваная схаваным удзельнікам',
 
@@ -1305,6 +1306,7 @@ $1",
 'editundo' => 'скасаваць',
 'diff-empty' => '(Розьніцы няма)',
 'diff-multi-sameuser' => '(не {{PLURAL:$1|паказаная $1 прамежная вэрсія|паказаныя $1 прамежныя вэрсіі|паказаныя $1 прамежных вэрсіяў}} аўтарства таго ж удзельніка)',
+'diff-multi-otherusers' => '(не {{PLURAL:$1|паказаная $1 прамежная вэрсія|паказаныя $1 прамежныя вэрсіі|паказаныя $1 прамежных вэрсіяў}} аўтарства {{PLURAL:$2|1=яшчэ аднаго ўдзельніка|$2 удзельнікаў}})',
 'diff-multi-manyusers' => '($1 {{PLURAL:$1|прамежная вэрсія|прамежныя вэрсіі|прамежных вэрсіяў}} $2 {{PLURAL:$2|удзельніка|удзельнікаў|удзельнікаў}} {{PLURAL:$1|не паказаная|не паказаныя|не паказаныя}})',
 'difference-missing-revision' => '{{PLURAL:$2|$2 вэрсія|$2 вэрсіі|$2 вэрсіяў}} з гэтымі адрозьненьнямі ($1) {{PLURAL:$2|не была|не былі}} знойдзеныя.
 
@@ -1789,6 +1791,8 @@ $1",
 Калі Вы жадаеце загрузіць Ваш файл, вярніцеся назад і загрузіце гэты файл з новай назвай. [[File:$1|thumb|center|$1]]',
 'file-exists-duplicate' => 'Гэты файл дублюе {{PLURAL:$1|1=наступны файл|наступныя файлы}}:',
 'file-deleted-duplicate' => 'Падобны файл ([[:$1]]) ужо выдаляўся. Калі ласка, паглядзіце гісторыю выдаленьняў гэтага файла перад яго паўторнай загрузкай.',
+'file-deleted-duplicate-notitle' => 'Файл, ідэнтычны гэтаму файлу, раней ужо быў выдалены, а назва файла была забароненая.
+Вам трэба зьвярнуцца да некага з правамі прагляду зьвестак забароненых файлаў, каб прааналізаваць сытуацыю перад тым, як загружаць файл ізноў.',
 'uploadwarning' => 'Папярэджаньне',
 'uploadwarning-text' => 'Калі ласка, зьмяніце апісаньне файла ніжэй і паспрабуйце ізноў.',
 'savefile' => 'Захаваць файл',
@@ -2226,7 +2230,7 @@ $1',
 
 # Special:Categories
 'categories' => 'Катэгорыі',
-'categoriespagetext' => '{{PLURAL:$1|1=Наступная катэгорыя зьмяшчае|Наступныя катэгорыі зьмяшчаюць}} старонкі і/альбо мэдыяфайлы.
+'categoriespagetext' => '{{PLURAL:$1|1=Наступная катэгорыя зьмяшчае|Наступныя катэгорыі зьмяшчаюць}} старонкі альбо мэдыяфайлы.
 Тут не паказаныя [[Special:UnusedCategories|катэгорыі, якія не выкарыстоўваюцца]].
 Глядзіце таксама [[Special:WantedCategories|сьпіс запатрабаваных катэгорыяў]].',
 'categoriesfrom' => 'Паказаць катэгорыі, пачынаючы з:',
@@ -2243,7 +2247,7 @@ $1',
 'linksearch-pat' => 'Узор для пошуку:',
 'linksearch-ns' => 'Прастора назваў:',
 'linksearch-ok' => 'Шукаць',
-'linksearch-text' => 'Можна ўжываць сымбалі падстаноўкі, напрыклад, «*.wikipedia.org».<br />
+'linksearch-text' => 'Можна ўжываць сымбалі падстаноўкі, напрыклад, «*.wikipedia.org».
 Неабходны дамэн першага ўзроўню, напрыклад, «*.org».<br />
 {{PLURAL:$2|1=Пратакол, які падтрымліваецца|Пратаколы, якія падтрымліваюцца}}: <code>$1</code> (дапомна http://, калі пратакол не пазначаны).',
 'linksearch-line' => 'Спасылка на $1 з $2',
@@ -2275,12 +2279,12 @@ $1',
 'listgrouprights-rights' => 'Правы',
 'listgrouprights-helppage' => 'Help:Правы групаў удзельнікаў',
 'listgrouprights-members' => '(сьпіс удзельнікаў групы)',
-'listgrouprights-addgroup' => 'можа дадаваць {{PLURAL:$2|1=групу|групы}}: $1',
-'listgrouprights-removegroup' => 'можа выдаляць {{PLURAL:$2|1=групу|групы}}: $1',
+'listgrouprights-addgroup' => 'можа дадаваць у {{PLURAL:$2|1=групу|групы}}: $1',
+'listgrouprights-removegroup' => 'можа выдаляць з {{PLURAL:$2|1=групы|групаў}}: $1',
 'listgrouprights-addgroup-all' => 'можа дадаваць усе групы',
 'listgrouprights-removegroup-all' => 'можа выдаляць усе групы',
-'listgrouprights-addgroup-self' => 'Ð\9cожа дадаць уласны рахунак да {{PLURAL:$2|1=групы|групаў}}: $1',
-'listgrouprights-removegroup-self' => 'Ð\9cожа выдаліць уласны рахунак з {{PLURAL:$2|1=групы|групаў}}: $1',
+'listgrouprights-addgroup-self' => 'можа дадаць уласны рахунак да {{PLURAL:$2|1=групы|групаў}}: $1',
+'listgrouprights-removegroup-self' => 'можа выдаліць уласны рахунак з {{PLURAL:$2|1=групы|групаў}}: $1',
 'listgrouprights-addgroup-self-all' => 'Можа дадаць уласны рахунак да ўсіх груп',
 'listgrouprights-removegroup-self-all' => 'Можа выдаліць уласны рахунак з ўсіх груп',
 
index ff4700c..da71fa0 100644 (file)
@@ -1124,7 +1124,7 @@ $1",
 'shown-title' => 'প্রতি পাতায় $1 {{PLURAL:$1|ফলাফল|ফলাফলসমূহ}} দেখাও',
 'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) দেখানো হোক।',
 'searchmenu-exists' => "'''এই উইকিতে \"[[:\$1]]\" নামে একটি পাতা রয়েছে'''",
-'searchmenu-new' => "'''\"[[:\$1]]\" পাতাটি এই উইকিতে তৈরি করুন!'''",
+'searchmenu-new' => '<strong>"[[:$1]]" পাতাটি এই উইকিতে তৈরি করুন!</strong> {{PLURAL:$2|0=|এছাড়া আপনার অনুসন্ধানের সাথে পাওয়া পাতা দেখুন।|এছাড়া অনুসন্ধানে পাওয়া ফলাফলগুলি দেখুন।}}',
 'searchprofile-articles' => 'বিষয়বস্তুর পাতা',
 'searchprofile-project' => 'সহায়িকা এবং প্রকল্প পাতা',
 'searchprofile-images' => 'মাল্টিমিডিয়া',
@@ -2229,7 +2229,7 @@ $UNWATCHURL
 'delete-warning-toobig' => 'এই পাতাটির একটি বৃহৎ সম্পাদনা ইতিহাস রয়েছে, যা $1 {{PLURAL:$1|সংস্করণেরও|সংস্করণেরও}} বেশি।
 এই পাতাটি মুছে ফেললে তা {{SITENAME}} সাইটের ডেটাবেজ সমস্যার কারণ হতে পারে;
 সাবধানতার সাথে এগিয়ে যান।',
-'deleting-backlinks-warning' => "'''সতর্কীকরণ:''' আপনি যেটি মুছে ফেলতে যাচ্ছেন তা অন্যান্য পাতাসমূহের সাথে সংযুক্ত আছে।",
+'deleting-backlinks-warning' => "'''সতরà§\8dà¦\95à§\80à¦\95রণ:''' à¦\86পনি à¦¯à§\87à¦\9fি à¦®à§\81à¦\9bà§\87 à¦«à§\87লতà§\87 à¦¯à¦¾à¦\9aà§\8dà¦\9bà§\87ন à¦¤à¦¾ à¦\85নà§\8dযানà§\8dয à¦ªà¦¾à¦¤à¦¾à¦¸à¦®à§\82হà§\87র à¦¸à¦¾à¦¥à§\87 à¦¸à¦\82যà§\81à¦\95à§\8dত à¦\85থবা à¦\85নà§\8dতরà§\8dভà§\81à¦\95à§\8dত à¦\95রা à¦\86à¦\9bà§\87।",
 
 # Rollback
 'rollback' => 'সম্পাদনা ফিরিয়ে নিন',
@@ -2526,7 +2526,7 @@ $1',
 'range_block_disabled' => 'প্রশাসকের পক্ষে আইপি ঠিকানার শ্রেণী বাধাদানের ক্ষমতা নিষ্ক্রিয় আছে।',
 'ipb_expiry_invalid' => 'মেয়াদোত্তীর্ণকাল অবৈধ।',
 'ipb_expiry_temp' => 'লুকানো ব্যবহারকারীনাম বাধা চিরস্থায়ী হতে হবে।',
-'ipb_hide_invalid' => 'à¦\8fà¦\87 à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9f à¦¬à¦¾à¦§à¦¾ à¦¦à§\87য়া à¦¸à¦®à§\8dভব à¦¨à¦¯à¦¼; à¦¹à¦¯à¦¼à¦¤à§\8b à¦¸à¦®à§\8dপাদনার à¦¸à¦\82à¦\96à§\8dযা à¦\85নà§\87à¦\95 à¦¬à§\87শি।',
+'ipb_hide_invalid' => 'à¦\8fà¦\87 à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9f à¦¬à¦¾à¦§à¦¾ à¦¦à§\87য়া à¦¸à¦®à§\8dভব à¦¨à¦¯à¦¼; à¦\8fà¦\9fি {{PLURAL:$1|à¦\8fà¦\95à§\87র à¦\85ধিà¦\95|$1à¦\9fি}} à¦¸à¦®à§\8dপাদনা à¦\95রà§\87à¦\9bà§\87।',
 'ipb_already_blocked' => '"$1" ইতিমধ্যে ব্লক',
 'ipb-needreblock' => '$1 পূর্বেই ব্লক রয়েছেন। আপনি কি সেটিংস পরিবর্তন করতে চান?',
 'ipb-otherblocks-header' => 'অন্যান্য {{PLURAL:$1|বাধাঁ|বাধাঁসমূহ}}',
@@ -3664,6 +3664,9 @@ $4-এ নিশ্চিতকরণ কোডটি মেয়াদোত
 'version-ext-colheader-license' => 'লাইসেন্স',
 'version-ext-colheader-description' => 'বিবরণ',
 'version-ext-colheader-credits' => 'লেখক',
+'version-license-title' => '$1-এর জন্য লাইসেন্স',
+'version-credits-title' => '$1-এর জন্য কৃতিত্ব',
+'version-credits-not-found' => 'এই এক্সটেনশনটির জন্য কোনো বিস্তারিত কৃতিত্ব তথ্য পাওয়া যায়নি।',
 'version-poweredby-credits' => "এইক উইকিটি পরিচালিত হচ্ছে '''[https://www.mediawiki.org/ মিডিয়াউইকি]'''-এর মাধ্যমে, কপিরাইট © ২০০১-$1 $2।",
 'version-poweredby-others' => 'অন্যান্য',
 'version-poweredby-translators' => 'translatewiki.net অনুবাদকগণ',
@@ -3683,7 +3686,7 @@ $4-এ নিশ্চিতকরণ কোডটি মেয়াদোত
 # Special:Redirect
 'redirect' => 'পাতা, ফাইল, ব্যবহারকরী, অথবা সংশোধন আইডি দ্বারা পুনঃনির্দেশ করা হয়েছে',
 'redirect-legend' => 'একটি ফাইল অথবা পাতায় পুনঃনির্দেশ করা হয়েছে',
-'redirect-summary' => 'à¦\8fà¦\87 à¦¬à¦¿à¦¶à§\87ষ à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦ªà§\81নà¦\83নিরà§\8dদà§\87শিত à¦¹à¦¯à¦¼à§\87à¦\9bà§\87 à¦\8fà¦\95à¦\9fি à¦«à¦¾à¦\87লà§\87 (ফাà¦\87লà§\87র à¦¨à¦¾à¦®), à¦\8fà¦\95à¦\9fি à¦ªà¦¾à¦¤à¦¾ (রিভিশন à¦\86à¦\87ডি), à¦\85থবা à¦\8fà¦\95à¦\9fি à¦¬à§\8dযবহারà¦\95রà§\80 à¦ªà¦¾à¦¤à¦¾à¦¯à¦¼ (সà¦\82à¦\96à§\8dযায় à¦²à§\87à¦\96া à¦¬à§\8dযবহারà¦\95ারà§\80 à¦\86à¦\87ডি)। à¦¬à§\8dযবহার: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]], or [[{{#Special:Redirect}}/user/101]]।',
+'redirect-summary' => 'à¦\8fà¦\87 à¦¬à¦¿à¦¶à§\87ষ à¦ªà¦¾à¦¤à¦¾à¦\9fি à¦\8fà¦\95à¦\9fি à¦«à¦¾à¦\87লà§\87 (ফাà¦\87লà§\87র à¦¨à¦¾à¦®), à¦\8fà¦\95à¦\9fি à¦ªà¦¾à¦¤à¦¾à¦¯à¦¼ (সà¦\82সà§\8dà¦\95রণ à¦\86à¦\87ডি à¦¬à¦¾ à¦ªà¦¾à¦¤à¦¾ à¦\86à¦\87ডি), à¦\85থবা à¦\8fà¦\95à¦\9fি à¦¬à§\8dযবহারà¦\95রà§\80 à¦ªà¦¾à¦¤à¦¾à¦¯à¦¼ (সà¦\82à¦\96à§\8dযায় à¦²à§\87à¦\96া à¦¬à§\8dযবহারà¦\95ারà§\80 à¦\86à¦\87ডি) à¦ªà§\81নà¦\83নিরà§\8dদà§\87শিত à¦¹à¦¯à¦¼à§\87à¦\9bà§\87। à¦¬à§\8dযবহার:  [[{{#Special:Redirect}}/file/à¦\89দাহরণ.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], à¦\85থবা [[{{#Special:Redirect}}/user/101]]।',
 'redirect-submit' => 'যাও',
 'redirect-lookup' => 'দেখুন:',
 'redirect-value' => 'মান:',
index c2933c3..9ee95a8 100644 (file)
@@ -1551,7 +1551,7 @@ Ma skrivit anezhañ e vo implijet evit lakaat war wel ar pezh a vo bet degaset g
 'recentchanges-label-bot' => "Gant ur bot eo bet degaset ar c'hemm-mañ.",
 'recentchanges-label-unpatrolled' => "N'eo ket bet gwiriet ar c'hemm-mañ evit c'hoazh.",
 'recentchanges-label-plusminus' => 'Kemmet eo ment ar bajenn eus an niver-mañ a oktedoù',
-'recentchanges-legend-heading' => '"Alc\'hwez :"',
+'recentchanges-legend-heading' => "'''Alc'hwez :'''",
 'recentchanges-legend-newpage' => '(gwelet ivez [[Special:NewPages|roll ar pajennoù nevez]])',
 'rcnotefrom' => "Setu aze roll ar c'hemmoù c'hoarvezet abaoe an '''$2''' ('''$1''' d'ar muiañ).",
 'rclistfrom' => "Diskouez ar c'hemmoù diwezhañ abaoe an $1.",
index ad2948c..770b678 100644 (file)
@@ -2042,7 +2042,7 @@ Les entrades <del>ratllades</del> s\'han resolt.',
 'ninterwikis' => '$1 {{PLURAL:$1|interwiki|interwikis}}',
 'nlinks' => '$1 {{PLURAL:$1|enllaç|enllaços}}',
 'nmembers' => '$1 {{PLURAL:$1|membre|membres}}',
-'nmemberschanged' => '$1 → $2 {{PLURAL:$2|membre|membres}}',
+'nmemberschanged' => '$1 → $2 {{PLURAL:$2|element|elements}}',
 'nrevisions' => '$1 {{PLURAL:$1|revisió|revisions}}',
 'nviews' => '$1 {{PLURAL:$1|visita|visites}}',
 'nimagelinks' => "S'utilitza en {{PLURAL:$1|una pàgina|$1 pàgines}}",
index 3de136e..b2cc8f6 100644 (file)
@@ -479,7 +479,7 @@ $messages = array(
 # Vector skin
 'vector-action-addsection' => 'ТӀетоха хьедар',
 'vector-action-delete' => 'ДӀаяккха',
-'vector-action-move' => 'Цlе хийца',
+'vector-action-move' => 'ЦӀе хийца',
 'vector-action-protect' => 'Гlаролла дé',
 'vector-action-undelete' => 'Меттахlоттадé',
 'vector-action-unprotect' => 'ГӀароллех къаста',
@@ -687,7 +687,7 @@ URL язъеш гӀалат даьлла хила мега.
 ХӀу бахьна ду билгал дина дац.',
 'no-null-revision' => '«$1» агӀона нисдар дан цаделира',
 'badtitle' => 'Цамегаш йолу цlе',
-'badtitletext' => 'Дехарца йолу агlонан цlе нийса яц, йаьсса ю, хила мега нийса ца хlоттийна меттаюкъар йа юкъарвики цlе. Хила мега, цlарца цамагош йолу саберг.',
+'badtitletext' => 'Дехарца йолу агӀонан цӀе нийса яц, йаьсса ю, хила мега нийса ца хӀоттийна меттаюкъар йа юкъарвики цӀе. Хила мега, цӀарца цамагош йолу символаш.',
 'perfcached' => 'Лахара хаам схьаэца кэша чура цундела тӀехьарлаьра хийцамаш гойтуш бац. Кэша чохь латтаё оцул $1  кӀезиг {{PLURAL:$1|1=дӀаяздар|дӀаяздарш}}.',
 'perfcachedts' => 'Лахара хаам схьаэца кэша чура иза тӀаьхьара карла ялла $1. Кэша чохь латта до оцул $4 кӀезиг {{PLURAL:$4|1=дӀаяздар|дӀаяздарш}}.',
 'querypage-no-updates' => 'ХӀинца хӀара агӀо карлаякхар дӀадайина ду.
@@ -1103,7 +1103,7 @@ URL язъеш гӀалат даьлла хила мега.
 'revdelete-hide-image' => 'Къайлабаккха файлан чулацам',
 'revdelete-hide-name' => 'Къайлаяккха дешдерг а цуна объект а',
 'revdelete-hide-comment' => 'Хийцамах лаьцнарг',
-'revdelete-hide-user' => 'Ð\9aÑ\8aайлаÑ\8fккÑ\85а Ð°Ð²Ñ\82оÑ\80ан Ñ\86Ó\80е',
+'revdelete-hide-user' => 'Ð\94екÑ\8aаÑ\88Ñ\85оÑ\87Ñ\83н Ñ\86Ó\80е/IP-адÑ\80еÑ\81',
 'revdelete-radio-same' => '(ма хийца)',
 'revdelete-radio-set' => 'Къайлаяьккхина',
 'revdelete-radio-unset' => 'Гуш ерг',
@@ -1156,11 +1156,13 @@ $1",
 # Diffs
 'history-title' => '$1 — хийцаман истори',
 'difference-title' => '$1 — Версешан башхалла',
-'lineno' => 'Могlа $1:',
+'lineno' => 'МогӀа $1:',
 'compareselectedversions' => 'Хаьржина версеш муха ю хьажа',
 'showhideselectedversions' => 'Гайта/къайлаяха хаьржина башхонаш',
 'editundo' => 'цаоьшу',
 'diff-empty' => '(башхалла яц)',
+'diff-multi-sameuser' => '(ца {{PLURAL:$1|гайтина юккъера цхьа верси|гайтина юккъера цхьа версеш}} оьцу декъашхочун)',
+'diff-multi-otherusers' => '(ца {{PLURAL:$1|гайтина юккъера верси|гайтина юккъера версеш}} {{PLURAL:$2|кхин цхьан декъашхочун|$2 декъашхойн}})',
 
 # Search results
 'searchresults' => 'Лахарна хилам',
@@ -1470,7 +1472,7 @@ $1",
 'rc_categories_any' => 'Муьлхаа',
 'rc-change-size-new' => 'Хийцам бинчул тӀехьа болу барам: $1 {{PLURAL:$1|байт}}',
 'newsectionsummary' => '/* $1 */ Керла хьедар',
-'rc-enhanced-expand' => 'Гайта ма дарра дерг (лелош ю JavaScript)',
+'rc-enhanced-expand' => 'Гайта мадарра',
 'rc-enhanced-hide' => 'Ма дарра дерг къайладаккха',
 'rc-old-title' => 'дуьххьара кхоьллина яра цӀарца «$1»',
 
@@ -1694,7 +1696,7 @@ PICT # тайп тайпан
 'doubleredirects' => 'Шалха дIасахьажийнарш',
 'doubleredirectstext' => 'ХӀокху агӀонехь ю дӀасахьажорашан тӀе хьажийна йолу дӀасахьажораш.
 <del>ТӀехула сиз хаькхна </del>нисйина чарна.',
-'double-redirect-fixed-move' => 'Агlон [[$1]] цlе хийцна, хlинца иза дlахьажийна оцу [[$2]]',
+'double-redirect-fixed-move' => 'АгӀон [[$1]] цӀе хийцина, хӀинца иза дӀахьажийна оцу [[$2]]',
 
 'brokenredirects' => 'ДIахаьдна долу дIасахьажораш',
 'brokenredirectstext' => 'Лахара дӀасахьажийнарш ю йоцучу агӀонийн тӀе хьажийна:',
@@ -1756,8 +1758,8 @@ PICT # тайп тайпан
 'newpages' => 'Керла агlонаш',
 'newpages-username' => 'Декъашхо:',
 'ancientpages' => 'Яззамаш оцу терахьца тӀаьххьара тадар дина долу',
-'move' => 'Цlе хийца',
-'movethispage' => 'Хlокху агlон цlе хийца',
+'move' => 'ЦӀе хийца',
+'movethispage' => 'ХӀокху агӀон цӀе хийца',
 'unusedimagestext' => 'Дехар до, тидаме эца, кхин йолу дуьнана машан-меттигаш а лелош хила мега нийсса йогӀу хьажораг (URL) хӀокху хӀуман, хӀокху могӀаме йогӀуш ялахь яцахь а иза хила мега жигара лелош.',
 'unusedcategoriestext' => 'ХӀокху категорешан чохь агӀонаш я кхин категореш яц.',
 'notargettitle' => 'Ӏалашо билгал йина яц',
@@ -1794,7 +1796,7 @@ PICT # тайп тайпан
 'allinnamespace' => 'Массо агlонаш оцу цlери анахь «$1»',
 'allpagessubmit' => 'Кхочушдé',
 'allpagesprefix' => 'Лаха агlонаш, дlайуьлалуш йолу:',
-'allpagesbadtitle' => 'Цамагош йолу агlон цlе. Коьрта могlан юкъах ю юкъарвики меттанашан юкъе тlечlагlйина йолу хьаьрк йа магийна доцу оцу коьрта моlанца сабол элп йа кхин.',
+'allpagesbadtitle' => 'Цамагош йолу агӀон цӀе. Коьрта могӀан юкъах ю юкъарвики меттанашан юкъе тӀечӀагӀйина йолу хьаьрк йа магийна доцу оцу коьрта моӀанца символаш йа кхин.',
 'allpages-bad-ns' => '{{SITENAME}} кху чохь ана цlераш яц «$1».',
 'allpages-hide-redirects' => 'Къайлаяха дӀасахьажийнарш',
 
@@ -1882,6 +1884,7 @@ PICT # тайп тайпан
 'notanarticle' => 'Бац яззам',
 'watchlist-details' => 'Хьан тергаме могlамца $1 {{PLURAL:$1|агlо|агlонаш|агlонаш}} ю, дийцаре агlонаша йоцуш.',
 'wlheader-showupdated' => "Хийцам бина агӀонаш '''Ӏаьржа''' шрифтцан билгальяха ю.",
+'wlnote2' => 'Лахахьа гайтина {{PLURAL:$1|тӀеххьара сахьт}} чохь бина хийцамаш $2 $3.',
 'wlshowlast' => 'Гайта тlаьххьара $1 сахьташ $2 денош $3',
 'watchlist-options' => 'Тергаме могlаман гlирс нисбар',
 
@@ -1918,6 +1921,7 @@ PICT # тайп тайпан
 ** авторан лаамца
 ** авторан бакъонаш талхор',
 'delete-edit-reasonlist' => 'Бахьанин список нисяр',
+'deleting-backlinks-warning' => "'''ДӀахьедар.''' Ахьа дӀайоккхуш йолчун тӀе товжийна кхин агӀонаш ю.",
 
 # Rollback
 'rollback' => 'Юхабаккха хийцам',
@@ -1944,7 +1948,7 @@ PICT # тайп тайпан
 'unprotectedarticle' => 'ГӀоролла дӀадаьстина «[[$1]]»',
 'movedarticleprotection' => '«[[$2]]» агӀона тӀера гӀаролла «[[$1]]» агӀона тӀе даьккхина',
 'protect-title' => 'Оцунна «$1» гӀоралла дар',
-'prot_1movedto2' => '«[[$1]]» цlе хийцина оцу «[[$2]]»',
+'prot_1movedto2' => '«[[$1]]» цӀе хийцина оцу «[[$2]]»',
 'protect-legend' => 'Бакъде гӀоралла дар',
 'protectcomment' => 'Бахьан:',
 'protectexpiry' => 'Чекхйолу:',
@@ -2188,24 +2192,24 @@ PICT # тайп тайпан
 '''ДӀАХЬЕДАР!'''
 
 ЦӀе хийцар бахьнехь гӀаръялла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
-'movepagetalktext' => "Тlе хlоьттина йолу дийцаре агlо ишта цlе хийцина хира ю, '''цхьа йолу ханчохь, маца:'''
+'movepagetalktext' => "ТӀе хӀоьттина йолу дийцаре агӀо ишта цӀе хийцина хира ю, '''цхьа йолу ханчохь, маца:'''
 
-*Йаьсса йоцу дийцаре агlо йолуш ю оцу цlарца йа
-*Ахьа къастаман харжам цабиняхь а къастам хlотточехь.
+*Йаьсса йоцу дийцаре агӀо йолуш ю оцу цӀарца йа
+*Ахьа къастаман харжам цабиняхь а къастам хӀотточехь.
 
-Ишта чу ханчохь, ахьа дехьа яккха йезар ю йа куьйга хlоттайар, нагахь иза хьашт йалахь.",
+Ишта чу ханчохь, ахьа дехьа яккха йезар ю йа куьйга хӀоттайар, нагахь иза хьашт йалахь.",
 'movearticle' => 'Цle хийца хlокху агlон',
 'moveuserpage-warning' => "'''Тергам бе.''' Хьо декъашхочун агӀона цӀе хийца гӀерта. Дехар до, тергам бе, декъашхочун агӀона цӀе бен хийца лур яц, декъашхочун дӀаяздаран цӀе хийца лур яц.",
 'newtitle' => 'Керла цlе',
 'move-watch' => 'Латайé хӀара агӀо тергаме могӀанан юкъахь',
-'movepagebtn' => 'Агlон цlе хийца',
-'pagemovedsub' => 'Агlон цlе хийцина',
-'movepage-moved' => "'''Агlон цlе «$1» хийцина хlокху «$2»'''",
+'movepagebtn' => 'АгӀон цӀе хийца',
+'pagemovedsub' => 'АгӀон цӀе хийцина',
+'movepage-moved' => "'''АгӀон цӀе «$1» хийцина хӀокху «$2»'''",
 'movepage-moved-redirect' => 'Кхоьллина дӀасахьажориг.',
 'movepage-moved-noredirect' => 'ДӀасхьажориг кхоллар дохина.',
-'articleexists' => 'Хlарасанна цlе йолу агlо йолуш ю йа ахьа гойтуш йолу цlе магош яц.
-Дехар до, харжа кхин цlе.',
-'movetalk' => 'Цуьнца йогlуш йолу дийцаре агlон цlе хийцар',
+'articleexists' => 'ХӀарасанна цӀе йолу агӀо йолуш ю йа ахьа гойтуш йолу цӀе магош яц.
+Дехар до, харжа кхин цӀе.',
+'movetalk' => 'Цуьнца йогӀуш йолу дийцаре агӀон цӀе хийцар',
 'move-subpages' => 'ЦӀeрш хийцае бухара агӀонаши ($1 кхаччалц)',
 'move-talk-subpages' => 'ЦӀе хийца бухара агӀонаши а агӀонашан дийцаре а ($1  кхаччалц)',
 'movepage-page-exists' => 'Агӏо $1 йолуш ю цундела и ша юху дӏаязъян йиш яц.',
@@ -2298,7 +2302,7 @@ PICT # тайп тайпан
 'tooltip-ca-protect' => 'Гlаролла дé хlокху агlон хийцам цабайта',
 'tooltip-ca-unprotect' => 'Дlадаккха хlокху агlонна долу гаролла',
 'tooltip-ca-delete' => 'ДӀаяккха хӀара агӀо',
-'tooltip-ca-move' => 'Агlон цlе хийца',
+'tooltip-ca-move' => 'АгӀон цӀе хийца',
 'tooltip-ca-watch' => 'ТӀетоха хӀара агӀо сан тергаме могӀанан юкъа',
 'tooltip-ca-unwatch' => 'ДӀаяккха хӀара агӀо хьай тергаме могӀанан юкъар',
 'tooltip-search' => 'Лаха иза дош',
@@ -2417,6 +2421,8 @@ PICT # тайп тайпан
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
 'seconds-abbrev' => '$1оцу',
+'minutes-abbrev' => '$1 мин',
+'hours-abbrev' => '$1 сахь.',
 'hours' => '{{PLURAL:$1|1 сахьт}}',
 'days' => '{{PLURAL:$1|$1 де}}',
 'weeks' => '{{PLURAL:$1|$1 кӀира}}',
@@ -2468,8 +2474,10 @@ PICT # тайп тайпан
 'exif-bitspersample' => 'Бесан кIоргалла',
 'exif-photometricinterpretation' => 'Беснин модель',
 'exif-orientation' => 'Суьртан хьал',
+'exif-ycbcrpositioning' => 'Y а C а компонентин листаран кеп',
 'exif-xresolution' => 'Шоралла',
 'exif-yresolution' => 'Локхалла',
+'exif-referenceblackwhite' => 'Ӏаьржа а къай а тӀадамийн меттиг',
 'exif-datetime' => 'Файл хийцина терахь а хан',
 'exif-imagedescription' => 'Суьртан цӏе',
 'exif-make' => 'Камера арахоьцург',
@@ -2477,17 +2485,33 @@ PICT # тайп тайпан
 'exif-software' => 'Лелина программа',
 'exif-copyright' => 'Авторан бакъо ерг',
 'exif-exifversion' => 'Верси Exif',
+'exif-flashpixversion' => 'Ловш йолу верси FlashPix',
 'exif-colorspace' => 'Беснашан хьал',
+'exif-componentsconfiguration' => 'Бесара компонентин конфигураци',
 'exif-compressedbitsperpixel' => 'Бесан кIоргалла дацдина чул тӀехьа',
 'exif-pixelxdimension' => 'Суьртан локхалла',
 'exif-datetimeoriginal' => 'Дуьххьарлера терахь а хан',
 'exif-datetimedigitized' => 'Оцифровк йина терахь а хан а',
-'exif-exposuretime' => 'Экспозицин хан',
+'exif-subsectime' => 'Файлан хийцам баран хан секундашкахь',
+'exif-exposuretime' => 'Сурт доккхуш йолу серлон хьал',
 'exif-fnumber' => 'Диафрагмин дукхалла',
-'exif-maxaperturevalue' => 'Минимальни диафрагмин дукхалла',
+'exif-shutterspeedvalue' => 'APEX чура дешнаш',
+'exif-aperturevalue' => 'APEX чура оьз',
+'exif-exposurebiasvalue' => 'Сурт доккхуш яла оьшу серло меттаяло',
+'exif-maxaperturevalue' => 'Минимальни оьзан дукхалла',
+'exif-meteringmode' => 'Сурт доккхуш яла серло юьстаран хьал',
+'exif-flash' => 'Серлона статус',
 'exif-focallength' => 'Фокусни бохалла',
+'exif-focalplanexresolution' => 'X магийна фокалан тӀапа',
+'exif-focalplaneyresolution' => 'Y магийна фокалан тӀапа',
+'exif-focalplaneresolutionunit' => 'Магоран фокалан дустар',
 'exif-sensingmethod' => 'Сенсоран тайп',
 'exif-filesource' => 'Файлан хьост',
+'exif-customrendered' => 'Кхин тӀе кечдар',
+'exif-exposuremode' => 'Сурт доккхуш йолу серлон хьал харжар',
+'exif-whitebalance' => 'Къайн баланс',
+'exif-digitalzoomratio' => 'Терхьаш дукха хиларан коэффициент',
+'exif-scenecapturetype' => 'Сурт доккхуш йолу меттиган тайп',
 'exif-imageuniqueid' => 'Суьртан номер (ID)',
 'exif-gpslatitude' => 'Шоралла',
 'exif-gpslongitude' => 'Дохалла',
@@ -2522,14 +2546,27 @@ PICT # тайп тайпан
 
 'exif-xyresolution-i' => '$1 тӏадамаш дюйман',
 
+'exif-meteringmode-5' => 'Матрин',
+
 'exif-lightsource-1' => 'Ден хьехам',
+'exif-lightsource-4' => 'Серло',
 'exif-lightsource-9' => 'Хаза хенан хӀоттам',
 'exif-lightsource-10' => 'Мархаш йолу',
 
+'exif-focalplaneresolutionunit-2' => 'дюйм',
+
 'exif-filesource-3' => 'Терахьийн суртдохку аппарат',
 
 'exif-scenetype-1' => 'Сурт даьккхина нис дуьххьал',
 
+'exif-customrendered-0' => 'ХӀума дийна дац',
+'exif-customrendered-1' => 'Нийса доцу кечдар',
+
+'exif-whitebalance-0' => 'Къайн автоматически баланс',
+'exif-whitebalance-1' => 'Куьйга хӀоттийна къайн баланс',
+
+'exif-scenecapturetype-0' => 'Стандартан',
+
 'exif-gaincontrol-0' => 'Яц',
 
 'exif-contrast-0' => 'Лартӏахь',
@@ -2538,6 +2575,8 @@ PICT # тайп тайпан
 
 'exif-sharpness-0' => 'Лартӏахь',
 
+'exif-ycbcrpositioning-1' => 'Юкъйина',
+
 'exif-dc-date' => 'Терахь(ш)',
 'exif-dc-rights' => 'Бакъонаш',
 
@@ -2631,6 +2670,7 @@ MediaWiki яржош ю и шуна пайдане хир яц те аьлла,
 Шоьга кхача езаш яра [{{SERVER}}{{SCRIPTPATH}}/COPYING копи GNU General Public License] хӀокху программица, кхаьчна яцахь язъе Free Software Foundation, Inc., адрес тӀе: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA я [//www.gnu.org/licenses/old-licenses/gpl-2.0.html еша и онлайнехь].',
 'version-software' => 'ДӀахӀоттийна программин латтор',
 'version-software-version' => 'Верси',
+'version-entrypoints' => 'ЧугӀо адресин тӀадамаш',
 
 # Special:Redirect
 'redirect' => 'Декъашхочун файлан тӀера дӀасхьажор',
@@ -2737,7 +2777,7 @@ MediaWiki яржош ю и шуна пайдане хир яц те аьлла,
 'logentry-newusers-newusers' => '{{GENDER:$2|ДӀавазвелла|ДӀаязелла}} керла декъашхо $1',
 'logentry-newusers-create' => '{{GENDER:$2|ДӀавазвелла|ДӀаязелла}} керла декъашхо $1',
 'logentry-newusers-autocreate' => 'Автоматически кхоьллина {{GENDER:$2|декъашхочун}} $1 дӀаяздар',
-'logentry-rights-rights' => '$1 {{GENDER:$2|хийцина}} хӀокхуна $3 бакъо $4 → $5',
+'logentry-rights-rights' => '$1 {{GENDER:$2|хийцина}} $3 бакъо $4 → $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$2|хийцина}} хӏокхуна $3 бакъо',
 'rightsnone' => '(яц)',
 
index 4f7cfb7..d69400c 100644 (file)
@@ -22,6 +22,7 @@
  * @author Littledogboy
  * @author Martin Kozák
  * @author Matěj Grabovský
+ * @author Matěj Suchánek
  * @author Mercy
  * @author Michawiki
  * @author Mormegil
@@ -1189,7 +1190,7 @@ Zřejmě byla smazána.',
 'invalid-content-data' => 'Obsažená data jsou chybná',
 'content-not-allowed-here' => 'Obsah typu $1 není na stránce [[$2]] dovolen.',
 'editwarning-warning' => 'Opuštěním této stránky se mohou veškeré provedené změny ztratit.
-Přihlášení uživatelé si mohou toto varování vypnout na záložce „Editace“ v uživatelském nastavení.',
+Přihlášení uživatelé si mohou toto varování vypnout na záložce „{{int:prefs-editing}}“ v uživatelském nastavení.',
 'editpage-notsupportedcontentformat-title' => 'Nepodporovaný formát obsahu',
 'editpage-notsupportedcontentformat-text' => 'Model obsahu $2 nepodporuje formát obsahu $1.',
 
@@ -1404,6 +1405,8 @@ Ujistěte se, že tato změna udrží souvislost a posloupnost verzí v historii
 'showhideselectedversions' => 'Zobrazit/skrýt vybrané revize',
 'editundo' => 'zrušit editaci',
 'diff-empty' => '(Žádný rozdíl)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Není zobrazena 1 mezilehlá verze|Nejsou zobrazeny $1 mezilehlé verze|Není zobrazeno $1 mezilehlých verzí}} od stejného uživatele.)',
+'diff-multi-otherusers' => '({{PLURAL:$1|Není zobrazena 1 mezilehlá verze|Nejsou zobrazeny $1 mezilehlé verze|Není zobrazeno $1 mezilehlých verzí}} od {{PLURAL:$2|1 dalšího uživatele|$2 dalších uživatelů}}.)',
 'diff-multi-manyusers' => '(Není zobrazeno $1 mezilehlých verzí od více než $2 {{PLURAL:$2|uživatele|uživatelů}}.)',
 'difference-missing-revision' => '{{PLURAL:$2|Jedna z revizí|$2 revize|$2 revizí}} k požadovanému porovnání ($1) {{PLURAL:$2|neexistuje|neexistují|neexistuje}}.
 
@@ -2519,7 +2522,7 @@ Rady a kontakt:
 'confirmdeletetext' => 'Chystáte se smazat stránku s celou její historií. Prosím potvrďte, že to opravdu chcete učinit, že si uvědomujete důsledky a že je to v souladu s [[{{MediaWiki:Policy-url}}|pravidly]].',
 'actioncomplete' => 'Provedeno',
 'actionfailed' => 'Operace se nezdařila',
-'deletedtext' => 'Stránka nebo soubor „$1“ byla smazána. $2 zaznamenává poslední smazání.',
+'deletedtext' => 'Stránka nebo soubor „$1“ byl(a) smazán(a). $2 zaznamenává poslední smazání.',
 'dellogpage' => 'Kniha smazaných stránek',
 'dellogpagetext' => 'Zde je seznam posledních smazaných stránek.',
 'deletionlog' => 'Kniha smazaných stránek',
@@ -2536,7 +2539,7 @@ Rady a kontakt:
 'delete-edit-reasonlist' => 'Editovat důvody smazání',
 'delete-toobig' => 'Tato stránka má velkou historii editací, přes $1 {{PLURAL:$1|verzi|verze|verzí}}. Mazání takových stránek je omezeno, aby se předešlo nechtěnému narušení {{grammar:2sg|{{SITENAME}}}}.',
 'delete-warning-toobig' => 'Tato stránka má velkou historii editací, přes $1 {{PLURAL:$1|verzi|verze|verzí}}. Mazání takových stránek může narušit databázové operace {{grammar:2sg|{{SITENAME}}}}; postupujte opatrně.',
-'deleting-backlinks-warning' => "'''Upozornění:''' Stránka, kterou se chystáte smazat, je na jiných stránkách odkazována nebo vkládána.",
+'deleting-backlinks-warning' => "'''Upozornění:''' Stránka, kterou se chystáte smazat, je na jiných stránkách odkazována nebo je do nich vložena.",
 
 # Rollback
 'rollback' => 'Vrátit zpět editace',
@@ -2548,7 +2551,7 @@ Rady a kontakt:
 'cantrollback' => 'Nelze vrátit zpět poslední editaci, neboť poslední přispěvatel je jediným autorem této stránky.',
 'alreadyrolled' => 'Nelze vrátit zpět poslední editaci [[:$1]] od uživatele [[User:$2|$2]] ([[User talk:$2|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), protože někdo jiný již stránku editoval nebo vrátil tuto změnu zpět.
 
-Poslední editaci této stránky provedl(a) [[User:$3|$3]] ([[User talk:$3|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
+Poslední editaci této stránky {{PLURAL:$3|provedl|provedla|provedl uživatel}} [[User:$3|$3]] ([[User talk:$3|diskuse]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
 'editcomment' => "Shrnutí editace bylo: ''„$1“''.",
 'revertpage' => 'Editace uživatele „[[Special:Contributions/$2|$2]]“ ([[User talk:$2|diskuse]]) vráceny do předchozího stavu, jehož autorem je „[[User:$1|$1]]“',
 'revertpage-nouser' => 'Editace skrytého uživatele vráceny do předchozího stavu, jehož {{GENDER:$1|autorem|autorkou}} je „[[User:$1|$1]]“',
index d792bf0..bb3aacc 100644 (file)
@@ -417,7 +417,7 @@ $messages = array(
 'viewtalkpage' => 'Se diskussion',
 'otherlanguages' => 'Andre sprog',
 'redirectedfrom' => '(Omdirigeret fra $1)',
-'redirectpagesub' => 'Omdirigering',
+'redirectpagesub' => 'Omdirigeringsside',
 'lastmodifiedat' => 'Denne side blev senest ændret $1 kl. $2.',
 'viewcount' => 'Siden er vist {{PLURAL:$1|en gang|$1 gange}}.',
 'protectedpage' => 'Beskyttet side',
@@ -2000,7 +2000,7 @@ Husk at kontrollere for andre henvisninger til skabelonerne før de slettes.',
 'statistics' => 'Statistik',
 'statistics-header-pages' => 'Sidestatistik',
 'statistics-header-edits' => 'Redigeringsstatistik',
-'statistics-header-views' => 'Visningsstatistik',
+'statistics-header-views' => 'Statistik over sidevisninger',
 'statistics-header-users' => 'Statistik om brugere på {{SITENAME}}',
 'statistics-header-hooks' => 'Anden statistik',
 'statistics-articles' => 'Indholdssider',
@@ -2969,7 +2969,7 @@ Du kan se på kildeteksten.',
 'tooltip-watch' => 'Tilføj denne side til din overvågningsliste',
 'tooltip-watchlistedit-normal-submit' => 'Fjern titler',
 'tooltip-watchlistedit-raw-submit' => 'Opdater overvågningsliste',
-'tooltip-recreate' => 'Opret side, selv om den blev slettet.',
+'tooltip-recreate' => 'Genopret side, selv om den blev slettet.',
 'tooltip-upload' => 'Upload fil',
 'tooltip-rollback' => '"Rul tilbage" fjerner den sidste bidragsyders redigering(er) af denne side med et klik',
 'tooltip-undo' => '"Fjern redigering" fjerner denne redigering og åbner redigeringssiden med forhåndsvisning.
@@ -3005,7 +3005,7 @@ Det giver mulighed for at tilføje en begrundelse i beskrivelsen.',
 'spamprotectiontext' => 'Siden du ønskede at gemme, blev blokeret af spamfilteret.
 Dette skyldes sandsynligvis en henvisning til et sortlistet eksternt websted.',
 'spamprotectionmatch' => 'Følgende tekst udløste vores spamfilter: $1',
-'spambot_username' => 'MediaWiki spam-rensning',
+'spambot_username' => 'MediaWikis spamoprydning',
 'spam_reverting' => 'Sidste version uden henvisning til $1 gendannet.',
 'spam_blanking' => 'Alle versioner, som indeholdt henvisninger til $1, er renset.',
 'spam_deleting' => 'Alle versioner indeholder henvisninger til $1, sletter',
@@ -3652,7 +3652,7 @@ hvorfor siden blev slettet. Hvis du gemmer siden bliver den oprettet igen.",
 : ''$2''
 Bekræft venligst, at du virkelig vil oprette denne side igen.",
 'confirmrecreate-noreason' => '[[User:$1|$1]] ([[User talk:$1|diskussion]]) har slettet denne side, efter du begyndte at redigere. Bekræft venligst, at du gerne vil genoprette siden.',
-'recreate' => 'Opret igen',
+'recreate' => 'Genopret',
 
 # action=purge
 'confirm_purge_button' => 'O.k.',
index 6ad4ec3..2d208ee 100644 (file)
@@ -1255,7 +1255,7 @@ Sie wurde anscheinend gelöscht.',
 'invalid-content-data' => 'Ungültige Inhaltsdaten',
 'content-not-allowed-here' => 'Der Inhalt „$1“ ist auf der Seite [[$2]] nicht erlaubt',
 'editwarning-warning' => 'Das Verlassen dieser Seite kann dazu führen, dass deine Änderungen verloren gehen.
-Wenn du angemeldet bist, kannst du das Anzeigen dieser Warnung im Bereich „Bearbeiten“ deiner Einstellungen abschalten.',
+Wenn du angemeldet bist, kannst du das Anzeigen dieser Warnung im Bereich „{{int:prefs-editing}}“ deiner Einstellungen abschalten.',
 'editpage-notsupportedcontentformat-title' => 'Das Inhaltsformat wird nicht unterstützt',
 'editpage-notsupportedcontentformat-text' => 'Das Inhaltsformat $1 wird vom Inhaltsmodell $2 nicht unterstützt.',
 
@@ -1290,6 +1290,7 @@ Sie darf nicht mehr als $2 {{PLURAL:$2|Aufruf|Aufrufe}} haben, es {{PLURAL:$1|is
 Bitte prüfe den Vergleich unten, um sicherzustellen, dass du dies tun möchtest, und speichere dann unten deine Änderungen, um die Bearbeitung rückgängig zu machen.',
 'undo-failure' => 'Die Änderung konnte nicht rückgängig gemacht werden, da der betroffene Abschnitt zwischenzeitlich verändert wurde.',
 'undo-norev' => 'Die Bearbeitung konnte nicht rückgängig gemacht werden, da sie nicht vorhanden ist oder gelöscht wurde.',
+'undo-nochange' => 'Anscheinend wurde diese Bearbeitung bereits rückgängig gemacht.',
 'undo-summary' => 'Änderung $1 von [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussion]]) rückgängig gemacht.',
 'undo-summary-username-hidden' => 'Änderung $1 eines versteckten Benutzers rückgängig gemacht.',
 
index 5738e26..15a0c02 100644 (file)
@@ -1209,10 +1209,10 @@ Sebebo ke terefê $3 ra diyao ''$2''",
 'last' => 'peyên',
 'page_first' => 'verên',
 'page_last' => 'peyên',
-'histlegend' => "Ferqê weçinayışi: Qutiya versiyonan mor ke u  ''enter''i bıpıloxne ya zi makera cêrêne bıpıloxne.<br /> 
-Lecant: '''({{int:cur}})''' = ferqê versiyonê peyêni, '''({{int:last}})''' = ferqê versiyonê verêni, '''{{int:minoreditletter}}''' = vurnayışo werdi.",
+'histlegend' => "Ferqê weçinıtışi: Qutiya versiyonan seba têversanayış işaret ke û dest be ''enter''i ya zi gocega cêrêne ro ne.<br />
+Cedwel: <strong>({{int:ferq}})</strong> = ferqê verziyonê peyêni, <strong>({{int:peyên}})</strong> = ferqê versiyonê verêni, <strong>{{int:q}}</strong> = vurnayışo werdi.",
 'history-fieldset-title' => 'Tarixi bıvêne',
-'history-show-deleted' => 'Tenya esterıt',
+'history-show-deleted' => 'Tenya esterıtey',
 'histfirst' => 'Verênêr',
 'histlast' => 'Peyênêr',
 'historysize' => '({{PLURAL:$1|1 bayt|$1 bayti}})',
@@ -1755,11 +1755,11 @@ Eka tu wazene ke nameyo raşt xo bide, ma nameyo raşt ti iştirakanê ti de moc
 'recentchangeslinked' => 'Vurnayışê elaqeyıni',
 'recentchangeslinked-feed' => 'Vurnayışê elaqeyıni',
 'recentchangeslinked-toolbox' => 'Vurnayışê elaqeyıni',
-'recentchangeslinked-title' => 'vurnayışan ser "$1"',
+'recentchangeslinked-title' => 'Heqa "$1" de vurnayışi',
 'recentchangeslinked-summary' => "Lista cêrêne, pela bêlikerdiye rê (ya zi karberanê kategoriya bêlikerdiye rê) pelanê gırêdayoğan de lista de vurnayışê peyênana.
 [[Special:Watchlist|Lista şımaya seyrkedışi de]] peli be nuşteyo '''qolınd''' bêli kerdê.",
 'recentchangeslinked-page' => 'Nameyê pele:',
-'recentchangeslinked-to' => 'Pelayan ke ena pela ri gire bi, ser ayi vurnayışi bımoc',
+'recentchangeslinked-to' => 'Heruna pela ke yena dayene, vurnayışanê pelanê ke daye ra gırêdayiyê inan bımocne',
 
 # Upload
 'upload' => 'Dosya bar ke',
@@ -2027,7 +2027,7 @@ keyepel nıka zaf meşğulo yew dema herayi de newe ra tesel bıkerê.',
 # File description page
 'file-anchor-link' => 'Dosya',
 'filehist' => 'Ravêrdê dosya',
-'filehist-help' => 'bıploxne ser yew tarih u aye tarih dı versionê dosya bıvin.',
+'filehist-help' => 'Seba diyayışê viyarteyê dosya tarixê ke qısımê tarix/zemani derê inan bıtıkne.',
 'filehist-deleteall' => 'pêro bestere',
 'filehist-deleteone' => 'bestere',
 'filehist-revert' => 'reyna biyere',
@@ -2250,7 +2250,7 @@ Xo vira mekerê ke, sıteyê webiê bini şenê direkt ebe URLi yew dosya ra gı
 
 # Book sources
 'booksources' => 'Çımey kitaban',
-'booksources-search-legend' => 'Ser çımey kitaban bıgeyr',
+'booksources-search-legend' => 'Seba çımeyanê kıtaban cı geyre',
 'booksources-isbn' => 'ISBN:',
 'booksources-go' => 'Şo',
 'booksources-text' => 'listeya cêrıni, keyepelê kitap rotoxan o.',
@@ -2659,8 +2659,8 @@ $1',
 'contribsub2' => 'Qandê {{GENDER:$3|$1}} ($2)',
 'nocontribs' => 'Ena kriteriya de vurnayîş çini yo.',
 'uctop' => '(weziyet)',
-'month' => 'Aşm:',
-'year' => 'Ser:',
+'month' => 'Aşme:',
+'year' => 'Serre:',
 
 'sp-contributions-newbies' => 'Tenya iştıraqanê karberanê neweyan bımocne',
 'sp-contributions-newbies-sub' => 'Qe hesebê newe',
@@ -2723,7 +2723,7 @@ Cıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:',
 'ipbenableautoblock' => 'verniyê IPadresa peyin ê no karberi u wexta ke vurnayişi kerd ê IPadresani otomotik bıger.',
 'ipbsubmit' => 'Ena karber blok bike',
 'ipbother' => 'Waxtê bini:',
-'ipboptions' => '2 seat:2 hours,1 roc:1 day,3 roci:3 days,1 hefte:1 week,2 heftey:2 weeks,1 aşm:1 month,3 aşm:3 months,6 aşmi:6 months,1 ser:1 year,ebedi:infinite',
+'ipboptions' => '2 saeti:2 hours,1 roce:1 day,3 roci:3 days,1 hefte:1 week,2 heftey:2 weeks,1 aşme:1 month,3 aşmi:3 months,6 aşmi:6 months,1 serre:1 year,ebedi:infinite',
 'ipbhidename' => 'Nameyê karberî listeyan u vurnayîşan ra binumne',
 'ipbwatchuser' => 'Pela miniqaşe u pela ena karberî seyr bike',
 'ipb-disableusertalk' => 'No karber wexto ke bloqedeyo wa pela da xodı vurnayış kerdışi rê izin medı',
@@ -3109,7 +3109,7 @@ dosyaya emaneti vindbiyo',
 'tooltip-ca-nstab-help' => 'Pela peşti bıvêne',
 'tooltip-ca-nstab-category' => 'Pela kategoriye bıvêne',
 'tooltip-minoredit' => 'Nay vırnayışa werdi nışan bıkeré',
-'tooltip-save' => 'Vurnayışa qeyd ke',
+'tooltip-save' => 'Vurnayışanê xo qeyd ke',
 'tooltip-preview' => 'Vurnayışané ğo çımra ravyarné. Verdé qeyd kerdışi eneri bıkarné!',
 'tooltip-diff' => 'Metni sero vurnayışan mocneno',
 'tooltip-compareselectedversions' => 'Ena per de ferqê rewziyonan de dı weçinaya bıvinê',
index b8f93ff..5536a42 100644 (file)
@@ -567,6 +567,48 @@ La cêva 'd ingrès la pré èser stêda bèle cambiêda, opór n'in pré èser
 'passwordreset-capture-help' => "S' es sernés cla caşèla ché, l'indirés ed pôsta eletrônica (cun la cêva 'd ingrès pruvişôria), év vîn fâ vèder, d'ed là 'd èser spidî a l'utèint.",
 'passwordreset-email' => 'Indirés pôsta eletrônica',
 'passwordreset-emailtitle' => "Particulêr ed l'utèint só {{SITENAME}}",
+'passwordreset-emailtext-ip' => "Quelchidûn (prubabilmèint té, cun l'indirés IP $1) l'à dmandê de spidîregh 'na nōva cêva 'd ingrès per andêr dèinter a {{SITENAME}} ($4). {{PLURAL:$3|L'utèint inscrét| J utèint inscrét}} a sté indirés ed pôsta eletrônica în:
+$2 
+
+{{PLURAL:$3|Cla cêva 'd ingrès pruvişôria la scadrà| St' al cêvi 'd ingrès pruvişôri ché scadrân}} dôp {{PLURAL:$5|ûn dé|$5 dé}}. Ét duvrés andêr dèinter e sernîr 'na cêva 'd ingrès nōva adès. 
+
+Se t'é mìa stê té a fêr la dmânda, o s' ét t'é ricurdê la cêva 'd ingrès uriginêla e an 't vō mia pió cambiêrla, ét pō scanşlêr cól mesâg ché e cuntinvêr a druvêr la tó cêva 'd ingrès vècia.",
+'passwordreset-emailtext-user' => "L'utèint $1 ed {{SITENAME}} l'à dmandê de spidîregh 'na nōva cêva 'd ingrès per andêr dèinter a {{SITENAME}} ($4). {{PLURAL:$3|L'utèint inscrét| J utèint inscrét}} a sté indirés ed pôsta eletrônica în:
+
+$2 
+
+{{PLURAL:$3|Cla cêva 'd ingrès pruvişôria ché la scadrà| St' al cêvi 'd ingrès pruvişôri ché scadrân}} dôp {{PLURAL:$5|ûn dé|$5 dé}}. Ét duvrés andêr dèinter e sernîr 'na cêva 'd ingrès nōva adès. 
+
+Se t'é mìa stê té a fêr la dmânda, o s' ét t'é ricurdê la cêva 'd ingrès uriginêla e an 't vō mia pió cambiêrla, ét pō scanşlêr cól mesâg ché e cuntinvêr a druvêr la tó cêva 'd ingrès vècia",
+'passwordreset-emailelement' => "Nòm utèint: $1.
+Cêva 'd ingrès pruvişôria: $2",
+'passwordreset-emailsent' => "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès.",
+'passwordreset-emailsent-capture' => "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, ché sòta a gh'é al tèst che gh'é scrét.",
+'passwordreset-emailerror-capture' => "É stê fât un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, scréta ché 'd sègvit. La spedisiòun {{GENDER:$2|a l'utèint}} an n'é mia 'riusîda:$1",
+
+# Special:ChangeEmail
+'changeemail' => "Câmbia l'indirés ed la pôsta eletrônica",
+'changeemail-header' => "Câmbia l'indirés ed la pôsta eletrônica 'd la tó inscrisiòun.",
+'changeemail-text' => "Impés sté mòdul per cambiêr al tó indirés ed pòsta eletrônica. A srà necesâri mèter dèinter la cêva 'd ingrès per cunfermêr la mudéfica.",
+'changeemail-no-info' => "Per andêr dèinter diretamèint a cla pàgina ché 't gh'ê da fêr l'ingrès.",
+'changeemail-oldemail' => "L'indirés ed la pôsta eletrànica 'd adès.",
+'changeemail-newemail' => 'Nōv indirés ed pàsta eletrônica:',
+'changeemail-none' => '(nisûn)',
+'changeemail-password' => "La cêva 'd ingrès só {{SITENAME}}:",
+'changeemail-submit' => "Cambiêr l'indirés ed pôsta eletrônica",
+'changeemail-cancel' => 'Scanşèla',
+'changeemail-throttled' => "În stê fât trôp tentatîv 'd ingrès in pôch tèimp. Spèta $1 e pó tōrna pruvêr dôp.",
+
+# Special:ResetTokens
+'resettokens' => "Tōrna 'd impustêr la cêva",
+'resettokens-text' => "Ché 't pō turnêr a impustêr al cêvi ch'ét permèten l'ingrès a precîşi infurmasiòun privêdi lighêdi a la tó utèinsa. Ét duvrés fêrel se per chêş ét j ê spartîdi cun quelchidûn o se al j infurmasiòun ed la tó utèinsa în  in perécol.",
+'resettokens-no-tokens' => "An gh'é mìa di token da turnêr a impustêr.",
+'resettokens-legend' => "Tōrna 'd impustêr la cêva",
+'resettokens-token-label' => "$1 (valōr 'd adèsa: $2)",
+'resettokens-watchlist-token' => "Token p'r al feed web (Atom/RSS) dal [[Special:Watchlist|mudéfichi al pàgini ch'ét tîn sòt' ôc]]",
+'resettokens-done' => 'Token turnê a impustêr.',
+'resettokens-resetbutton' => 'Més a zēro i token sernî',
 
 # Edit page toolbar
 'bold_sample' => 'Grasèt',
@@ -588,13 +630,16 @@ La cêva 'd ingrès la pré èser stêda bèle cambiêda, opór n'in pré èser
 
 # Edit pages
 'summary' => 'Sûnt:',
+'subject' => 'Argumèint (tétol):',
 'minoredit' => "Còsta l'é 'na mudéfica céca",
 'watchthis' => 'Tîn adrē a cla pàgina ché',
 'savearticle' => 'Sêlva la pàgina',
 'preview' => 'Guêrda préma',
 'showpreview' => "Guêrda préma 'd salvêr",
+'showlivepreview' => 'Guêrda préma diretamèint',
 'showdiff' => 'Guêrda i cambiamèint',
 'anoneditwarning' => "'''Atensiòun:''' Ingrès mìa fât. Al tó indirés IP al srà sgnê int la stòria ed cla pàgina chè.",
+'anonpreviewwarning' => "\"An n'é mìa stê fât l'ingrès. Mèinter es sêlva la pàgina, l'indirés IP al srà sgnê int la stòria 'd la pàgina.\"",
 'blockedtitle' => 'Utèint bluchê',
 'newarticle' => '(Nōv)',
 'newarticletext' => "Al colegamèint apèina fât al cumbîna cun 'na pàgina ch' an n'é mìa incòra stêda fâta. S'ét vō fêr la pàgina adès, l'é asê cumincêr a scréver al tèst int la caşèla ché sòt (per vedèr infurmasiòun pió precîşi guêrda la [[{{MediaWiki:Helppage}}|pàgina 'd ajót]]). Se al colegamèint  l'é stê avêrt per erōr, l'é asê clichêr al pulsânt \"Indrē\" dal tó navigadōr.",
index 9bd4dd9..2398c4b 100644 (file)
@@ -1173,8 +1173,8 @@ $2
 'content-failed-to-parse' => 'Απέτυχε η ανάλυση  περιεχομένου του $2 για το μοντέλο $1:$3',
 'invalid-content-data' => 'Μη έγκυρα δεδομένα περιεχομένου',
 'content-not-allowed-here' => 'Το περιεχόμενο «$1» δεν επιτρέπεται στη σελίδα [[$2]]',
-'editwarning-warning' => 'Αφήνοντας αυτή τη σελίδα μπορεί να σας κάνει να χάσετε κάποιες αλλαγές που έχετε κάνει.
-Αν έχετε συνδεθεί, μπορείτε να απενεργοποιήσετε αυτή την προειδοποίηση στην  ενότητα "Επεξεργασία" των προτιμήσεών σας.',
+'editwarning-warning' => 'Αφήνοντας αυτή τη σελίδα μπορεί να έχει ως συνέπεια να χαθούν κάποιες αλλαγές που έχετε κάνει.
+Αν έχετε συνδεθεί, μπορείτε να απενεργοποιήσετε αυτή την προειδοποίηση στην  ενότητα "{{int:prefs-editing}}"  των προτιμήσεών σας.',
 
 # Content models
 'content-model-wikitext' => 'βικικείμενο',
@@ -3888,6 +3888,11 @@ $5
 'version-hook-subscribedby' => 'Υπογεγραμμένο από',
 'version-version' => '(Έκδοση $1)',
 'version-license' => 'Άδεια χρήσης',
+'version-ext-license' => 'Άδεια χρήσης',
+'version-ext-colheader-name' => 'Επέκταση',
+'version-ext-colheader-version' => 'Έκδοση',
+'version-ext-colheader-license' => 'Άδεια χρήσης',
+'version-ext-colheader-description' => 'Περιγραφή',
 'version-poweredby-credits' => "Αυτό το wiki λειτουργεί με το λογισμικό '''[https://www.mediawiki.org/ MediaWiki]''', πνευματική ιδιοκτησία © 2001-$1 $2.",
 'version-poweredby-others' => 'άλλοι',
 'version-poweredby-translators' => 'translatewiki.net μεταφραστές',
index 5d42c83..88b729d 100644 (file)
@@ -1616,6 +1616,7 @@ These arguments have been omitted.",
 Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.',
 'undo-failure'                 => 'The edit could not be undone due to conflicting intermediate edits.',
 'undo-norev'                   => 'The edit could not be undone because it does not exist or was deleted.',
+'undo-nochange'                => 'The edit appears to have already been undone.',
 'undo-summary'                 => 'Undo revision $1 by [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]])',
 'undo-summary-username-hidden' => 'Undo revision $1 by a hidden user',
 
@@ -1854,6 +1855,7 @@ Details can be found in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENA
 'searchrelated'                    => 'related',
 'searchall'                        => 'all',
 'showingresults'                   => "Showing below up to {{PLURAL:$1|<strong>1</strong> result|<strong>$1</strong> results}} starting with #<strong>$2</strong>.",
+'showingresultsinrange'            => "Showing below up to {{PLURAL:$1|<strong>1</strong> result|<strong>$1</strong> results}} in range #<strong>$2</strong> to #<strong>$3</strong>.",
 'showingresultsnum'                => "Showing below {{PLURAL:$3|<strong>1</strong> result|<strong>$3</strong> results}} starting with #<strong>$2</strong>.",
 'showingresultsheader'             => "{{PLURAL:$5|Result <strong>$1</strong> of <strong>$3</strong>|Results <strong>$1 - $2</strong> of <strong>$3</strong>}} for <strong>$4</strong>",
 'search-nonefound'                 => 'There were no results matching the query.',
@@ -3358,7 +3360,7 @@ See the [[Special:BlockList|block list]] to review blocks.',
 'contribslink'                    => 'contribs',
 'emaillink'                       => 'send email',
 'autoblocker'                     => 'Autoblocked because your IP address has been recently used by "[[User:$1|$1]]".
-The reason given for $1\'s block is "<em>$2</em>"',
+The reason given for $1\'s block is "$2"',
 'blocklogpage'                    => 'Block log',
 'blocklog-showlog'                => 'This user has been blocked previously.
 The block log is provided below for reference:',
index 68297e3..109a586 100644 (file)
@@ -1131,7 +1131,7 @@ See on juba olemas.',
 'invalid-content-data' => 'Vigased sisuandmed',
 'content-not-allowed-here' => 'Lehekülg [[$2]] ei või sisaldada $1i.',
 'editwarning-warning' => 'Sellelt leheküljelt lahkumise tõttu võivad tehtud muudatused kaotsi minna.
-Kui oled sisse loginud, saad selle hoiatuse eelistuste alaosas "Toimetamine" keelata.',
+Kui oled sisse loginud, saad selle hoiatuse eelistuste alaosas "{{int:prefs-editing}}" keelata.',
 'editpage-notsupportedcontentformat-title' => 'Sisuvormingu tugi puudub',
 'editpage-notsupportedcontentformat-text' => 'Sisumudelil $2 puudub sisuvormingu $1 tugi.',
 
@@ -1343,6 +1343,8 @@ Pane tähele, et navigeerimislinkide kasutamine lähtestab redaktsioonide valiku
 'showhideselectedversions' => 'Muuda valitud redaktsioonide nähtavust',
 'editundo' => 'eemalda',
 'diff-empty' => '(Erinevus puudub)',
+'diff-multi-sameuser' => '(ei näidata sama kasutaja {{PLURAL:$1|üht|$1}} vahepealset redaktsiooni)',
+'diff-multi-otherusers' => '(ei näidata {{PLURAL:$2|ühe teise|$2}} kasutaja {{PLURAL:$1|üht|$1}} vahepealset redaktsiooni)',
 'diff-multi-manyusers' => '({{PLURAL:$1|Ühte|$1}} vahepealset rohkem kui {{PLURAL:$2|ühe|$2}} kasutaja redaktsiooni ei näidata.)',
 'difference-missing-revision' => 'Selle erinevuste vaate {{PLURAL:$2|üht|$2}} redaktsiooni ($1) ei leitud.
 
index 2e15d4a..2514d6b 100644 (file)
@@ -1303,8 +1303,8 @@ $2
 'content-failed-to-parse' => 'عدم موفقیت در تجزیه محتوای $2 برای مدل $1: $3',
 'invalid-content-data' => 'داده محتوای نامعتبر',
 'content-not-allowed-here' => 'محتوای «$1» در صفحهٔ [[$2]] مجاز نیست',
-'editwarning-warning' => 'خرÙ\88ج Ø§Ø² Ø§Û\8cÙ\86 ØµÙ\81Ø­Ù\87 Ù\85Ù\85Ú©Ù\86 Ø§Ø³Øª Ø¨Ø§Ø¹Ø« Ø§Ø² Ø¯Ø³Øª Ø±Ù\81تÙ\86 Ù\87رÚ\86Ù\87 Ù\86Ù\88شتÙ\87â\80\8cاÛ\8cد Ø´Ù\88د.
-اگر شما با نام کاربری وارد شده‌اید می‌توانید این هشدار را در بخش «در حال ویرایش» ترجیحاتتان بیابید.',
+'editwarning-warning' => 'خرÙ\88ج Ø§Ø² Ø§Û\8cÙ\86 ØµÙ\81Ø­Ù\87 Ù\85Ù\85Ú©Ù\86 Ø§Ø³Øª Ø¨Ø§Ø¹Ø« Ø´Ù\88د Ú©Ù\87 Ø´Ù\85ا Ù\87ر Ø´Ø§Ù\86سÛ\8c Ú©Ù\87 Ø¨Ù\87 Ù\88جÙ\88د Ø¢Ù\88ردÙ\87 Ø§Û\8cد Ø±Ø§ Ø§Ø² Ø¯Ø³Øª Ø¨Ø¯Ù\87Û\8cد.
+اگر شما وارد سیستم شده‌اید، می‌توانید این هشدار را در بخش «در حال ویرایش» ترجیحاتتان غیرفعال کنید.',
 'editpage-notsupportedcontentformat-title' => 'فرمت محتوا پشتیبانی نشده',
 'editpage-notsupportedcontentformat-text' => 'فرمت محتوای $1 توسط مدل محتوای $2 پشتیبانی نشده‌است.',
 
@@ -1518,6 +1518,8 @@ $1",
 'showhideselectedversions' => 'نمایش/نهفتن نسخه‌های انتخاب شده',
 'editundo' => 'خنثی‌سازی',
 'diff-empty' => '(بدون تفاوت)',
+'diff-multi-sameuser' => '({{PLURAL:$1|یک نسخهٔ متوسط|$1 نسخه‌های متوسط}} توسط کاربر مشابهی که نشان داده نشده)',
+'diff-multi-otherusers' => '({{PLURAL:$1|یک نسخهٔ متوسط|$1 نسخه‌های متوسط}} توسط {{PLURAL:$2|کاربر دیگری|$2 کاربران}} نشان داده نشده)',
 'diff-multi-manyusers' => '({{PLURAL:$1|یک|$1}} ویرایش میانی توسط بیش از {{PLURAL:$2|یک|$2}} کاربر نشان داده نشده‌است)',
 'difference-missing-revision' => '{{PLURAL:$2|یک ویرایش|$2 ویرایش}}  از تفاوت نسخه‌ها ($1) {{PLURAL:$2|یافت|یافت}}  نشد.
 
@@ -1538,7 +1540,7 @@ $1",
 'shown-title' => 'نمایش $1 {{PLURAL:$1|نتیجه|نتیجه}} در هر صفحه',
 'viewprevnext' => 'نمایش ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "'''صفحه‌ای با عنوان «[[:$1]]» در این ویکی وجود دارد.'''",
-'searchmenu-new' => "'''صفحهٔ «[[:$1]]» را در این ویکی بسازید!'''",
+'searchmenu-new' => '<strong>ایجاد صفحه "[[:$1]]" در این ویکی!</strong> {{PLURAL:$2|0=|همچنین مشاهدهٔ صفحهٔ پیدا شده با جستجوی شما.|همچنین مشاهدهٔ جستجوی نتایج پیدا شده.}}',
 'searchprofile-articles' => 'صفحه‌های محتوایی',
 'searchprofile-project' => 'صفحه‌های راهنما و پروژه',
 'searchprofile-images' => 'چندرسانه‌ای',
@@ -2577,6 +2579,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
 'watchmethod-list' => 'بررسی صفحه‌های مورد پی‌گیری برای ویرایش‌های اخیر',
 'watchlistcontains' => 'فهرست پی‌گیری‌های شما حاوی $1 {{PLURAL:$1|صفحه|صفحه}} است.',
 'iteminvalidname' => 'مشکل با مورد «$1»، نام نامعتبر است...',
+'wlnote2' => 'در زیر تغییرات اخیر وجود دارد {{PLURAL:$1|ساعت|<strong>$1</strong> ساعت‌ها}}, به عنوان $2, $3.',
 'wlshowlast' => 'نمایش آخرین $1 ساعت $2 روز $3',
 'watchlist-options' => 'گزینه‌های پی‌گیری',
 
@@ -3211,6 +3214,7 @@ $2',
 'import-error-special' => 'صفحهٔ «$1» درون‌ریزی نشد، چرا که متعلق به فضای نام نامجاز است.',
 'import-error-invalid' => 'صفحه "$1" به دلیل نامعتبر بودن نامش وارد نمی‌شود.',
 'import-error-unserialize' => 'امکان خارج کردن نسخهٔ $2 از صفحهٔ «$1» از حالت سریال‌شده وجود نداشت. گزارش شد که نسخه از مدل محتوای $3 استفاده می‌کند که به صورت $4 سریال شده‌است.',
+'import-error-bad-location' => 'بازبینی $2 با استفاده از مدل محتوای $3 نمی‌تواند در "$1" در این ویکی ذخیره شده باشد، از آنجایی که مدل در آن صفحه پشتیبانی نشده‌است.',
 'import-options-wrong' => '{{PLURAL:$2|جزئیات|جزئیات}} اشتباه: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'با توجه به ریشه صفحه عنوان نامعتبر است.',
 'import-rootpage-nosubpage' => 'فضای نام  "$1" صفحهٔ مبنا اجازهٔ زیرصفحه نمی‌دهد.',
index 4f0b5f4..367748e 100644 (file)
@@ -684,6 +684,7 @@ $1",
 'versionrequiredtext' => 'La version $1 de MediaWiki est nécessaire pour utiliser cette page. Consultez [[Special:Version|la page des versions]]',
 
 'ok' => 'Valider',
+'pagetitle' => '$1 — {{SITENAME}}',
 'retrievedfrom' => 'Récupérée de « $1 »',
 'youhavenewmessages' => '{{PLURAL:$3|Vous avez}} $1 ($2).',
 'youhavenewmessagesfromusers' => "{{PLURAL:$4|Vous avez}} $1 {{PLURAL:$3|d'un autre utilisateur|de $3 autres utilisateurs}} ($2).",
@@ -1214,6 +1215,7 @@ La dernière entrée du journal est affichée ci-dessous pour référence :",
 'template-semiprotected' => '(semi-protégé)',
 'hiddencategories' => '{{PLURAL:$1|Catégorie cachée|Catégories cachées}} dont cette page fait partie :',
 'edittools' => '<!-- Tout texte entré ici sera affiché sous les boîtes de modification ou les formulaires de téléversement de fichier. -->',
+'edittools-upload' => '—',
 'nocreatetext' => '{{SITENAME}} a restreint la possibilité de créer de nouvelles pages.
 Vous pouvez revenir en arrière et modifier une page existante, ou bien [[Special:UserLogin|vous connecter ou créer un compte]].',
 'nocreate-loggedin' => "Vous n'avez pas la permission de créer de nouvelles pages.",
@@ -1241,7 +1243,7 @@ Elle existe déjà.",
 'invalid-content-data' => 'Données du contenu non valides',
 'content-not-allowed-here' => 'Le contenu « $1 » n’est pas autorisé sur la page [[$2]]',
 'editwarning-warning' => 'Quitter cette page vous fera perdre toutes les modifications que vous avez faites.
-Si vous êtes connecté, vous pouvez désactiver cet avertissement dans la section « Modification » de vos préférences.',
+Si vous êtes connecté, vous pouvez désactiver cet avertissement dans la section « {{int:prefs-editing}} » de vos préférences.',
 'editpage-notsupportedcontentformat-title' => 'Format de contenu non pris en charge',
 'editpage-notsupportedcontentformat-text' => "Le format de contenu $1 n'est pas pris en charge par le modèle de contenu $2 .",
 
@@ -1275,6 +1277,7 @@ Il devrait y avoir moins de $2 appel{{PLURAL:$2||s}}, alors qu'il y en a mainten
 'undo-success' => 'Cette modification va être défaite. Veuillez vérifier les modifications ci-dessous, puis publier si c’est bien ce que vous voulez faire.',
 'undo-failure' => 'Cette modification ne peut pas être défaite : cela entrerait en conflit avec les modifications intermédiaires.',
 'undo-norev' => 'La modification n’a pas pu être défaite parce qu’elle est inexistante ou qu’elle a été supprimée.',
+'undo-nochange' => 'Il semble que la modification aie déjà été annulée.',
 'undo-summary' => 'Annulation des modifications $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussion]])',
 'undo-summary-username-hidden' => 'Annuler la révision $1 par un utilisateur masqué',
 
@@ -1435,6 +1438,7 @@ Assurez-vous que cette opération conservera la continuité de l'historique de l
 'mergehistory-comment' => '[[:$1]] fusionnée avec [[:$2]] : $3',
 'mergehistory-same-destination' => "Les pages d'origine et de destination ne peuvent pas être la même",
 'mergehistory-reason' => 'Motif :',
+'mergehistory-revisionrow' => '$1 ($2) $3 — $4 $5 $6',
 
 # Merge log
 'mergelog' => 'Journal des fusions',
@@ -1452,6 +1456,8 @@ Assurez-vous que cette opération conservera la continuité de l'historique de l
 'showhideselectedversions' => 'Afficher/masquer les versions sélectionnées',
 'editundo' => 'annuler',
 'diff-empty' => '(Aucune différence)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Une révision intermédiaire par le même utilisateur non affichée|$1 révisions intermédiaires par le même utilisateur non affichées}})',
+'diff-multi-otherusers' => '({{PLURAL:$1|Une révision intermédiaire|$1 révisions intermédiaires}} par {{PLURAL:$2|un autre utilisateur|$2 utilisateurs}} non {{PLURAL:$1|affichée|affichées}})',
 'diff-multi-manyusers' => "({{PLURAL:$1|Une révision intermédiaire|$1 révisions intermédiaires}} par plus {{PLURAL:$2|d'un utilisateur|de $2 utilisateurs}} {{PLURAL:$1|est masquée|sont masquées}})",
 'difference-missing-revision' => "{{PLURAL:$2|Une révision|$2 révisions}} de cette différence ($1) {{PLURAL:$2|n'a pas été trouvée|n'ont pas été trouvées}}.
 
@@ -1472,7 +1478,7 @@ Vous pouvez trouver des détails dans le [{{fullurl:{{#Special:Log}}/delete|page
 'shown-title' => 'Afficher $1 résultat{{PLURAL:$1||s}} par page',
 'viewprevnext' => 'Voir ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-exists' => "'''Il existe une page nommée « [[:$1]] » sur ce wiki.''' {{PLURAL:$2|0=|Voyez également les autres résultats de votre recherche.}}",
-'searchmenu-new' => "'''Créer la page « [[:$1|$1]] » sur ce wiki !''' {{PLURAL:$2|0=|Voyez également la page trouvée avec votre recherche.|Voyez également les résultats de votre recherche.}}",
+'searchmenu-new' => '<strong>Créer la page « [[:$1|$1]] » sur ce wiki !</strong> {{PLURAL:$2|0=|Voyez également la page trouvée avec votre recherche.|Voyez également les résultats de votre recherche.}}',
 'searchprofile-articles' => 'Pages de contenu',
 'searchprofile-project' => "Pages d'aide et de projet",
 'searchprofile-images' => 'Multimédia',
@@ -2746,6 +2752,7 @@ Il a peut-être déjà été restauré.',
 $1',
 'undelete-show-file-confirm' => 'Êtes-vous sûr de vouloir visionner une version supprimée du fichier « <nowiki>$1</nowiki> » datant du $2 à $3 ?',
 'undelete-show-file-submit' => 'Oui',
+'undelete-revision-row' => '$1 $2 ($3) $4 — $5 $6 $7 $8 $9',
 
 # Namespace form on various pages
 'namespace' => 'Espace de noms :',
@@ -3235,6 +3242,7 @@ Vous pouvez toutefois en visualiser la source.',
 'print.css' => '/* Le CSS placé ici affectera les impressions */',
 'noscript.css' => '/* Le CSS placé ici affectera les utilisateurs ayant désactivé Javascript. */',
 'group-autoconfirmed.css' => '/* Le CSS placé ici affectera les utilisateurs auto-confirmés seulement. */',
+'group-user.css' => '/* Le CSS placé ici n’affectera que les utilisateurs enregistrés. */',
 'group-bot.css' => '/* Le CSS placé ici affectera les robots seulement. */',
 'group-sysop.css' => '/* Le CSS inclus ici n’affectera que les administrateurs */',
 'group-bureaucrat.css' => '/* Le CSS inclus ici n’affectera que les bureaucrates */',
@@ -3246,6 +3254,7 @@ Vous pouvez toutefois en visualiser la source.',
 'modern.js' => '/* Tout JavaScript ici sera chargé avec les pages accédées par les utilisateurs de l’habillage Moderne uniquement */',
 'vector.js' => '/* Tout code JavaScript placé ici sera chargé pour les utilisateurs de l’habillage Vector */',
 'group-autoconfirmed.js' => '/* Le JavaScript inclus ici n’affectera que les utilisateurs auto-confirmés */',
+'group-user.js' => '/* Le JavaScript placé ici ne sera chargé que pour les utilisateurs enregistrés. */',
 'group-bot.js' => '/* Le JavaScript inclus ici n’affectera que les robots */',
 'group-sysop.js' => '/* Le JavaScript inclus ici n’affectera que les administrateurs */',
 'group-bureaucrat.js' => '/* Le JavaScript inclus ici n’affectera que les bureaucrates */',
@@ -3367,6 +3376,7 @@ $1',
 Si vous l'exécutez, votre système peut être compromis.",
 'imagemaxsize' => "Taille maximale des images :<br />''(pour les pages de description de fichier)''",
 'thumbsize' => 'Taille de la miniature :',
+'widthheight' => '$1&nbsp;×&nbsp;$2',
 'widthheightpage' => '$1 × $2, $3 page{{PLURAL:$3||s}}',
 'file-info' => 'Taille du fichier : $1, type MIME : $2',
 'file-info-size' => '$1 × $2 pixels, taille du fichier : $3, type MIME : $4',
@@ -3400,6 +3410,10 @@ Si vous l'exécutez, votre système peut être compromis.",
 'sp-newimages-showfrom' => 'Afficher les nouveaux fichiers à partir du $1 à $2',
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'video-dims' => '$1, $2&nbsp;×&nbsp;$3',
+'seconds-abbrev' => '$1&nbsp;s',
+'minutes-abbrev' => '$1&nbsp;min',
+'hours-abbrev' => '$1&nbsp;h',
 'days-abbrev' => '$1 j',
 'seconds' => '{{PLURAL:$1|$1 seconde|$1 secondes}}',
 'minutes' => '{{PLURAL:$1|$1 minute|$1 minutes}}',
@@ -3430,6 +3444,22 @@ Si vous l'exécutez, votre système peut être compromis.",
 Seules les listes d’énumération (commençant par *) sont prises en compte. Le premier lien d’une ligne doit être celui d’une mauvaise image.
 Les autres liens sur la même ligne sont considérés comme des exceptions, par exemple des pages sur lesquelles l’image peut apparaître.',
 
+# Variants for Kurdish language
+'variantname-ku-arab' => 'ku-arab',
+'variantname-ku-latn' => 'ku-latn',
+
+# Variants for Tajiki language
+'variantname-tg-cyrl' => 'tg-cyrl',
+'variantname-tg-latn' => 'tg-latn',
+
+# Variants for Inuktitut language
+'variantname-ike-cans' => 'ike-cans',
+'variantname-ike-latn' => 'ike-latn',
+
+# Variants for Tachelhit language
+'variantname-shi-tfng' => 'shi-tfng',
+'variantname-shi-latn' => 'shi-latn',
+
 # Metadata
 'metadata' => 'Métadonnées',
 'metadata-help' => "Ce fichier contient des informations supplémentaires, probablement ajoutées par l'appareil photo numérique ou le numériseur utilisé pour le créer. Si le fichier a été modifié depuis son état original, certains détails peuvent ne pas refléter entièrement l'image modifiée.",
@@ -3629,6 +3659,19 @@ Les autres liens sur la même ligne sont considérés comme des exceptions, par
 'exif-originalimageheight' => "Hauteur de l'image avant qu'elle ait été recadrée",
 'exif-originalimagewidth' => "Largeur de l'image avant qu'elle ait été recadrée",
 
+# Make & model, can be wikified in order to link to the camera and model name
+'exif-contact-value' => '$1
+
+$2
+<div class="adr">
+$3
+
+$6 $4, $5
+
+$7
+</div>
+$8',
+
 # Exif attributes
 'exif-compression-1' => 'Non compressé',
 'exif-compression-2' => 'CCITT Groupe 3 Longueur du codage Huffman modifié de dimension 1',
@@ -3983,16 +4026,27 @@ Veuillez confirmer que vous désirez réellement recréer cette page.",
 'autosumm-new' => 'Page créée avec « $1 »',
 
 # Size units
-'size-bytes' => '$1 o',
-'size-kilobytes' => '$1 Kio',
-'size-megabytes' => '$1 Mio',
-'size-gigabytes' => '$1 Gio',
-'size-terabytes' => '$1 Tio',
-'size-petabytes' => '$1 Pio',
+'size-bytes' => '$1&nbsp;o',
+'size-kilobytes' => '$1&nbsp;Kio',
+'size-megabytes' => '$1&nbsp;Mio',
+'size-gigabytes' => '$1&nbsp;Gio',
+'size-terabytes' => '$1&nbsp;Tio',
+'size-petabytes' => '$1&nbsp;Pio',
 'size-exabytes' => '$1 Eio',
-'size-zetabytes' => '$1 Zio',
+'size-zetabytes' => '$1&nbsp;Zio',
 'size-yottabytes' => '$1 Yio',
 
+# Bitrate units
+'bitrate-bits' => '$1&nbsp;bps',
+'bitrate-kilobits' => '$1&nbsp;kbps',
+'bitrate-megabits' => '$1&nbsp;Mbps',
+'bitrate-gigabits' => '$1&nbsp;Gbps',
+'bitrate-terabits' => '$1&nbsp;Tbps',
+'bitrate-petabits' => '$1&nbsp;Pbps',
+'bitrate-exabits' => '$1&nbsp;Ebps',
+'bitrate-zetabits' => '$1&nbsp;Zbps',
+'bitrate-yottabits' => '$1&nbsp;Ybps',
+
 # Live preview
 'livepreview-loading' => 'Chargement...',
 'livepreview-ready' => 'Chargement … terminé !',
index b187169..5bd1ca0 100644 (file)
@@ -583,6 +583,8 @@ Am det uunmeldin uftuslütjen, skel dü en nei paaswurd iindu.',
 'retypenew' => 'Skriiw det paaswurd noch ans weder hen:',
 'resetpass_submit' => 'Paaswurd saat an uunmelde',
 'changepassword-success' => 'Din paaswurd as feranert wurden!',
+'changepassword-throttled' => 'Dü heest tufölsis fersoocht, di uuntumeldin.
+Wees so gud an teew $1, iar dü det noch ans ferschükst.',
 'resetpass_forbidden' => 'Det paaswurd koon ei feranert wurd.',
 'resetpass-no-info' => 'Dü skel di uunmelde, am üüb det sidj tutugripen.',
 'resetpass-submit-loggedin' => 'Paaswurd feranre',
@@ -634,6 +636,8 @@ Tidjwiis paaswurd: $2',
 'changeemail-password' => 'Din {{SITENAME}} paaswurd:',
 'changeemail-submit' => 'E-mail adres feranre',
 'changeemail-cancel' => 'Ufbreeg',
+'changeemail-throttled' => 'Dü heest tufölsis fersoocht, di uuntumeldin.
+Wees so gud an teew $1, iar dü det noch ans ferschükst.',
 
 # Special:ResetTokens
 'resettokens' => 'Tokens turagsaat',
@@ -848,7 +852,7 @@ Uun't strik- an fersküüw-logbuk oner stäänt muar diartu.",
 'invalid-content-data' => 'Diar stäänt wat uun, wat diar ei hen hiart',
 'content-not-allowed-here' => '„$1“ mut ei skrewen wurd üüb sidj [[$2]]',
 'editwarning-warning' => 'Wan dü detheer sidj slotst, kön feranrangen ferleesen gung.
-Üs uunmeldet brüker könst dü detheer wäärnang bi din iinstelangen oner „Bewerke“ wechknipse.',
+Üs uunmeldet brüker könst dü detheer wäärnang bi din iinstelangen oner „{{int:prefs-editing}}“ ufstel.',
 'editpage-notsupportedcontentformat-title' => 'Detdiar formoot gongt ei.',
 'editpage-notsupportedcontentformat-text' => 'Det formoot $1 gongt ei mä det model $2.',
 
@@ -1056,6 +1060,8 @@ A nawigatjuun-links saat ales weder turag üüb di ual stant.',
 'showhideselectedversions' => 'Werjuunen wise of fersteeg',
 'editundo' => 'turagsaat',
 'diff-empty' => '(nään ferskeel)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Ian werjuun diartesken|$1 werjuunen diartesken}} faan disalew brüker {{PLURAL:$1|woort|wurd}} ei uunwiset)',
+'diff-multi-otherusers' => '({{PLURAL:$1|Ian werjuun diartesken|$1 werjuunen diartesken}} faan {{PLURAL:$2|ään öödern brüker|$2 ööder brükern}} {{PLURAL:$1|woort|wurd}} ei uunwiset)',
 'diff-multi-manyusers' => '({{PLURAL:$1|Ian werjuun diartesken|$1 werjuunen diartesken}} faan muar üs $2 {{PLURAL:$2|brüker|brükern}} wurd ei uunwiset)',
 'difference-missing-revision' => "{{PLURAL:$2|Ian werjuun|$2 werjuunen}} faan di ferskeel ($1) {{PLURAL:$2|as|san}} ei fünjen wurden.
 
@@ -1076,7 +1082,7 @@ Dü könst det uun't [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'shown-title' => 'Wise $1 {{PLURAL:$1|resultaat|resultaaten}} per sidj',
 'viewprevnext' => 'Wise ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "'''Deer as en sid nååmd \"[[:\$1]]\" önj jüdeer Wiki'''",
-'searchmenu-new' => "'''Maage det sidj „[[:$1]]“ uun detheer wiki.'''",
+'searchmenu-new' => '<strong>Maage det sidj „[[:$1]]“ uun detheer wiki!</strong> {{PLURAL:$2|0=|Luke uk bi det fünjen sidj.|Luke uk bi a fünjen sidjen.}}',
 'searchprofile-articles' => 'Artiikler',
 'searchprofile-project' => 'Halep- an Projektsidjen',
 'searchprofile-images' => 'Multimedia',
@@ -1092,6 +1098,7 @@ Dü könst det uun't [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'search-result-score' => 'Relewans: $1 %',
 'search-redirect' => '(widjerfeerd faan „$1“)',
 'search-section' => '(kirew $1)',
+'search-file-match' => '(fünjen tekst)',
 'search-suggest' => 'Mendst dü „$1“?',
 'search-interwiki-caption' => 'Saster-projekten',
 'search-interwiki-default' => '$1 resultaaten:',
@@ -2082,6 +2089,7 @@ Feranrangen faan detdiar sidj wurd üüb detdiar list fäästhäälen.",
 'watchmethod-list' => "Sidjen, diar dü uun't uug heest, am a leetst feranrangen beluke",
 'watchlistcontains' => "Dü häälst $1 {{PLURAL:$1|sidj|sidjen}} uun't uug.",
 'iteminvalidname' => 'Mä di iindrach „$1“ stemet wat ei, di nööm as ferkiard.',
+'wlnote2' => 'Diar stun a feranrangen faan a leetst {{PLURAL:$1|stünj|<strong>$1</strong> stünjen}}, üüb a stant faan $2, $3.',
 'wlshowlast' => 'Wise a feranrangen faan leetst $1 stünjen, $2 daar of $3.',
 'watchlist-options' => "Iinstelangen för't uunwisin",
 
@@ -2161,7 +2169,7 @@ Halep an muar diartu: {{canonicalurl:{{MediaWiki:Helppage}}}}',
 'delete-edit-reasonlist' => "Grünjer för't striken bewerke",
 'delete-toobig' => 'Detdiar sidj hää muar üs $1 {{PLURAL:$1|werjuun|werjuunen}} . Sok sidjen kön ei so gau stregen wurd, ööders san a servers plaat.',
 'delete-warning-toobig' => "Detdiar sidj hää muar üs $1 {{PLURAL:$1|werjuun|werjuunen}} . Det striken koon komer maage bi't dootenbeenk.",
-'deleting-backlinks-warning' => "'''Paase üüb:''' Diar ferwise noch ööder sidjen üüb det sidj, diar dü strik wel.",
+'deleting-backlinks-warning' => "'''Paase üüb:''' Diar ferwise noch ööder sidjen üüb det sidj, diar dü strik wel. Of det sidj as noch huarööders iinbünjen.",
 
 # Rollback
 'rollback' => 'Feranrangen turagsaat',
@@ -2458,7 +2466,7 @@ Luke bi't [[Special:BlockList|sperlist]] för aal jo aktuel speren.",
 'range_block_disabled' => 'Det mögelkhaid, hialer adresrümer tu sperin, as ei aktiif.',
 'ipb_expiry_invalid' => 'Didiar tidjrüm gongt ei.',
 'ipb_expiry_temp' => 'Ferbürgen brükernööm-speren skel permanent wees.',
-'ipb_hide_invalid' => 'Detdiar brükerkonto koon ei ferbürgen wurd, auer diar tuföl feranrangen uun a ferluup stun.',
+'ipb_hide_invalid' => 'Detdiar brükerkonto koon ei ferbürgen wurd, auer diar muar üs {{PLURAL:$1|ian feranrang|$1 feranrangen}} uun a ferluup stun.',
 'ipb_already_blocked' => '„$1“ as al speret',
 'ipb-needreblock' => '$1 as al speret. Wel dü a speriinstelangen feranre?',
 'ipb-otherblocks-header' => 'Ööder {{PLURAL:$1|sper|speren}}',
@@ -2619,6 +2627,7 @@ Wees so gud an beschük a sidjen [https://www.mediawiki.org/wiki/Localisation Me
 'allmessages-prefix' => 'Filter mä prefix:',
 'allmessages-language' => 'Spriak:',
 'allmessages-filter-submit' => 'Widjer',
+'allmessages-filter-translate' => 'Auersaat',
 
 # Thumbnails
 'thumbnail-more' => 'Fergratre',
@@ -2668,7 +2677,7 @@ Transwiki-import-aktjuunen wurd uun't [[Special:Log/import|Import-logbuk]] fää
 'importuploaderrortemp' => "Bi't huuchschüüren faan det importdatei as wat skiaf gingen. Diar as nian tidjwiis fertiaknis.",
 'import-parse-failure' => "Bi't importiarin faan det XML-datei as wat skiaf gingen.",
 'import-noarticle' => 'Diar as nian sidj tu importiarin bestemet wurden.',
-'import-nonewrevisions' => 'Aal jodiar werjuunen san al ans importiaret wurden.',
+'import-nonewrevisions' => 'Diar wurd nian werjuunen importiaret, auer jo eder al diar wiar of auersprüngen wurden san.',
 'xml-error-string' => '$1 uun rä $2, türn $3 (byte $4): $5',
 'import-upload' => 'XML-datein importiare',
 'import-token-mismatch' => 'Session dooten san wech. Ferschük det noch ans weder.',
@@ -2679,6 +2688,7 @@ Transwiki-import-aktjuunen wurd uun't [[Special:Log/import|Import-logbuk]] fää
 'import-error-special' => 'Det sidj „$1“ as ei importiaret wurden, auer hat tu en nöömrüm hiart, huar nian sidjen mögelk san.',
 'import-error-invalid' => 'Det sidj „$1“ as ei importiaret wurden, auer di nööm ei stemet.',
 'import-error-unserialize' => 'Det werjuun $2 faan det sidj „$1“ küd ei deserialisiaret wurd. Det werjuun woort mä det münster $3 brükt, an det as mä $4 serialisiaret.',
+'import-error-bad-location' => 'Det feranrang $2 mä model $3 koon ei üs "$1" üüb detheer wiki seekert wurd, auer detdiar model heer ei brükt wurd koon.',
 'import-options-wrong' => 'Ferkiard {{PLURAL:$2|iinstelang|iinstelangen}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Didiar sidjennööm as ferkiard.',
 'import-rootpage-nosubpage' => 'Uun di nöömrüm „$1“ jaft at nian onersidjen.',
@@ -3818,4 +3828,7 @@ Uk parser-funktjuunen liküs <code><nowiki>{{</nowiki>#language:…}}</code> an
 'expand_templates_generate_rawhtml' => 'Rä HTML uunwise',
 'expand_templates_preview' => 'Föörskau',
 
+# Unknown messages
+'createaccount-hook-aborted' => '$1',
+'uploadinvalidxml' => "Det XML uun det huuchschüürd datei küd ei ''parset'' wurd.",
 );
index ff7595f..cc30c65 100644 (file)
@@ -1914,7 +1914,7 @@ Se o problema persiste, póñase en contacto cun [[Special:ListUsers/sysop|admin
 # File backend
 'backend-fail-stream' => 'Non se puido transmitir o ficheiro "$1".',
 'backend-fail-backup' => 'Non se puido facer unha copia de seguridade do ficheiro "$1".',
-'backend-fail-notexists' => 'Non existe o ficheiro "$1".',
+'backend-fail-notexists' => 'O ficheiro "$1" non existe.',
 'backend-fail-hashes' => 'Non se puideron obter os cardinais do ficheiro por comparación.',
 'backend-fail-notsame' => 'Xa existe un ficheiro chamado "$1", con contidos diferentes.',
 'backend-fail-invalidpath' => '"$1" non é unha ruta de almacenamento válida.',
index 6f5ceac..45112ba 100644 (file)
@@ -127,6 +127,18 @@ $messages = array(
 'oct' => 'JFou',
 'nov' => 'Soun',
 'dec' => 'Noll',
+'january-date' => '$1 Jerrey Geuree',
+'february-date' => '$1 Toshiaght Arree',
+'march-date' => '$1 Mayrnt',
+'april-date' => '$1 Averil',
+'may-date' => '$1 Boaldyn',
+'june-date' => '1 Mean Souree',
+'july-date' => '$1 Jerrey Souree',
+'august-date' => '$1 Luanistyn',
+'september-date' => '$1 Mean Fouyir',
+'october-date' => '$1 Jerrey Fouyir',
+'november-date' => '$1 Sauin',
+'december-date' => '$1 Mee ny Nollick',
 
 # Categories related messages
 'pagecategories' => '{{PLURAL:$1|Ronney|Ronnaghyn}}',
@@ -198,10 +210,11 @@ $messages = array(
 'view' => 'Lhaih',
 'edit' => 'Reagh',
 'create' => 'Croo',
-'editthispage' => 'Reagh yn duillag shoh',
+'editthispage' => 'Reagh y duillag shoh',
 'create-this-page' => 'Croo yn duillag shoh',
 'delete' => 'Scryss',
 'deletethispage' => 'Scryss y duillag shoh',
+'undeletethispage' => 'Jee-scryss y duillag shoh',
 'undelete_short' => 'Jee-scryss {{PLURAL:$1|$1 caghlaa|$1 chaghlaa|$1 chaghlaa|$1 caghlaaghyn}}',
 'viewdeleted_short' => 'Jeeagh er {{PLURAL:$1|$1 caghlaa scryssit magh|$1 chaghlaa scryssit magh|$1 chaghlaa scryssit magh|$1 caghlaaghyn scryssit magh}}',
 'protect' => 'Coadee',
@@ -724,14 +737,14 @@ My bailliu eh y chiarail, bee eh ymmydit son cur gys lieh y chur dhyt er son yn
 'nchanges' => '$1 {{PLURAL:$1|caghlaa|chaghlaa|chaghlaa|caghlaaghyn}}',
 'recentchanges' => "Caghlaaghyn s'noa",
 'recentchanges-legend' => "Reihyssyn da ny caghlaaghyn s'noa",
-'recentchanges-summary' => "Shirrey ny caghlaaghyn s'noa da'n wiki er y duillag shoh.",
+'recentchanges-summary' => "Shirr ny caghlaaghyn s'noa da'n wiki er y duillag shoh.",
 'recentchanges-feed-description' => "Shirr ny caghlaaghyn s'noa er y wiki 'sy scoltey shoh.",
 'recentchanges-label-newpage' => 'Ren y reaghey shoh croo duillag noa',
 'recentchanges-label-minor' => 'She myn-reaghey eh shoh',
 'recentchanges-label-bot' => 'Ren bot y reaghey shoh',
 'rcnotefrom' => "Shoh heese ny caghlaaghyn veih '''$2''' (gys '''$1''' taishbynit).",
 'rclistfrom' => "Taishbyn ny caghlaaghyn s'noa veih $1",
-'rcshowhideminor' => '{{PLURAL:$1|$1 myn-arraghey|$1 vyn-arraghey|$1 vyn-arraghey|$1 myn-arraghyn}}',
+'rcshowhideminor' => '$1 myn-arraghyn',
 'rcshowhidebots' => '{{PLURAL:$1|$1 robot|$1 robot|$1 robot|$1 robotyn}}',
 'rcshowhideliu' => '{{PLURAL:$1|$1 ymmydeyr|$1 ymmydeyr|$1 ymmydeyr|$1 ymmydeyryn}} ta loggit stiagh',
 'rcshowhideanons' => '{{PLURAL:$1|$1 ymmydeyr|$1 ymmydeyr|$1 ymmydeyr|$1 ymmydeyryn}} neuenmyssit',
index eff679e..22b09ba 100644 (file)
@@ -23,6 +23,7 @@
  * @author Rotem Liss (March 2006 on)
  * @author Rotemliss
  * @author YaronSh
+ * @author Yona b
  * @author אור שפירא
  * @author דולב
  * @author ערן
@@ -932,6 +933,8 @@ $2',
 'retypenew' => 'חזרה על הסיסמה החדשה:',
 'resetpass_submit' => 'הגדרת הסיסמה וכניסה לחשבון',
 'changepassword-success' => 'סיסמתכם שונתה בהצלחה!',
+'changepassword-throttled' => 'ביצעתם לאחרונה ניסיונות רבים מדי להיכנס לחשבון זה.
+אנא המתינו $1 לפני שתנסו שוב.',
 'resetpass_forbidden' => 'לא ניתן לשנות סיסמאות.',
 'resetpass-no-info' => 'יש להיכנס לחשבון כדי לגשת לדף זה באופן ישיר.',
 'resetpass-submit-loggedin' => 'שינוי סיסמה',
@@ -990,6 +993,8 @@ $2
 'changeemail-password' => 'סיסמה ב{{grammar:תחילית|{{SITENAME}}}}:',
 'changeemail-submit' => 'שינוי כתובת הדוא"ל',
 'changeemail-cancel' => 'ביטול',
+'changeemail-throttled' => 'ביצעתם ניסיונות רבים מדי להיכנס לחשבון זה.
+אנא המתינו $1 לפני שתנסו שוב.',
 
 # Special:ResetTokens
 'resettokens' => 'איפוס אסימונים',
@@ -1208,7 +1213,7 @@ $2
 'invalid-content-data' => 'מידע שגוי על התוכן',
 'content-not-allowed-here' => 'תוכן מסוג "$1" אינו מותר בדף [[$2]]',
 'editwarning-warning' => 'עזיבת דף זה עשויה לגרום לאובדן כל השינויים שביצעתם.
-אם אתם מחוברים לחשבון, תוכלו לבטל אזהרה זו בחלק "עריכה" שבהעדפות שלכם.',
+אם אתם מחוברים לחשבון, תוכלו לבטל אזהרה זו בחלק "{{int:prefs-editing}}" שבהעדפות שלכם.',
 'editpage-notsupportedcontentformat-title' => 'סוג התוכן אינו נתמך',
 'editpage-notsupportedcontentformat-text' => 'תוכן מסוג $1 אינו נתמך על־ידי מודל התוכן $2.',
 
@@ -1425,6 +1430,8 @@ $1",
 'showhideselectedversions' => 'הצגת/הסתרת הגרסאות שנבחרו',
 'editundo' => 'ביטול',
 'diff-empty' => '(אין הבדלים)',
+'diff-multi-sameuser' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} ממשתמש אחד אינן מוצגות',
+'diff-multi-otherusers' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}}  {{PLURAL:$2|ממשתמש אחד|מ-$2 משתמשים}}  אינן מוצגות)',
 'diff-multi-manyusers' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} של יותר {{PLURAL:$2|ממשתמש אחד|מ־$2 משתמשים}} {{PLURAL:$1|אינה מוצגת|אינן מוצגות}})',
 'difference-missing-revision' => '{{PLURAL:$2|גרסה אחת|$2 גרסאות}} של ההבדל הזה בין שתי גרסאות ($1) {{PLURAL:$2|לא נמצאה|לא נמצאו}}.
 
@@ -1445,7 +1452,8 @@ $1",
 'shown-title' => 'הצגת {{PLURAL:$1|תוצאה אחת|$1 תוצאות}} בדף',
 'viewprevnext' => 'צפייה ב: ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "'''קיים דף בשם \"[[:\$1]]\" באתר זה.'''",
-'searchmenu-new' => "'''יצירת הדף \"[[:\$1]]\" באתר זה.'''",
+'searchmenu-new' => "<strong>'''יצירת הדף \"[[:\$1]]\" באתר זה.'''</strong> 
+{{PLURAL:\$2|0=|ראו גם את הדף שנמצא בחיפוש שלכם.|ראו גם את תוצאות החיפוש שלכם.}}",
 'searchprofile-articles' => 'דפי תוכן',
 'searchprofile-project' => 'עזרה ודפי המיזם',
 'searchprofile-images' => 'מולטימדיה',
@@ -2491,6 +2499,7 @@ $1',
 'watchmethod-list' => 'בודק את העריכות האחרונות בדפים שברשימת המעקב',
 'watchlistcontains' => 'רשימת המעקב כוללת {{PLURAL:$1|דף אחד|$1 דפים}}.',
 'iteminvalidname' => 'בעיה עם $1, שם שגוי…',
+'wlnote2' => 'להלן השינויים האחרונים ב{{PLURAL:$1|שעה האחרונה|-<strong> $1 </strong> שעות האחרונות}}, מ-$2, $3.',
 'wlshowlast' => '(הצגת $1 שעות אחרונות | $2 ימים אחרונים | $3)',
 'watchlist-options' => 'אפשרויות ברשימת המעקב',
 
@@ -3049,6 +3058,7 @@ $1',
 'allmessages-prefix' => 'סינון לפי קידומת:',
 'allmessages-language' => 'שפה:',
 'allmessages-filter-submit' => 'הצגה',
+'allmessages-filter-translate' => 'תרגום',
 
 # Thumbnails
 'thumbnail-more' => 'הגדלה',
index be6aa23..3753680 100644 (file)
@@ -355,12 +355,12 @@ $messages = array(
 'category-empty' => "''Þessi flokkur inniheldur engar síður eða margmiðlunarefni.''",
 'hidden-categories' => '{{PLURAL:$1|Falinn flokkur|Faldir flokkar}}',
 'hidden-category-category' => 'Faldir flokkar',
-'category-subcat-count' => '{{PLURAL:$2|Þessi flokkur hefur einungis eftirfarandi undirflokk.|Þessi flokkur hefur eftirfarandi {{PLURAL:$1|undirflokk|$1 undirflokka}}, af alls $2.}}',
-'category-subcat-count-limited' => 'Þessi flokkur hefur eftirfarandi {{PLURAL:$1|undirflokk|$1 undirflokka}}.',
+'category-subcat-count' => 'Þessi flokkur hefur eftirfarandi $1 {{PLURAL:$1|undirflokk|undirflokka}}, af alls $2.',
+'category-subcat-count-limited' => 'Þessi flokkur hefur eftirfarandi $1 {{PLURAL:$1|undirflokk|undirflokka}}.',
 'category-article-count' => 'Þessi flokkur inniheldur {{PLURAL:$1|$1 síðu|$1 síður}}, af alls {{PLURAL:$2|$2}}.',
-'category-article-count-limited' => 'Eftirfarandi {{PLURAL:$1|síða er|$1 síður eru}} í þessum flokki.',
+'category-article-count-limited' => 'Eftirfarandi $1 {{PLURAL:$1|síða er|síður eru}} í þessum flokki.',
 'category-file-count' => 'Þessi flokkur inniheldur {{PLURAL:$1|$1 skrá|$1 skrár}}, af alls {{PLURAL:$2|$2}}.',
-'category-file-count-limited' => 'Eftirfarandi {{PLURAL:$1|skrá er|$1 skrár eru}} í þessum flokki.',
+'category-file-count-limited' => 'Eftirfarandi $1 {{PLURAL:$1|skrá er|skrár eru}} í þessum flokki.',
 'listingcontinuesabbrev' => 'frh.',
 'index-category' => 'Raðaðar skrár',
 'noindex-category' => 'Óraðaðar skrár',
@@ -428,7 +428,7 @@ $messages = array(
 'deletethispage' => 'Eyða þessari síðu',
 'undeletethispage' => 'Endurvekja þessa síðu',
 'undelete_short' => 'Endurvekja {{PLURAL:$1|$1 breytingu|$1 breytingar}}',
-'viewdeleted_short' => 'Skoða {{PLURAL:$1|eina eydda breytingu|$1 eyddar breytingar}}',
+'viewdeleted_short' => 'Skoða $1 {{PLURAL:$1|eydda breytingu|eyddar breytingar}}',
 'protect' => 'Vernda',
 'protect_change' => 'breyta',
 'protectthispage' => 'Vernda þessa síðu',
@@ -456,7 +456,7 @@ $messages = array(
 'redirectedfrom' => '(Tilvísað frá $1)',
 'redirectpagesub' => 'Tilvísunarsíða',
 'lastmodifiedat' => 'Þessari síðu var síðast breytt $1 klukkan $2.',
-'viewcount' => 'Þessi síða hefur verið skoðuð {{PLURAL:$1|einu sinni|$1 sinnum}}.',
+'viewcount' => 'Þessi síða hefur verið skoðuð $1 {{PLURAL:$1|sinni|sinnum}}.',
 'protectedpage' => 'Vernduð síða',
 'jumpto' => 'Stökkva á:',
 'jumptonavigation' => 'flakk',
@@ -736,8 +736,8 @@ halda áfram að nota gamla lykilorðið.',
 Vinsamlegast skráðu þig inn á ný þegar þú hefur móttekið það.',
 'blocked-mailpassword' => 'Þér er ekki heimilt að gera breytingar frá þessu netfangi og  því getur þú ekki fengið nýtt lykilorð í pósti.  Þetta er gert til þess að koma í veg fyrir skemmdarverk.',
 'eauthentsent' => 'Staðfestingarpóstur hefur verið sendur á uppgefið netfang. Þú verður að fylgja leiðbeiningunum í póstinum til þess að virkja netfangið og staðfesta að það sé örugglega þitt.',
-'throttled-mailpassword' => 'Tölvupóstur til að endursetja lykilorðið hefur þegar verið sent, innan við {{PLURAL:$1|síðasta klukkutímans|$1 síðustu klukkutímanna}}.
-Til að koma í veg fyrir misnotkun, er aðeins einn tölvupóstur sendur {{PLURAL:$1|hvern klukkutíma|hverja $1 klukkutíma}}.',
+'throttled-mailpassword' => 'Tölvupóstur til að endursetja lykilorðið hefur þegar verið sent, innan við $1 {{PLURAL:$1|síðasta klukkutímans|síðustu klukkutímanna}}.
+Til að koma í veg fyrir misnotkun, er aðeins einn tölvupóstur sendur {{PLURAL:$1|hvern $1 klukkutíma|hverja $1 klukkutíma}}.',
 'mailerror' => 'Upp kom villa við sendingu tölvupósts: $1',
 'acct_creation_throttle_hit' => 'Því miður, hafa verið búnir til {{PLURAL:$1|$1 nýr aðgangur|$1 nýjir aðgangar}} í dag sem er hámarksfjöldi nýskráninga á einum degi.
 Þú getur því miður ekki búið til nýjan aðgang frá þessari IP-tölu að svo stöddu.',
@@ -1019,7 +1019,7 @@ Verndunarskrá síðunnar er gefin fyrir neðan til tilvísunar.",
 'templatesusedsection' => 'Snið {{PLURAL:$1|notað|notuð}} í þessum hluta:',
 'template-protected' => '(vernduð)',
 'template-semiprotected' => '(hálfvernduð)',
-'hiddencategories' => 'Þessi síða er meðlimur í {{PLURAL:$1|1 földum flokki|$1 földum flokkum}}:',
+'hiddencategories' => 'Þessi síða er meðlimur í $1 {{PLURAL:$1|földum flokki|földum flokkum}}:',
 'nocreatetext' => '{{SITENAME}} hefur takmarkað eiginleikann að gera nýjar síður.
 Þú getur farið til baka og breytt núverandi síðum, eða [[Special:UserLogin|skráð þið inn eða búið til aðgang]].',
 'nocreate-loggedin' => 'Þú hefur ekki leyfi til að skapa nýjar síður.',
@@ -1939,7 +1939,7 @@ Eftirfarandi listi sýnir {{PLURAL:$1|fyrsta myndatengilinn|fyrstu $1 myndatengl
 'nolinkstoimage' => 'Engar síður tengja í þessa skrá.',
 'morelinkstoimage' => 'Skoða [[Special:WhatLinksHere/$1|fleiri myndatengla]] á þessa skrá.',
 'linkstoimage-redirect' => '$1 (tilvísun) $2',
-'duplicatesoffile' => 'Eftirfarandi {{PLURAL:$1|skrá er afrit|$1 skrár eru afrit}} af þessari skrá ([[Special:FileDuplicateSearch/$2|Frekari upplýsingar]]):',
+'duplicatesoffile' => 'Eftirfarandi $2 {{PLURAL:$1|skrá er afrit|skrár eru afrit}} af þessari skrá ([[Special:FileDuplicateSearch/$2|Frekari upplýsingar]]):',
 'sharedupload' => 'Skrá þessi er af $1, og deilt meðal annarra verkefna og nýtist því þar.',
 'sharedupload-desc-there' => 'Skrá þessi er af $1, og deilt meðal annarra verkefna og nýtist því þar.
 Gjörðu svo vel og sjáðu [$2 skráarsíðuna þar] fyrir fleiri upplýsingar.',
@@ -2038,7 +2038,7 @@ Leitarstrengurinn á að vera á þessu formi: efnistag/myndasnið, t.d. <code>i
 'statistics-views-peredit' => 'Uppflettingar á hverja breytingu (meðaltal)',
 'statistics-users' => 'Skráðir  [[Special:ListUsers|notendur]]',
 'statistics-users-active' => 'Virkir notendur',
-'statistics-users-active-desc' => 'Notendur sem hafa framkvæmt aðgerð {{PLURAL:$1|síðastliðin dag|síðastliðna $1 daga}}',
+'statistics-users-active-desc' => 'Notendur sem hafa framkvæmt aðgerð {{PLURAL:$1|síðusta $1 dag|síðustu $1 daga}}',
 'statistics-mostpopular' => 'Mest skoðuðu síður',
 
 'pageswithprop' => 'Síður með eiginleika',
@@ -2133,7 +2133,7 @@ Vinsamlegast athugið að aðrar vefsíður gætu tengt beint í skrár héðan,
 'notargettext' => 'Villa: Engin síða eða notandi tilgreind til að nota þennan möguleika á.',
 'nopagetitle' => 'Síðan er ekki til',
 'nopagetext' => 'Síðan sem á að færa frá er ekki til.',
-'pager-newer-n' => '{{PLURAL:$1|nýrri 1|nýrri $1}}',
+'pager-newer-n' => '{{PLURAL:$1|nýrri}} $1',
 'pager-older-n' => '{{PLURAL:$1|1 eldri|$1 eldri}}',
 'suppress' => 'Yfirsýn',
 'querypage-disabled' => 'Þessi kerfisíða er óvirk til að minnka ekki afköst vefþjónsins.',
@@ -2210,7 +2210,7 @@ Leitin þarf að minnsta kosti að innihalda rótarlén, eins og "*.org"
 # Special:ActiveUsers
 'activeusers' => 'Virkir notendur',
 'activeusers-intro' => 'Þetta er listi yfir notendur sem hafa verið virkir {{PLURAL:$1|síðasta|síðustu}} $1 {{PLURAL:$1|dag|daga}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|aðgerð|aðgerðir}} á {{PLURAL:$3|síðastliðnum degi|síðustu $3 dögum}}',
+'activeusers-count' => '$1 {{PLURAL:$1|aðgerð|aðgerðir}} á {{PLURAL:$3|síðasta $3 degi|síðustu $3 dögum}}',
 'activeusers-from' => 'Sýna notendur sem byrja á:',
 'activeusers-hidebots' => 'Fela vélmenni',
 'activeusers-hidesysops' => 'Fela möppudýr',
@@ -2485,7 +2485,7 @@ Núverandi staða síðunnar er '''$1''':",
 'undeletepage' => 'Skoða og endurvekja eyddar síður',
 'undeletepagetitle' => "'''Eftirfarandi er samansafn af eyddum breytingum á [[:$1|$1]]'''.",
 'viewdeletedpage' => 'Skoða eyddar síður',
-'undeletepagetext' => 'Eftirfarandi {{PLURAL:$1|síðu hefur verið eytt en hún er þó enn í gagnagrunninum og getur verið endurvakin|$1 síðum hefur verið eytt en eru þó enn í gagnagrunninum og geta verið endurvaknar}}.
+'undeletepagetext' => 'Eftirfarandi $1 {{PLURAL:$1|síðu hefur verið eytt en hún er þó enn í gagnagrunninum og getur verið endurvakin|síðum hefur verið eytt en eru þó enn í gagnagrunninum og geta verið endurvaknar}}.
 Gagnagrunnurinn kann að vera tæmdur reglulega.',
 'undelete-fieldset-title' => 'Endurvekja breytingar',
 'undeleteextrahelp' => "Til þess að endurvekja alla breytingarskrá síðunnar, skildu öll box eftir óhökuð og ýttu á '''''{{int:undeletebtn}}'''''.
@@ -2784,7 +2784,7 @@ Vinsamlegast veldu annan titil.',
 'movelogpage' => 'Flutningaskrá',
 'movelogpagetext' => 'Þetta er listi yfir síður sem nýlega hafa verið færðar.',
 'movesubpage' => '{{PLURAL:$1|Undirsíða|Undirsíður}}',
-'movesubpagetext' => 'Þessi síða hefur {{PLURAL:$1|eina undirsíðu|$1 undirsíður}} sem {{PLURAL:$1|er sýnd|eru sýndar}} hér fyrir neðan.',
+'movesubpagetext' => 'Þessi síða hefur $1 {{PLURAL:$1|undirsíðu|undirsíður}} sem {{PLURAL:$1|er sýnd|eru sýndar}} hér fyrir neðan.',
 'movenosubpage' => 'Þessi síða hefur engar undirsíður.',
 'movereason' => 'Ástæða:',
 'revertmove' => 'taka til baka',
@@ -3145,7 +3145,7 @@ Vinsamlegast reyndu aftur.',
 'file-info-gif-looped' => 'síendurtekin hreyfimynd',
 'file-info-gif-frames' => '$1 {{PLURAL:$1|rammi|rammar}}',
 'file-info-png-looped' => 'síendurtekin hreyfimynd',
-'file-info-png-repeat' => 'spilað {{PLURAL:$1|einu sinni|$1 sinnum}}',
+'file-info-png-repeat' => 'spilað $1 {{PLURAL:$1|sinni|sinnum}}',
 'file-info-png-frames' => '$1 {{PLURAL:$1|rammi|rammar}}',
 'file-no-thumb-animation' => "'''Athugið: Vegna tæknilegra takmarkanna birtast smámyndir af þessari skrá aðeins sem kyrrmyndir.'''",
 'file-no-thumb-animation-gif' => "'''Athugið:Vegna tæknilegra takmarkanna munu smámyndir af GIF-myndum í hárri upplausn eins og þessari ekki birtast sem hreyfimyndir.'''",
@@ -3163,10 +3163,10 @@ Vinsamlegast reyndu aftur.',
 'sp-newimages-showfrom' => 'Leita af nýjum skráum frá $2, $1',
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
-'seconds' => '{{PLURAL:$1|einni sekúndu|$1 sekúndum}}',
-'minutes' => '{{PLURAL:$1|einni mínútu|$1 mínútum}}',
-'hours' => '{{PLURAL:$1|einum klukkutíma|$1 klukkutímum}}',
-'days' => '{{PLURAL:$1|einum degi|$1 dögum}}',
+'seconds' => '$1 {{PLURAL:$1|sekúndu|sekúndum}}',
+'minutes' => '$1 {{PLURAL:$1|mínútu|mínútum}}',
+'hours' => '$1 {{PLURAL:$1|klukkutíma|klukkutímum}}',
+'days' => '$1 {{PLURAL:$1|degi|dögum}}',
 'weeks' => '{{PLURAL:$1|$1 vika|$1 vikur}}',
 'months' => '{{PLURAL:$1|$1 mánuði|$1 mánuðum}}',
 'years' => '{{PLURAL:$1|$1 ári|$1 árum}}',
@@ -3914,7 +3914,7 @@ Ef ekki, þá getur þú notað einfalt eyðublað hér fyrir neðan. Athugasemd
 'api-error-badaccess-groups' => 'Þú hefur ekki leyfi til að hlaða inn skrám.',
 'api-error-badtoken' => 'Innri villa: Skemmdur tóki.',
 'api-error-copyuploaddisabled' => 'Ekki er hægt að hlaða upp með vefslóð á þessum vefþjón.',
-'api-error-duplicate' => 'Það {{PLURAL:$1|er [$2 önnur skrá]|eru[$2 aðrar skrár]}} þegar til á vefsvæðinu sem hafa sama innihald.',
+'api-error-duplicate' => 'Það {{PLURAL:$1|er [$2 önnur skrá]|eru [$2 aðrar skrár]}} þegar til á vefsvæðinu sem hafa sama innihald.',
 'api-error-duplicate-archive' => 'Það {{PLURAL:$1|var [$2 önnur skrá]|voru [$2 aðrar skrár]}} þegar á síðunni með sama innihald, en {{PLURAL:$1|henni|þeim}} var eytt.',
 'api-error-duplicate-archive-popup-title' => 'Eins {{PLURAL:$1|skrá|skrár}} sem {{PLURAL:$1|hefur|hafa}} þegar verið eytt.',
 'api-error-duplicate-popup-title' => '{{PLURAL:$1|Afrituð skrá|Afritaðar skrár}}',
index 2a0041d..e2710fa 100644 (file)
@@ -1110,7 +1110,7 @@ Esiste già.',
 'invalid-content-data' => 'Dati contenuti non validi',
 'content-not-allowed-here' => 'Contenuto in "$1" non consentito nella pagine [[$2]]',
 'editwarning-warning' => 'Lasciare questa pagina potrebbe causare la perdita di tutte le modifiche fatte.
-Se hai effettuato l\'accesso, puoi disattivare questo avviso nella sezione "Casella di modifica" delle tue preferenze.',
+Se hai effettuato l\'accesso, puoi disattivare questo avviso nella sezione "{{int:prefs-editing}}" delle tue preferenze.',
 'editpage-notsupportedcontentformat-title' => 'Formato contenuto non supportato',
 'editpage-notsupportedcontentformat-text' => 'Il formato del contenuto $1 non è supportato dal modello di contenuto $2.',
 
@@ -1146,6 +1146,7 @@ Alcuni template non verranno inclusi.",
 Controlla 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.',
 'undo-norev' => 'La modifica non può essere annullata perché non esiste o è stata cancellata.',
+'undo-nochange' => 'Sembra che la modifica sia già stata annullata.',
 'undo-summary' => 'Annullata la modifica $1 di [[Special:Contributions/$2|$2]] ([[User talk:$2|discussione]])',
 'undo-summary-username-hidden' => 'Annullata la modifica $1 di un utente nascosto',
 
@@ -1320,9 +1321,9 @@ Vedi l'[[Special:BlockList|elenco dei blocchi]] per l'elenco dei bandi e dei blo
 'showhideselectedversions' => 'Mostra/nascondi versioni selezionate',
 'editundo' => 'annulla',
 'diff-empty' => '(Nessuna differenza)',
-'diff-multi-sameuser' => '({{PLURAL:$1|Una revisione intermedia|$1 revisioni intermedie}} di uno stesso utente non sono mostrate )',
-'diff-multi-otherusers' => '({{PLURAL:$1|Una revisione intermedia|$1 revisioni intermedie}} di {{PLURAL:$2|un altro utente|$2 utenti}} non mostrate)',
-'diff-multi-manyusers' => '({{PLURAL:$1|Una revisione intermedia|$1 revisioni intermedie}} di oltre $2 {{PLURAL:$2|utente|utenti}} non {{PLURAL:$1|mostrata|mostrate}})',
+'diff-multi-sameuser' => '({{PLURAL:$1|Una versione intermedia|$1 versioni intermedie}} di uno stesso utente non sono mostrate )',
+'diff-multi-otherusers' => '({{PLURAL:$1|Una versione intermedia|$1 versioni intermedie}} di {{PLURAL:$2|un altro utente|$2 utenti}} non mostrate)',
+'diff-multi-manyusers' => '({{PLURAL:$1|Una versione intermedia|$1 versioni intermedie}} di oltre $2 {{PLURAL:$2|utente|utenti}} non {{PLURAL:$1|mostrata|mostrate}})',
 'difference-missing-revision' => '{{PLURAL:$2|Una versione|$2 versioni}} di questa differenza ($1) {{PLURAL:$2|non è stata trovata|non sono state trovate}}.
 
 Questo si verifica solitamente seguendo un collegamento obsoleto di un diff a una pagina cancellata.
index dee5759..ee9eb39 100644 (file)
@@ -1235,7 +1235,7 @@ $1または他の[[{{MediaWiki:Grouppage-sysop}}|管理者]]にこのブロッ
 'invalid-content-data' => '本文データが無効です',
 'content-not-allowed-here' => 'ページ [[$2]] では、「$1」コンテンツは許可されていません',
 'editwarning-warning' => 'このページを離れると、あなたが行なった変更がすべて失われてしまうかもしれません。
-ログインしている場合、個人設定の「編集」タブでこの警告を表示しないようにすることができます。',
+ログインしている場合、個人設定の「{{int:prefs-editing}}」タブでこの警告を表示しないようにすることができます。',
 'editpage-notsupportedcontentformat-title' => '対応していないコンテンツ形式',
 'editpage-notsupportedcontentformat-text' => 'コンテンツ モデル $2 は、コンテンツ形式 $1 に対応していません。',
 
index ad773a0..0359aad 100644 (file)
@@ -1193,7 +1193,7 @@ Tı şikina sewiya sevekiyaena na pele bıvurnê, hema yê nae sevekiyaena qedem
 'contributions-title' => '$1 de iştırakê karberi',
 'mycontris' => 'İştıraqi',
 'contribsub2' => 'Serba $1 ($2)',
-'uctop' => '(ser)',
+'uctop' => '(rocane)',
 'month' => 'Asme ra (u ravêr):',
 'year' => 'Serre ra (u ravêr):',
 
index 03b8683..e3c08bc 100644 (file)
@@ -1138,7 +1138,7 @@ IP-мекенжайыңыз бұл беттің түзету тарихында
 'edit-gone-missing' => 'Бетті жаңарту мүмкін емес.
 Мүмкін, бұл бет жойылған.',
 'edit-conflict' => 'Өңдемелер қақтығысы.',
-'postedit-confirmation' => 'Сіздің өңдемеңіз сақталды.',
+'postedit-confirmation' => 'Өңдемеңіз сақталды.',
 'edit-already-exists' => 'Жаңа бет жасау мүмкін емес.
 Ол әлдеқашан бар.',
 'defaultmessagetext' => 'Әдепкі мәтіні',
@@ -1303,6 +1303,11 @@ $1",
 'showhideselectedversions' => 'Бөлектенген нұсқаларды көрсет/жасыр',
 'editundo' => 'жоққа шығару',
 'diff-empty' => '(айырмашылығы жоқ)',
+'difference-missing-revision' => 'Бұл ($1) {{PLURAL:$2|нұсқа|$2 нұсқалар}} айырмашылығы табылмады.
+
+
+Бұл әлте жойылған беттің нұсқалар айырмашылығының сілтемесі.
+Егжей-тегжейін [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} жою журналынан] таба аласыз.',
 
 # Search results
 'searchresults' => 'Іздеу нәтижелері',
@@ -1839,6 +1844,7 @@ URL дұрыс екендігін және торап істеп тұрғаны
 'listfiles_size' => 'Өлшемі',
 'listfiles_description' => 'Сипаттамасы',
 'listfiles_count' => 'Нұсқалары',
+'listfiles-show-all' => 'Суреттердің ескі нұсқаларын да қамту',
 'listfiles-latestversion' => 'Соңғы нұсқасы',
 'listfiles-latestversion-yes' => 'Иә',
 'listfiles-latestversion-no' => 'Жоқ',
index d75b1d0..eb17238 100644 (file)
@@ -1218,7 +1218,7 @@ IP 주소는 여러 사용자가 공유할 수 있습니다.
 'invalid-content-data' => '잘못된 내용 데이터입니다',
 'content-not-allowed-here' => '"$1" 내용은 [[$2]] 문서예 허용하지 않습니다',
 'editwarning-warning' => '이 페이지에서 벗어나면 저장하지 않은 바뀜이 모두 사라집니다.
-로그인을 했다면, 환경 설정의 "편집 상자"에서 이 경고를 띄우지 않도록 설정할 수 있습니다.',
+로그인을 했다면, 환경 설정의 "{{int:편집 상자}}"에서 이 경고를 띄우지 않도록 설정할 수 있습니다.',
 'editpage-notsupportedcontentformat-title' => '지원하지 않는 컨텐츠 형식',
 'editpage-notsupportedcontentformat-text' => '컨텐츠 모델 $2 에서는 컨텐츠형식 $1을 지원하지 않습니다.',
 
@@ -1436,6 +1436,8 @@ $1",
 'showhideselectedversions' => '선택한 판을 보이기/숨기기',
 'editundo' => '편집 취소',
 'diff-empty' => '(차이 없음)',
+'diff-multi-sameuser' => '(같은 사용자에 의한 {{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|없습니다}}.
 
@@ -1456,7 +1458,8 @@ $1",
 'shown-title' => '쪽마다 {{PLURAL:$1|결과}} $1개씩 보기',
 'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) 보기',
 'searchmenu-exists' => "'''이 위키에 \"[[:\$1]]\"의 이름을 가진 문서가 있습니다.'''",
-'searchmenu-new' => "'''이 위키에 \"[[:\$1]]\" 문서를 만드세요!'''",
+'searchmenu-new' => '<strong>이 위키에 "[[:$1]]" 문서를 만드세요!</strong>
+{{PLURAL:$2|0=|검색으로 찾은 문서들을 참조하세요.}}',
 'searchprofile-articles' => '본문',
 'searchprofile-project' => '도움말 및 프로젝트 문서',
 'searchprofile-images' => '멀티미디어',
@@ -3136,7 +3139,7 @@ $2',
 임시 폴더가 존재하지 않습니다.',
 'import-parse-failure' => 'XML 문서 분석 실패',
 'import-noarticle' => '가져올 문서가 없습니다!',
-'import-nonewrevisions' => '이전에 이미 모든 판을 가져왔습니다.',
+'import-nonewrevisions' => '가져온 판 없음(모든 판이 이미 존재하거나 오류로 인해 건너뛰었을 수도 있습니다.)',
 'xml-error-string' => '$3단 $2줄 (바이트 $4)에서 $1: $5',
 'import-upload' => 'XML 데이터 올리기',
 'import-token-mismatch' => '세션 데이터가 손실되었습니다.
@@ -3148,6 +3151,7 @@ $2',
 'import-error-special' => '"$1" 문서는 특수 문서에 속해 있기 때문에 가져오지 않습니다.',
 'import-error-invalid' => '"$1" 문서는 제목이 잘못되었기 때문에 가져오지 않습니다.',
 'import-error-unserialize' => '"$1" 문서의 $2 판이 일렬적이지 않습니다. $3 내용 모델을 사용하여 $4 형식으로 일렬화되도록 판을 보고했습니다.',
+'import-error-bad-location' => '$3 내용 모델을 사용하는 $2 판을 이 위키의 "$1"에 저장할 수 없습니다. 모델을 문서에서 지원하지 않습니다.',
 'import-options-wrong' => '잘못된 {{PLURAL:$2|선택 사항}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => '주어진 루트 문서는 잘못된 제목입니다.',
 'import-rootpage-nosubpage' => '루트 문서의 "$1" 이름공간은 하위 문서를 허용하지 않습니다.',
@@ -4350,5 +4354,6 @@ $5
 'expand_templates_preview' => '미리 보기',
 
 # Unknown messages
+'createaccount-hook-aborted' => '$1',
 'uploadinvalidxml' => '업로드된 파일의 XML의 구문을 분석할 수 없습니다.',
 );
index 63edf80..6bb6baf 100644 (file)
@@ -380,7 +380,7 @@ $messages = array(
 'undelete_short' => 'Traer atrás $1 {{PLURAL:$1|trocamientos|trocamientos}}',
 'viewdeleted_short' => 'Ver {{PLURAL:$1|un trocamiento efassado|$1 trocamientos efassados}}',
 'protect' => 'Guadrar',
-'protect_change' => 'trocar el guardadijo',
+'protect_change' => 'trocar',
 'protectthispage' => 'Guardar esta hoja',
 'unprotect' => 'Trocar guardadijo',
 'unprotectthispage' => 'Trocar el guardadijo desta hoja',
@@ -791,7 +791,7 @@ Leyenda: (act) = diferencias con la versión actual,
 'revdelete-radio-set' => 'Eskondido',
 'revdelete-radio-unset' => 'Visible',
 'revdelete-log' => 'Razon:',
-'revdel-restore' => 'troca la vizibilitá',
+'revdel-restore' => 'trocar la vizibilitá',
 'pagehist' => 'La storia de la hoja',
 'revdelete-otherreason' => 'Otro razon/razon adisiyonal',
 'revdelete-reasonotherlist' => 'Otra razón',
@@ -833,7 +833,7 @@ Leyenda: (act) = diferencias con la versión actual,
 'searchprofile-advanced-tooltip' => 'Buxcar en espacios de nombres partikolares',
 'search-result-size' => '$1 ({{PLURAL:$2|1 biervo|$2 biervos}})',
 'search-result-category-size' => '{{PLURAL:$1|1 miembro|$1 miembros}} ({{PLURAL:$2|1 basho-kateggoria|$2 basho-kateggoria}}, {{PLURAL:$3|1 dossia|$3 dossias}})',
-'search-redirect' => '(direksión desde $1)',
+'search-redirect' => '(redireksión de la hoja $1)',
 'search-section' => '(kapítolo $1)',
 'search-suggest' => 'Quijites dezir: $1',
 'search-interwiki-caption' => 'Proyectos hermanos',
@@ -983,8 +983,8 @@ Leyenda: (act) = diferencias con la versión actual,
 'recentchangeslinked-feed' => 'Trocamientos conectados',
 'recentchangeslinked-toolbox' => 'Trocamientos atados',
 'recentchangeslinked-title' => 'Los trocamientos relacionados con "$1"',
-'recentchangeslinked-summary' => "Esto es la lista de los trocamientos dalcavo de las hojas que relatan a una hoja particòlar (o de los miembros de la kategoría particòlar).
-Las hojas en tu [[Special:Watchlist|lista de akavidamiento]] son '''reforçadas'''.",
+'recentchangeslinked-summary' => "Esto es una lista de trocamientos dalcavo en las hojas atadas de una hoja partikolara (u en los miembros de una kategoría partikolara).
+Las hojas en tu [[Special:Watchlist|lista de acavidamiento]] son '''reforçadas'''.",
 'recentchangeslinked-page' => 'Nombre de la hoja',
 'recentchangeslinked-to' => 'Amostra los trocamientos freskos en lugar de la hoja indicada',
 
@@ -1035,7 +1035,7 @@ Las hojas en tu [[Special:Watchlist|lista de akavidamiento]] son '''reforçadas'
 'filehist-filesize' => 'El boy de la dosya',
 'filehist-comment' => 'Comentario',
 'filehist-missing' => 'No se topa el archivo',
-'imagelinks' => 'El uso del dosya',
+'imagelinks' => 'Usos de la dosya',
 'linkstoimage' => '{{PLURAL:$1|La hoja venidera da link|Las hojas venideras dan link}} a esta dosya:',
 'nolinkstoimage' => 'No ay hojas con atamientos a esta dosya.',
 'sharedupload' => 'Este arxivo es de $1 i puede ser usado por otros proyectos.',
@@ -1385,7 +1385,7 @@ Puedes ver su manadero',
 'tooltip-ca-protect' => 'Guardar esta hoja',
 'tooltip-ca-delete' => 'Efassar esta hoja',
 'tooltip-ca-move' => 'Taxirea (renombra) esta hoja',
-'tooltip-ca-watch' => 'Ajustar esta hoja a tu lista de akavidamientos',
+'tooltip-ca-watch' => 'Ajusta esta hoja a tu lista de acavidamientos',
 'tooltip-ca-unwatch' => 'Quita esta hoja de tu lista de escojidos',
 'tooltip-search' => 'Buxca en {{SITENAME}}',
 'tooltip-search-go' => 'Ir a la hoja con este nombre egzakto, si egziste.',
@@ -1399,9 +1399,9 @@ Puedes ver su manadero',
 'tooltip-n-randompage' => 'Carga una hoja por azardo',
 'tooltip-n-help' => 'Ambézate y topa ayudo',
 'tooltip-t-whatlinkshere' => 'Una lista de todas las hojas del viki que tienen atamientos a esta hoja',
-'tooltip-t-recentchangeslinked' => 'Los trocamientos dalcavo de las hojas atadas a la ésta',
+'tooltip-t-recentchangeslinked' => 'Los trocamientos dalcavo en las hojas atadas a la ésta',
 'tooltip-feed-rss' => 'Sindicación RSS de esta hoja',
-'tooltip-feed-atom' => "Fuente de Atom d'esta hoja",
+'tooltip-feed-atom' => 'Canal Atomo parâ esta hoja',
 'tooltip-t-contributions' => 'Ver la lista de ajustamientos de este usuario',
 'tooltip-t-emailuser' => 'A este usuario, mándale una letra electrόnica (ímey)',
 'tooltip-t-upload' => 'Suve dosyas',
@@ -1423,7 +1423,7 @@ Puedes ver su manadero',
 'tooltip-watch' => 'Ajusta esta hoja a tu lista de escojidas',
 'tooltip-rollback' => '«Hazer aboltar» haze aboltar todos los trocamientos del usador dalcavo, sólo en klikando una vez.',
 'tooltip-undo' => '«Des-hazer» abolta este trocamiento y lo avre en el modo de previsteo. Permete ajustar una razón en el somario.',
-'tooltip-summary' => 'Entrar un somaryo kurto',
+'tooltip-summary' => 'Entrar un somario curto',
 
 # Attribution
 'anonymous' => '{{PLURAL:$1|Uzuario anonimo|Uzuarios anonimos}} de {{SITENAME}}',
index 22c3d92..9fd9fa4 100644 (file)
@@ -1020,7 +1020,7 @@ Si gouf anscheinend geläscht.",
 'invalid-content-data' => 'Donnéeë vum Inhalt sinn net valabel',
 'content-not-allowed-here' => '"$1"-Inhalt ass op der Säit [[$2]] net erlaabt',
 'editwarning-warning' => 'Wann Dir dës Säit verloosst kann dat dozou féieren datt Dir all Ännerungen, déi Dir gemaach hutt, verléiert.
-Wann Dir ageloggt sidd, kënnt Dir dës Warnung an der Sektioun "Änneren" vun Ären Astellungen ausschalten.',
+Wann Dir ageloggt sidd, kënnt Dir dës Warnung an der Sektioun "{{int:prefs-editing}}" vun Ären Astellungen ausschalten.',
 'editpage-notsupportedcontentformat-title' => 'Format vum Inhalt gëtt net ënnerstëtzt',
 'editpage-notsupportedcontentformat-text' => 'De Format vum Inhalt $1 gëtt net vum Modell vum Inhalt $2 ënnerstëtzt.',
 
@@ -1049,6 +1049,7 @@ Et däerfen net méi wéi $2 {{PLURAL:$2|Ufro|Ufroe}} sinn, aktuell {{PLURAL:$2|
 'undo-success' => "D'Ännerung gëtt réckgängeg gemaach. Iwwerpréift w.e.g. de Verglach ënnendrënner fir nozekuckeen ob et sou richteg ass, duerno späichert w.e.g d'Ännerungen of, fir dës Aktioun ofzeschléissen.",
 'undo-failure' => "D'Ännerung konnt net réckgängeg gemaach ginn, wëll de betraffenen Abschnitt an der Tëschenzäit geännert gouf.",
 'undo-norev' => "D'Ännerung kann net zréckgesat ginn, well et se net gëtt oder well se scho geläscht ass.",
+'undo-nochange' => "D'Ännerung gouf anscheinend schonn zeréckgesat.",
 'undo-summary' => 'Ännerung $1 vu(n) [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskussioun]] | [[Special:Contributions/$2|{{MediaWiki:Contribslink}}]]) annulléieren.',
 'undo-summary-username-hidden' => 'Versioun $1 vun engem verstoppte Benotzer zrécksetzen',
 
index f4bd080..bb38c2c 100644 (file)
@@ -258,7 +258,7 @@ $messages = array(
 'disclaimers' => 'منكرون',
 'disclaimerpage' => 'پروجه:منكر بيئن كاروريا',
 'edithelp' => 'هومياری سی ويرايشت',
-'helppage' => 'هومياری:محتوا',
+'helppage' => 'هومياری:مینونه',
 'mainpage' => 'سرآسونه',
 'mainpage-description' => 'سرآسونه',
 'policy-url' => 'پروجه:خط و مش',
@@ -1319,13 +1319,18 @@ $2',
 'watchnologintext' => 'شما سی آلشت دئن سیل برگتو با [[ویجه:وامین اومائن کارور|وامین اومائه]]',
 'watch' => 'سيل كردن',
 'unwatch' => 'ديه نبيه',
+'notanarticle' => 'مینونه هیچ بلگه ای نئ',
 'watchlist-details' => '{{جمی:$1|$1 بلگه|$1 بلگیا}} د سیل برگتو هیش بلگه قسه کردن نی .',
+'wlheader-enotif' => 'وارسیاری ایمیل فعال بیه.',
 'wlshowlast' => 'آخرین$1 ساعتیا $2و روزیا $3 نشو بیئه',
 'watchlist-options' => 'گزینیا سیل برگ',
 
+'enotif_mailer' => '{{نوم سیلجا}} وارسیاری ایمیل زننه',
 'enotif_impersonal_salutation' => '{{نوم سیلجا}} کارور',
 
 # Delete
+'excontent' => 'مینونه :"$1" بی',
+'exbeforeblank' => 'مینونه حالی دمایی:"$1" بی',
 'actioncomplete' => 'عملكرد كامل بيه',
 'actionfailed' => 'عملكرد شكست حرده',
 'dellogpage' => 'لاگ پاك كردن',
@@ -1345,6 +1350,7 @@ $2',
 'prot_1movedto2' => '[[$1]] د [[$2]] جا وه جا بی',
 'protect-default' => 'همه کاروریا اجازه دارن',
 'protect-othertime' => 'وخت هنی:',
+'protect-expiry-options' => '1 ساعت:1 ساعت,1 روز:1 روز,1 هفته:1 هفته,2 هفته:2 هفته,1 ما:1 ما,3 ما:3 ما,6 ما:6 ما,1 سال:1 سال,بی حساو:بی حساو',
 'restriction-type' => 'دسرسی:',
 
 # Restrictions (nouns)
@@ -1406,7 +1412,7 @@ $2',
 'block' => 'منع کارور',
 'blockip' => 'منع کارور',
 'ipbother' => 'وخت هنی:',
-'ipboptions' => '2 Ø³Ø§Ø¹ØªÛ\8cا:2 Ø³Ø§Ø¹Øª,1 Ø±Ù\88:1 Ø±Ù\88,3 Ø±Ù\88زا:3 Ø±Ù\88,1 Ù\87Ù\81تÙ\87:1 Ù\87Ù\81تÙ\87,2 Ù\87Ù\81تÙ\87 Û\8cا:2 Ù\87Ù\81تÙ\87,1 Ù\85ا:1 Ù\85ا,3 Ù\85ا:3 Ù\85Û\8cا,6 Ù\85ا:6 Ù\85اÛ\8cا,1 Ø³Ø§Ù\84:1ساÙ\84­Ø¯ Ù\86ارÙ\87:حد Ù\86ارÙ\87',
+'ipboptions' => '2 Ø³Ø§Ø¹ØªÛ\8cا:2 Ø³Ø§Ø¹Øª,1 Ø±Ù\88:1 Ø±Ù\88,3 Ø±Ù\88زا:3 Ø±Ù\88,1 Ù\87Ù\81تÙ\87:1 Ù\87Ù\81تÙ\87,2 Ù\87Ù\81تÙ\87 Û\8cا:2 Ù\87Ù\81تÙ\87,1 Ù\85ا:1 Ù\85ا,3 Ù\85ا:3 Ù\85Û\8cا,6 Ù\85ا:6 Ù\85اÛ\8cا,1 Ø³Ø§Ù\84:1ساÙ\84¨Û\8c Ø­Ø³Ø§Ù\88:بÛ\8c Ø­Ø³Ø§Ù\88',
 'ipbhidename' => 'نوم کاروری نه سی ویرایشت یا و نوم گه یا قام کو',
 'unblockip' => 'کارور منع نبیه',
 'blocklist' => 'كاروريا منع بيه',
@@ -1521,6 +1527,7 @@ $2',
 
 # Info page
 'pageinfo-language' => 'بلگه مینونه زون',
+'pageinfo-content-model' => 'شلگ مینونه بلگه',
 'pageinfo-category-files' => 'شماره جانیایا',
 
 # Patrol log
@@ -1546,6 +1553,13 @@ $2',
 'newimages-label' => 'نوم جانیا(یا بشقی د وه):',
 'sp-newimages-showfrom' => 'جانیایا تازه نه که $2 ، $2 شرو بینه نشو بیه',
 
+# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'days' => '{{جمی:$1|1$ روز|$1 روز}}',
+'years' => '{{جمی:$1|$1 سال|$1 سال}}',
+
+# Human-readable timestamps
+'monday-at' => 'دوشمه د $1',
+
 # Bad image list
 'bad_image_list' => 'دونسمنديانه وه ای شلگ وارد بكيت:
 
@@ -1579,6 +1593,8 @@ $2',
 'exif-filesource' => 'سرچشمه جانیا',
 'exif-gpstimestamp' => 'وخت جی پی اس (ساعت اتمی)',
 'exif-jpegfilecomment' => 'ویر و باور فایل پی ان جی',
+'exif-citycreated' => 'شهری که عسگ دش گرته بیه',
+'exif-citydest' => 'شهر دیار بیه',
 'exif-languagecode' => 'زون',
 'exif-datetimeexpires' => 'وا نها دش استفاده نبوئه',
 'exif-pngfilecomment' => 'ویر و باور فایل جی پی ان جی',
@@ -1588,12 +1604,18 @@ $2',
 
 'exif-exposureprogram-1' => 'دسی',
 
+'exif-lightsource-1' => 'روشنایی روز',
+
+'exif-scenecapturetype-3' => 'چی شو',
+
 # Pseudotags used for GPSAltitudeRef
 'exif-gpsaltitude-above-sealevel' => '$1 {{جمی:$1|متر|متریا}} وارؤ د ریتراز دریا',
 'exif-gpsaltitude-below-sealevel' => '$1 {{جمی:$1|متر|متریا}} وارؤ د ریتراز دریا',
 
 'exif-gpsdop-good' => 'خو ($1)',
 
+'exif-iimcategory-ace' => 'هنریا، رهزیشت و زیستگه',
+
 # 'all' in various places, this might be different for inflected languages
 'watchlistall2' => 'همه شو',
 'namespacesall' => 'همه شو',
@@ -1603,11 +1625,15 @@ $2',
 'imgmultigo' => 'رؤ!',
 
 # Language selector for translatable SVGs
+'img-lang-default' => '(زون پیش زمینه)',
 'img-lang-go' => 'رو',
 
 # Table pager
 'table_pager_limit_submit' => 'رو',
 
+# Auto-summaries
+'autosumm-replace' => 'مینونه وا "َ$1" جاگزین بی',
+
 # Watchlist editing tools
 'watchlisttools-view' => 'آلشتیا مرتوط نه بوینیت',
 'watchlisttools-edit' => 'سیل برگ بوینیتو و ویرایشت بکید',
@@ -1648,7 +1674,9 @@ $2',
 'compare-revision-not-exists' => 'وانئری که شما تی دیار کردیته وجود ناره.',
 
 # New logging system
+'revdelete-content-hid' => 'مینونه قام بیه',
 'revdelete-uname-hid' => 'نوم کاروری قام بیه',
+'revdelete-content-unhid' => 'مینونه قام نبیه',
 'revdelete-uname-unhid' => 'نوم کاروری قام نبیه',
 
 # Feedback
@@ -1661,6 +1689,10 @@ $2',
 'api-error-illegal-filename' => 'نوم جانیا اجازه دئه نئ.',
 'api-error-mustbeloggedin' => 'شما سی سوارکردن فایلیا با بیایت وامین',
 
+# Durations
+'duration-days' => '$1{{جمی:$1|روز|روزیا}}',
+'duration-years' => '$1{{جمی:$1| سال|سالیا}}',
+
 # Special:ExpandTemplates
 'expand_templates_remove_comments' => 'جا وه جا بیئن ویر و باوریا',
 
index 6a075e8..ba0244e 100644 (file)
@@ -670,6 +670,7 @@ Mila manaiky cookies ianao raha te hiditra amin'ny {{SITENAME}}.",
 'userlogin-resetpassword-link' => 'Hadino ny tenimiafina?',
 'helplogin-url' => 'Help:Fidirana',
 'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Fanoroana mikasika ny fidirana]]',
+'userlogin-loggedin' => "Efa tafiditra amin'ny anaran'i {{GENDER:$1|$1}} ianao. Ampiasao ny fôrmiolera eo ambany raha hiditra amin'ny anaran'ny mpikambana hafa.",
 'userlogin-createanother' => 'Hamorona kaonty hafa',
 'createacct-join' => 'Atsofohy eo ambany ny fampahalalana momba anao.',
 'createacct-another-join' => "Atsofohy eo ambany ny fampahalalana vaovaon'ny kaonty",
@@ -733,16 +734,15 @@ tenimiafina taloha ihany no ampiasao.{{PLURAL:}}',
 'passwordsent' => 'Nandefasana tenimiafina vaovao any amin\'ny adiresy imailak\'i "$1".
 Azafady midira rehefa voarainao io imailaka io.',
 'blocked-mailpassword' => "Voasakana ny adiresy IP-nao, nesorina aminao ny asa ''password recovery'' mba tsy hanararaotra.",
-'eauthentsent' => "
-Efa nandefasana imailaka fanamarinana ilay adiresy nomenao.
-Alohan'ny handraisanao imailaka hafa, dia araho ny torolalana ao anatin'io imailaka io,
-mba hanaporofoana fa anao io kaonty io.",
+'eauthentsent' => "Efa nandefasana imailaka fanamarinana ilay adiresy nomenao.
+Alohan'ny handefasana mailaka hafa any amin'ity kaonty ity dia mila manaraka ny torolalana ianao hahafahana manamarina anao ho tompon'ilay kaonty.",
 'throttled-mailpassword' => "Efa nandefasana mailaka famerenana tenimiafiana ianao tanatin'ny {{PLURAL:$1|ora|$1 ora}}.
 Mba tsy hisian'ny fanararaotana dia mailaka famerenana tenimiafiana iray ihany no azo ampiasaina isaky ny adin'ny $1{{PLURAL:}}.",
 'mailerror' => "Nisy olana tamin'ny fandefasana imailaka: $1",
 'acct_creation_throttle_hit' => 'Miala tsiny, efa nanokatra kaonty miisa $1 ianao, ka tsy afaka mamorona hafa intsony.{{PLURAL:}}',
-'emailauthenticated' => "Voamarina tamin'ny $2 $3 ny adiresy imailakao.",
-'emailnotauthenticated' => "Tsy mbola voamarina ny adiresinao. Tsy mbola afaka mandefa hafatra ianao amin'ireto zavatra azo atao manaraka ireto.",
+'emailauthenticated' => "Voamarina tamin'ny $2 tamin'ny $3 ny adiresy mailakao.",
+'emailnotauthenticated' => "Tsy mbola nomarinina ny adiresy mailakao.
+Tsy handefa mailaka izy ho an'ireo asa ireo.",
 'noemailprefs' => 'Manomeza adiresy imailaka raha hampiasa ireo fitaovana ireo ianao.',
 'emailconfirmlink' => 'Hamarino ny adiresy imailakao',
 'invalidemailaddress' => 'Tsy mety io imailaka nalefanao io satria tsy manaraka ny firafitra tokony ho izy.
@@ -792,7 +792,7 @@ Mety efa nanova tenimiafina na nanontany tenimiafina miserana angamba ianao.',
 # Special:PasswordReset
 'passwordreset' => 'Famafana ary famerenana ny tenimiafina',
 'passwordreset-text-one' => 'Fenoy ity fôrmiolera ity mba hamerenana ny tenimiafinao',
-'passwordreset-text-many' => "Fenoy ny iray amin'ireo saha ireo mba hamerenana ny tenimiafinao{{PLURAL:$1}}",
+'passwordreset-text-many' => '{{PLURAL:$1|Fenoy ny saha mba hahazoanao tenimiafina vonjimaika.}}',
 'passwordreset-legend' => 'Famafana ary famerenana ny tenimiafina',
 'passwordreset-disabled' => "Tsy nalefa ny fanovana tenimiafina adino eto amin'ity wiki ity.",
 'passwordreset-emaildisabled' => "Tsy avela ny fampiasana mailaka eto amin'ity wiki ity.",
@@ -1044,7 +1044,7 @@ Efa misy izy.',
 'invalid-content-data' => "Data anaty votoatiny tsy miady amin'ny fepetra",
 'content-not-allowed-here' => "Votoatiny ''$1'' voarara eo amin'ny pejy [[$2]]",
 'editwarning-warning' => "Mety hahavery ny fanovana nataonao ny fialanao amin'ity pejy ity.
-Raha tafiditra ianao dia azonao esorina ity fampitandremana ity ao amin'ny fizarana \"Fanovàna\" ao amin'ny safidinao",
+Raha tafiditra ianao dia azonao esorina ity fampitandremana ity ao amin'ny fizarana \"{{int:prefs-editing}}\" ao amin'ny safidinao.",
 
 # Content models
 'content-model-wikitext' => 'wiki-soratra',
@@ -1077,6 +1077,7 @@ Ao aorian'ny fivelarana, mety namoaka valy lava loatra angamba izy, ary tsy namp
 'undo-success' => 'Ho voafafa io fanovana io. Marino tsara ny fanovana eo ambany, ary tehirizo rehefa vita.',
 'undo-failure' => "Tsy afaka esorina io fanovàna io : mety tsy miraikitra amin'ny fanovàna misy eo ampivoaniny ra esorina",
 'undo-norev' => 'Tsy afaka nesorina ilay fanovàna satria tsy misy na efa voafafa izy.',
+'undo-nochange' => 'Hoatry ny efa nofoanana ilay fanovana.',
 'undo-summary' => "Niala ny fanovàna $1 nataon'i [[Special:Contributions/$2|$2]] ([[User talk:$2|resaho]])",
 'undo-summary-username-hidden' => 'Namafa ny famerenana $1 nataom-pikambana afenina',
 
@@ -1165,18 +1166,19 @@ tsy misy ilay izy, na ny santiôna ankehitriny no andramana asitrika.',
 Mbola afaka jeren'ireo mpandrindran'i {{SITENAME}} foana ny votoatiny voafina  ary azony atao ho hitan'ny vahoaka indray ilay izy amin'ny alalan'ity pejy fanaovan-tsafidy ity, raha tsy misy fepetra apetraka.",
 'revdelete-confirm' => 'Amafiso eto ny hevitrao raha hanao io ianao, raha azonao sary an-tsaina ny mety ho vokany, ary raha araka ny [[{{MediaWiki:Policy-url}}|fepetra mihatra]] ny zavatra ataonao.',
 'revdelete-suppress-text' => "Ny famafàna pejy dia ampiasaina rehefa :
-* Misy information tsy sarababem-bahoaka tsy metimety
-*: ''Misy adiresy nomeraona antso an-tariby, nomeraona sécurité sociale, sns.''",
+* Fampahalalana mampiely lainga
+* Misy fampahalalana tsy sarababem-bahoaka tsy metimety
+*: ''Adiresy onenana, laharana antso an-tariby, sns.''",
 'revdelete-legend' => "Ampetraho ny fepetra momban'ny fahitana :",
-'revdelete-hide-text' => "Asitriho ny lahatsoratr'ity version ity",
+'revdelete-hide-text' => 'Tahirintsoratry ny versiona',
 'revdelete-hide-image' => "asitriho ny votoatin'ilay rakitra",
 'revdelete-hide-name' => 'Asitriho ny asa sy ny tanjona',
-'revdelete-hide-comment' => 'asitriho ny ambangovangony',
-'revdelete-hide-user' => "Asitriho ny solonanaran'ny mpikambana/adiresy IP",
+'revdelete-hide-comment' => "Ambangovangon'ilay fiovàna",
+'revdelete-hide-user' => "Adiresy IPn'ny Mpanova",
 'revdelete-hide-restricted' => "Fafao ireo votoatiny ireo amin'ny mpiandrindra sy amin'ny mpikambana hafa",
 'revdelete-radio-same' => '(aza ovaina)',
-'revdelete-radio-set' => 'Eny',
-'revdelete-radio-unset' => 'Tsia',
+'revdelete-radio-set' => 'Afenina',
+'revdelete-radio-unset' => 'Hita maso',
 'revdelete-suppress' => "Manitrika ny votoatiny ho an'ny mpandrindra",
 'revdelete-unsuppress' => "Hanala ny fepetra eo amin'ny versiona naverina",
 'revdelete-log' => 'Antony :',
@@ -1268,7 +1270,7 @@ Marino raha manohy ny tantaram-pejy ity asa ity.",
 'shown-title' => 'Aseho valiny $1 isaky ny pejy iray{{PLURAL:}}',
 'viewprevnext' => 'Hijery ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-exists' => "'''Misy pejy mitondra anarana « [[:$1]] » eto amin'ity wiki ity'''",
-'searchmenu-new' => "'''Hanamboatra ny pejy « [[:$1|$1]] » eto amin'ity wiki ity !'''",
+'searchmenu-new' => "'''Hamorona ny pejy \"[[:\$1]]\" eto amin'ity wiki ity!'''",
 'searchprofile-articles' => 'Pejy misy votoatiny',
 'searchprofile-project' => 'Pejy fanampiana sy pejy tetikasa',
 'searchprofile-images' => 'Multimedia',
index 6274cee..29a6edf 100644 (file)
@@ -1211,7 +1211,7 @@ $2
 'invalid-content-data' => 'Неважечки податоци од содржината',
 'content-not-allowed-here' => 'Содржините од моделот „$1“ не се допуштени на страницата [[$2]]',
 'editwarning-warning' => 'Ако ја напуштите страницата ќе ги изгубите сите промени кои сте ги направиле.
-Ако сте најавени, можете да го исклучите ова предупредување во одделот „Уредување“ во вашите нагодувања.',
+Ако сте најавени, можете да го исклучите ова предупредување во одделот „{{int:prefs-editing}}“ во вашите нагодувања.',
 'editpage-notsupportedcontentformat-title' => 'Форматот на содржината не е поддржан',
 'editpage-notsupportedcontentformat-text' => 'Форматот $1 is не е поддржан од содржинскиот модел $2.',
 
@@ -1248,6 +1248,7 @@ $2
 Ве молиме споредете ги промените со претходната верзија за да проверите дали тоа е сигурно она што сакате да го направите, а потоа зачувајте ги промените за да го завршите откажувањето на претходното уредување.',
 'undo-failure' => 'Уредувањето не можеше да се откаже заради меѓувремени спротиставени уредувања.',
 'undo-norev' => 'Измената не можеше да биде вратена бидејќи не постои или била избришана.',
+'undo-nochange' => 'Се чини дека измената (уредувањето) е веќе вратена.',
 'undo-summary' => 'Откажано уредувањето $1 на уредникот [[Special:Contributions/$2|$2]] ([[User talk:$2|разговор]])',
 'undo-summary-username-hidden' => 'Поништи ја ревизијата $1 на скриен корисник',
 
@@ -2147,7 +2148,7 @@ $1',
 'uploadnewversion-linktext' => 'Подигни нова верзија на податотекава',
 'shared-repo-from' => 'од $1',
 'shared-repo' => 'заедничко складиште',
-'shared-repo-name-wikimediacommons' => 'Ð\97аедниÑ\87каÑ\82а Ð Ð¸Ð·Ð½Ð¸Ñ\86а',
+'shared-repo-name-wikimediacommons' => 'РизниÑ\86аÑ\82а',
 'filepage.css' => '/* Тука поставените каскадни стилски страници (CSS) се вклучени во страницата за опис на податотеката, како и на клиентските викија */',
 'upload-disallowed-here' => 'Нажалост, не можете да презапишете врз сликава.',
 
index 9077e54..51308ec 100644 (file)
@@ -1163,7 +1163,7 @@ $1 ആണ് ഈ തടയൽ നടത്തിയത്. ''$2'' എന്ന
 'invalid-content-data' => 'അസാധുവായ ഉള്ളടക്ക ഡേറ്റ',
 'content-not-allowed-here' => '"$1" ഉള്ളടക്കം [[$2]] താളിൽ അനുവദിക്കുന്നില്ല',
 'editwarning-warning' => 'ഈ താളിൽ നിന്നും പോകുന്നത് താങ്കൾ വരുത്തിയ മാറ്റങ്ങൾ നഷ്ടപ്പെടാൻ ഇടയാക്കും.
-താങ്കൾ ലോഗിൻ ചെയ്തിട്ടുണ്ടെങ്കിൽ, താങ്കളുടെ ക്രമീകരണങ്ങളിൽ "തിരുത്തൽ" എന്ന ഭാഗത്ത് ചെന്ന് ഈ അറിയിപ്പ് പ്രദർശിപ്പിക്കുന്നത് ഒഴിവാക്കാവുന്നതാണ്.',
+താങ്കൾ ലോഗിൻ ചെയ്തിട്ടുണ്ടെങ്കിൽ, താങ്കളുടെ ക്രമീകരണങ്ങളിൽ "{{int:prefs-editing}}"  എന്ന ഭാഗത്ത് ചെന്ന് ഈ അറിയിപ്പ് പ്രദർശിപ്പിക്കുന്നത് ഒഴിവാക്കാവുന്നതാണ്.',
 'editpage-notsupportedcontentformat-title' => 'ഉള്ളടക്ക ഫോർമാറ്റ് പിന്തുണയ്ക്കുന്നില്ല',
 'editpage-notsupportedcontentformat-text' => 'ഉള്ളടക്കത്തിന്റെ ഫോർമാറ്റ് ആയ $1 ഉള്ളടക്ക രീതിയായ $2 പിന്തുണയ്ക്കുന്നില്ല.',
 
@@ -1381,6 +1381,8 @@ $1",
 'showhideselectedversions' => 'തിരഞ്ഞെടുത്ത മാറ്റങ്ങൾ പ്രദർശിപ്പിക്കുക/മറയ്ക്കുക',
 'editundo' => 'മാറ്റം തിരസ്ക്കരിക്കുക',
 'diff-empty' => '(വ്യത്യാസം ഇല്ല)',
+'diff-multi-sameuser' => '(ഒരേ ഉപയോക്താവ് ചെയ്ത {{PLURAL:$1|ഇടയ്ക്കുള്ള ഒരു നാൾപ്പതിപ്പ്|ഇടയ്ക്കുള്ള $1 നാൾപ്പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല)',
+'diff-multi-otherusers' => '({{PLURAL:$2|മറ്റൊരു ഉപയോക്താവ്|$2 ഉപയോക്താക്കൾ}} ചെയ്ത {{PLURAL:$1|ഇടയ്ക്കുള്ള ഒരു നാൾപ്പതിപ്പ്|ഇടയ്ക്കുള്ള $1 നാൾപ്പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല)',
 'diff-multi-manyusers' => '(ഇടയ്ക്ക് {{PLURAL:$2|ഒന്നിലധികം|$2 എണ്ണത്തിലധികം}} ഉപയോക്താക്കൾ ചെയ്തിട്ടുള്ള {{PLURAL:$1|ഒരു പതിപ്പ്|$1 പതിപ്പുകൾ}} പ്രദർശിപ്പിക്കുന്നില്ല.)',
 'difference-missing-revision' => 'ഈ വ്യത്യാസത്തിൽ ($1) {{PLURAL:$2|ഒരു നാൾപ്പതിപ്പ്|$2 നാൾപ്പതിപ്പുകൾ}} കാണാനായില്ല.
 
@@ -1401,7 +1403,7 @@ $1",
 'shown-title' => '{{PLURAL:$1|ഒരു ഫലം|$1 ഫലങ്ങൾ}} വീതം താളിൽ കാണിക്കുക',
 'viewprevnext' => '$1 {{int:pipe-separator}} $2 എണ്ണം കാണുക ($3)',
 'searchmenu-exists' => "'''\"[[:\$1]]\" എന്ന തലക്കെട്ടിൽ ഒരു താൾ ഈ വിക്കിയിൽ നിലവിലുണ്ട്'''",
-'searchmenu-new' => "'''ഈ വിക്കിയിൽ \"[[:\$1]]\" താൾ നിർമ്മിക്കുക!'''",
+'searchmenu-new' => '<strong>ഈ വിക്കിയിൽ "[[:$1]]" എന്ന താൾ സൃഷ്ടിക്കുക!</strong> {{PLURAL:$2|0=|ഒപ്പം താങ്കളുടെ തിരയലിനു ലഭിച്ച ഫലമായ ഈ താൾ കാണുക.|ഒപ്പം താങ്കളുടെ തിരയലിനു ലഭിച്ച ഫലങ്ങൾ കാണുക.}}',
 'searchprofile-articles' => 'ലേഖനങ്ങളിൽ',
 'searchprofile-project' => 'സഹായം, പദ്ധതി താളുകളിൽ',
 'searchprofile-images' => 'പ്രമാണങ്ങളിൽ',
@@ -2511,7 +2513,7 @@ $UNWATCHURL
 'delete-edit-reasonlist' => 'മായ്ക്കലിന്റെ കാരണം തിരുത്തുക',
 'delete-toobig' => 'ഈ താളിനു വളരെ വിപുലമായ തിരുത്തൽ ചരിത്രമുണ്ട്. $1 മേൽ {{PLURAL:$1|പതിപ്പുണ്ട്|പതിപ്പുകളുണ്ട്}}. ഇത്തരം താളുകൾ മായ്ക്കുന്നതു {{SITENAME}} സം‌രംഭത്തിന്റെ നിലനില്പ്പിനെ തന്നെ ബാധിക്കുമെന്നതിനാൽ ഈ താൾ മായ്ക്കുന്നതിനുള്ള അവകാശം പരിമിതപ്പെടുത്തിയിരിക്കുന്നു.',
 'delete-warning-toobig' => 'ഈ താളിനു വളരെ വിപുലമായ തിരുത്തൽ ചരിത്രമുണ്ട്. അതായത്, ഇതിനു് $1 മേൽ {{PLURAL:$1|പതിപ്പുണ്ട്|പതിപ്പുകളുണ്ട്}}. ഇത്തരം താളുകൾ മായ്ക്കുന്നതു {{SITENAME}} സം‌രംഭത്തിന്റെ ഡാറ്റാബേസ് ഓപ്പറേഷനെ ബാധിച്ചേക്കാം. അതിനാൽ വളരെ ശ്രദ്ധാപൂർവ്വം തുടർനടപടികളിലേക്കു നീങ്ങുക.',
-'deleting-backlinks-warning' => "'''മുന്നറിയിപ്പ്:''' മറ്റു താളുകളിൽ നിന്നും താളിലേയ്ക്കുള്ള കണ്ണികൾ താങ്കൾ മായ്ക്കാൻ പോവുകയാണ്.",
+'deleting-backlinks-warning' => "'''à´®àµ\81à´¨àµ\8dനറിയിപàµ\8dà´ªàµ\8d:''' à´®à´±àµ\8dà´±àµ\81 à´¤à´¾à´³àµ\81à´\95ളിൽ à´¨à´¿à´¨àµ\8dà´¨àµ\81à´\82 à´¤à´¾à´³à´¿à´²àµ\87à´¯àµ\8dà´\95àµ\8dà´\95àµ\81à´³àµ\8dà´³ à´\95à´£àµ\8dണിà´\95ൾ à´\85à´²àµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ à´\89ൾപàµ\8dà´ªàµ\86à´\9fàµ\81à´¤àµ\8dതിയിà´\9fàµ\8dà´\9fàµ\81à´³àµ\8dà´³ à´¤à´¾à´³àµ\81à´\95ൾ à´¤à´¾à´\99àµ\8dà´\95ൾ à´®à´¾à´¯àµ\8dà´\95àµ\8dà´\95ാൻ à´ªàµ\8bà´µàµ\81à´\95യാണàµ\8d.",
 
 # Rollback
 'rollback' => 'തിരുത്തലുകൾ റോൾബാക്ക് ചെയ്യുക',
@@ -3035,7 +3037,7 @@ $1',
 തത്കാലത്തേയ്ക്കു വേണ്ടിയിരുന്ന ഒരു ഫോൾഡർ ലഭ്യമല്ല.',
 'import-parse-failure' => 'എക്സ്.എം.എൽ. ഇറക്കുമതി പാഴ്സ് പരാജയം',
 'import-noarticle' => 'ഇറക്കുമതി ചെയ്യാൻ താൾ ഇല്ല!',
-'import-nonewrevisions' => 'à´\8eà´²àµ\8dലാ à´ªà´¤à´¿à´ªàµ\8dà´ªàµ\81à´\95à´³àµ\81à´\82 à´®àµ\81à´®àµ\8dà´ªàµ\87 à´\87à´±à´\95àµ\8dà´\95àµ\81മതി à´\9aàµ\86à´¯àµ\8dതിà´\9fàµ\8dà´\9fàµ\81à´³àµ\8dളതാണàµ\8dâ\80\8c.',
+'import-nonewrevisions' => 'à´\92à´°àµ\81 à´¨à´¾àµ¾à´ªàµ\8dപതിപàµ\8dà´ªàµ\81à´\82 à´\87à´±à´\95àµ\8dà´\95àµ\81മതി à´\9aàµ\86à´¯àµ\8dതിà´\9fàµ\8dà´\9fà´¿à´²àµ\8dà´² (à´\8eà´²àµ\8dലാà´\82 à´¨à´¿à´²à´µà´¿àµ½ à´\89à´£àµ\8dà´\9fàµ\8d, à´\85à´²àµ\8dà´²àµ\86à´\99àµ\8dà´\95ിൽ à´ªà´¿à´´à´µàµ\81à´\95à´³àµ\81à´³àµ\8dളതിനാൽ à´\92ഴിവാà´\95àµ\8dà´\95à´¿).',
 'xml-error-string' => '$2 വരിയിൽ $1, നിര $3 (ബൈറ്റ് $4): $5',
 'import-upload' => 'എക്സ്.എം.എൽ. ഡേറ്റ അപ്‌‌ലോഡ് ചെയ്യുക',
 'import-token-mismatch' => 'സെഷൻ ഡാറ്റ നഷ്ടപ്പെട്ടതിനാൽ ദയവായി വീണ്ടും ശ്രമിക്കൂക',
@@ -4220,4 +4222,6 @@ $5
 'expand_templates_generate_rawhtml' => 'അസംസ്കൃത എച്ച്.റ്റി.എം.എൽ. പ്രദർശിപ്പിക്കുക',
 'expand_templates_preview' => 'എങ്ങനെയുണ്ടെന്നു കാണുക',
 
+# Unknown messages
+'uploadinvalidxml' => 'അപ്‌ലോഡ് ചെയ്ത പ്രമാണത്തിലെ എക്സ്.എം.എൽ. പാഴ്സ് ചെയ്യാൻ കഴിയില്ല.',
 );
index 90ebd48..a312ca6 100644 (file)
@@ -1551,6 +1551,7 @@ Innota però li l-werreja tal-kontenut ta' {{SITENAME}} f'dawn is-siti, jistgħu
 'recentchanges' => 'Tibdil riċenti',
 'recentchanges-legend' => 'Opzjonijiet tat-tibdil riċenti',
 'recentchanges-summary' => 'Din il-paġna turi l-modifiki l-aktar riċenti għal kontenut tas-sit.',
+'recentchanges-noresult' => 'L-ebda bidla ma saret matul il-perjodu mogħti li tissodisfa dawn il-kriterji.',
 'recentchanges-feed-description' => "Dan il-feed jirraporta l-modifiki l-aktar riċenti fil-kontenut ta' dan is-sit.",
 'recentchanges-label-newpage' => 'Din il-modifika ħolqot paġna ġdida',
 'recentchanges-label-minor' => 'Din hi modifika minuri',
index 8595700..893be59 100644 (file)
@@ -1151,7 +1151,8 @@ Slette- og flytteloggen vises nedenfor.',
 'content-failed-to-parse' => 'Klarte ikke å tolke innholdet $2 for innholdsmodellen $1: $3',
 'invalid-content-data' => 'Ugyldig innhold',
 'content-not-allowed-here' => 'Innholdsmodellen «$1» er ikke tillatt på siden [[$2]]',
-'editwarning-warning' => 'Ved å forlate siden kan du miste alle endringer du har utført. Om du er logget inn kan du slå av denne advarselen under «Redigering»-seksjonen i innstillingene.',
+'editwarning-warning' => 'Ved å forlate siden kan du miste alle endringer du har gjort.
+Hvis du er innlogget, kan du slå av denne advarselen under "{{int:prefs-editing}}"-avsnittet i dine innstillinger.',
 'editpage-notsupportedcontentformat-title' => 'Innholdsformatet er ikke støttet',
 'editpage-notsupportedcontentformat-text' => 'Innholdsformatet $1 er ikke støttet av innholdsmodellen $2.',
 
index e1498bb..7bd2cea 100644 (file)
@@ -1457,6 +1457,8 @@ Let op dat het gebruiken van de navigatiekoppelingen deze kolom opnieuw instelt.
 'showhideselectedversions' => 'Geselecteerde versies weergeven/verbergen',
 'editundo' => 'ongedaan maken',
 'diff-empty' => '(geen verschil)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Een tussenliggende revisie|$1 tussenliggende revisies}} door dezelfde gebruiken niet weergegeven)',
+'diff-multi-otherusers' => '({{PLURAL:$1|Een tussenliggende revisie|$1 tussenliggende revisies}} door {{PLURAL:$2|een andere gebruiker|$2 gebruikers}} niet weergegeven)',
 'diff-multi-manyusers' => '($1 tussenliggende {{PLURAL:$1|versie|versies}} door meer dan $2 {{PLURAL:$2|gebruiker|gebruikers}}  worden niet weergegeven)',
 'difference-missing-revision' => '{{PLURAL:$2|Eén versie|$2 versies}} van deze verschillen ($1) {{PLURAL:$2|is|zijn}} niet aangetroffen.
 
@@ -1478,7 +1480,7 @@ Probeer een andere zoekopdracht.',
 'shown-title' => '$1 {{PLURAL:$1|resultaat|resultaten}} per pagina weergeven',
 'viewprevnext' => '($1 {{int:pipe-separator}} $2) ($3) bekijken.',
 'searchmenu-exists' => "* Pagina '''[[$1]]'''",
-'searchmenu-new' => "'''De pagina \"[[:\$1]]\" aanmaken op deze wiki.'''",
+'searchmenu-new' => '<strong>Maak de pagina "[[:$1]]" op deze wiki!</strong> {{PLURAL:$2|0=|Zie ook de pagina met uw zoekresultaat. |Zie ook de lijst met gevonden zoekresultaten}}',
 'searchprofile-articles' => "Inhoudelijke pagina's",
 'searchprofile-project' => "Hulp- en projectpagina's",
 'searchprofile-images' => 'Multimedia',
@@ -2542,6 +2544,7 @@ Toekomstige bewerkingen van deze pagina en de bijbehorende overlegpagina worden
 'watchmethod-list' => "controleer pagina's op volglijst op wijzigingen",
 'watchlistcontains' => "Er {{PLURAL:$1|staat één pagina|staan $1 pagina's}} op uw volglijst.",
 'iteminvalidname' => "Probleem met object '$1', ongeldige naam…",
+'wlnote2' => 'Hieronder staan de veranderingen in {{PLURAL:$1|het|de}} laatste {{PLURAL:$1|uur|<strong> $1 </strong>uren}}, sinds $2, $3.',
 'wlshowlast' => 'Laatste $1 uur, $2 dagen bekijken ($3)',
 'watchlist-options' => 'Opties voor volglijst',
 
@@ -3165,7 +3168,7 @@ Het bestand is slechts gedeeltelijk aangekomen.',
 Een tijdelijke map is niet aanwezig.',
 'import-parse-failure' => 'Fout bij het verwerken van de XML-import',
 'import-noarticle' => "Er zijn geen te importeren pagina's!",
-'import-nonewrevisions' => 'Alle versies zijn al eerder geïmporteerd.',
+'import-nonewrevisions' => 'Geen revisies geïmporteerd (alle waren al aanwezig, of overgeslagen vanwege fouten).',
 'xml-error-string' => '$1 op regel $2, kolom $3 (byte $4): $5',
 'import-upload' => 'XML-gegevens uploaden',
 'import-token-mismatch' => 'De sessiegegevens zijn verloren gegaan. Probeer het opnieuw.',
@@ -3176,6 +3179,7 @@ Een tijdelijke map is niet aanwezig.',
 'import-error-special' => 'Pagina "$1" is niet geïmporteerd omdat deze is geplaatst in een speciale naamruimte waar geen pagina\'s in geplaatst kunnen worden.',
 'import-error-invalid' => 'De pagina" "$1" is niet geïmporteerd omdat de naam ongeldig is.',
 'import-error-unserialize' => 'Versie $2 van de pagina "$1" kon niet verwerkt worden. De versie hoort contentmodel $3 te gebruiken met een serialisatie als $4.',
+'import-error-bad-location' => 'Revisie $2 met behulp van model $3 kan niet worden opgeslagen als "$1" op deze wiki, aangezien dat model niet ondersteund wordt op die pagina.',
 'import-options-wrong' => 'Verkeerde {{PLURAL:$2|optie|opties}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'De opgegeven basispagina is ongeldig.',
 'import-rootpage-nosubpage' => 'In de naamruimte "$1" van de basispagina is het aanmaken van subpagina\'s niet mogelijk.',
index a2d84bd..e76baaf 100644 (file)
@@ -1159,7 +1159,7 @@ Strona już istnieje.',
 'invalid-content-data' => 'Zawartość strony zawiera nieprawidłowe dane',
 'content-not-allowed-here' => 'Zawartość tego typu ($1) nie jest dozwolona na stronie [[$2]]',
 'editwarning-warning' => 'Opuszczenie tej strony może spowodować utratę wprowadzonych przez Ciebie zmian.
-Jeśli jesteś zalogowany możesz wyłączyć wyświetlanie tego ostrzeżenia w zakładce Edycja w swoich preferencjach.',
+Jeśli jesteś zalogowany, możesz wyłączyć wyświetlanie tego ostrzeżenia w zakładce „{{int:prefs-editing}}” w swoich preferencjach.',
 'editpage-notsupportedcontentformat-title' => 'Nieobsługiwany format zawartości',
 
 # Content models
@@ -1393,7 +1393,7 @@ Zazwyczaj jest to spowodowane przestarzałym linkiem do usuniętej strony. Powó
 'shown-title' => 'Pokaż po $1 {{PLURAL:$1|wyniku|wyniki|wyników}} na stronę',
 'viewprevnext' => 'Zobacz ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "* Strona '''[[$1]]'''",
-'searchmenu-new' => "'''Utwórz stronę „[[:$1|$1]]” na tej wiki.'''",
+'searchmenu-new' => '<strong>Utwórz stronę „[[:$1]]” na tej wiki!<strong> {{PLURAL:$2|0=|Zobacz też stronę z wynikami wyszukiwania.|Zobacz też wyniki wyszukiwania.}}',
 'searchprofile-articles' => 'Strony',
 'searchprofile-project' => 'Strony pomocy i projektu',
 'searchprofile-images' => 'Multimedia',
@@ -2433,7 +2433,7 @@ Każda zmiana treści tej strony lub związanej z nią strony dyskusji zostanie
 'watchmethod-list' => 'poszukiwanie obserwowanych stron wśród ostatnich zmian',
 'watchlistcontains' => 'Na liście obserwowanych przez Ciebie stron {{PLURAL:$1|znajduje się 1 pozycja|znajdują się $1 pozycje|znajduje się $1 pozycji}}.',
 'iteminvalidname' => 'Problem z pozycją „$1” – niepoprawna nazwa...',
-'wlnote2' => 'Poniżej pokazano zmiany wykonane w ciągu {{PLURAL:$1|ostatniej godziny|ostatnich <strong>$1</strong> godzin}}, licząc od $4, $3.',
+'wlnote2' => 'Poniżej pokazano zmiany wykonane w ciągu {{PLURAL:$1|ostatniej godziny|ostatnich <strong>$1</strong> godzin}}, licząc od $2, $3.',
 'wlshowlast' => 'Pokaż ostatnie $1 godzin, $2 dni ($3)',
 'watchlist-options' => 'Opcje obserwowanych',
 
index d498ae6..02af1fb 100644 (file)
@@ -871,7 +871,7 @@ A esist già.",
 'invalid-content-data' => 'Dat dël contnù pa bon',
 'content-not-allowed-here' => "Ël contnù «$1» a l'é nen autorisà an sla pàgina [[$2]]",
 'editwarning-warning' => "Chité sta pàgina-sì a peul feje perde tute le modìfiche ch'a l'ha fàit.
-S'a l'é rintrà ant ël sistema, a peul disabilité st'avis ant la session «Modìfica» dij sò gust.",
+S'a l'é rintrà ant ël sistema, a peul disabilité st'avis ant la session «{{int:prefs-editing}}» dij sò gust.",
 'editpage-notsupportedcontentformat-title' => 'Formà ëd contnù nen mantnù',
 'editpage-notsupportedcontentformat-text' => "Ël formà ëd contnù $1 a l'é nen mantnù dal model Ëd contnù $2.",
 
index 048756b..901cc2c 100644 (file)
@@ -55,6 +55,7 @@
  * @author Huji
  * @author IAlex
  * @author INkubusse
+ * @author Incnis Mrsi
  * @author Iniquity
  * @author Iwan Novirion
  * @author Jon Harald Søby
@@ -403,8 +404,8 @@ Parameters:
 Parameters:
 * $1 - number of subcategories shown',
 'category-article-count' => 'This message is used on category pages. Parameters:
-* $1 - number of pages shown
-* $2 - total number of pages in category',
+* $1  number of pages shown
+* $2  total number of pages in category',
 'category-article-count-limited' => 'This message is displayed at the top of a category page showing the number of pages in the category when not all pages in a category are counted.
 
 Parameters:
@@ -412,7 +413,7 @@ Parameters:
 'category-file-count' => 'This message is displayed at the top of a category page showing the number of pages in the category.
 
 Parameters:
-* $1 - number of files shown
+* $1  number of files shown
 * $2 - total number of files in category',
 'category-file-count-limited' => 'This message is displayed at the top of a category page showing the number of pages in the category when not all pages in a category are counted.
 
@@ -2180,9 +2181,7 @@ Parameters:
 'content-not-allowed-here' => 'Error message indicating that the desired content model is not supported in given localtion.
 * $1 - the human readable name of the content model: {{msg-mw|Content-model-wikitext}}, {{msg-mw|Content-model-javascript}}, {{msg-mw|Content-model-css}} or {{msg-mw|Content-model-text}}
 * $2 - the title of the page in question',
-'editwarning-warning' => "{{doc-important|Do ''not'' use <nowiki>{{int:prefs-editing}}</nowiki> for \"Editing\". It is forbidden in this message, see [[mwr:68405]].}}
-
-but you can see the text of that button here: {{msg-mw|Prefs-editing}}",
+'editwarning-warning' => 'Uses {{msg-mw|Prefs-editing}}',
 'editpage-notsupportedcontentformat-title' => 'Title of error page shown when using an incompatible format on EditPage',
 'editpage-notsupportedcontentformat-text' => 'Error message shown when using an incompatible format on EditPage. Parameters:
 * $1 - the format id
@@ -2303,6 +2302,7 @@ See also:
 'undo-norev' => 'Message appears if an attempt to revert an edit by clicking the "undo" link on the page history fails.
 
 {{Identical|Undo}}',
+'undo-nochange' => 'Message appears if an attempt to revert an edit by clicking the "undo" link results in an edit making no change to the current version of the page.',
 'undo-summary' => 'Edit summary for an undo action. Parameters:
 * $1 - revision ID
 * $2 - username
@@ -2992,6 +2992,10 @@ See also:
 * $3 - total number of results
 * $4 - the search term
 * $5 - number of results',
+'showingresultsinrange' => 'Used in pagination of [[Special:MostLinkedCategories]]. Parameters:
+* $1 - the total number of results in the batch shown
+* $2 - the number of the first item listed
+* $3 - the number of last item in the batch shown',
 'search-nonefound' => 'Message shown when a search returned no results (when using the default MediaWiki search engine).',
 'powersearch-legend' => 'Advanced search
 
@@ -8530,9 +8534,23 @@ Variant option for wikis with variants conversion enabled.',
 
 # Variants for Serbian language
 'variantname-sr-ec' => '{{optional}}
-Varient Option for wikis with variants conversion enabled.',
+Variant Option for wikis with variants conversion enabled.
+
+Note that <code>sr-ec</code> is not a conforming BCP47 language tag. Wikis should be migrated by:
+* allowing it only as a legacy alias of the preferred tag <code>sr-cyrl</code> (possibly insert a tracking category in templates as long as they must support the legacy tag),
+* making the new tag the default to look first, before looking for the old tag,
+* moving the translations to the new code by renaming them,
+* checking links in source pages still using the legacy tag to change it to the new tag,
+* possibly cleanup the redirect pages.',
 'variantname-sr-el' => '{{optional}}
-Varient Option for wikis with variants conversion enabled.',
+Variant Option for wikis with variants conversion enabled.
+
+Note that <code>sr-el</code> is not a conforming BCP47 language tag. Wikis should be migrated by:
+* allowing it only as a legacy alias of the preferred tag <code>sr-latn</code> (possibly insert a tracking category in templates as long as they must support the legacy tag),
+* making the new tag the default to look first, before looking for the old tag,
+* moving the translations to the new code by renaming them,
+* checking links in source pages still using the legacy tag to change it to the new tag,
+* possibly cleanup the redirect pages.',
 'variantname-sr' => '{{optional}}
 Varient Option for wikis with variants conversion enabled.',
 
@@ -9606,7 +9624,11 @@ px is the abbreviation for "pixel".',
 
 # Separators for various lists, etc.
 'semicolon-separator' => '{{optional}}',
-'comma-separator' => '{{optional}}',
+'comma-separator' => '{{optional}}
+
+Warning: languages have different usages of punctuation, and sometimes they are swapped (e.g. openining and closing quotation marks, or full stop and colon in Armenian), or change their form (the full stop in Chinese and Japanese, the prefered "colon" in Armenian used in fact as the regular full stop, the comma in Arabic, Armenian, and Chinese...)
+
+Their spacing (before or after) may also vary across languages (for example French requires a non-breaking space, preferably narrow if the browser supports NNBSP, on the inner side of some punctuations like quotation/question/exclamation marks, colon, and semicolons).',
 'colon-separator' => "{{optional}}
 Change it only if your language uses another character for ':' or it needs an extra space before the colon.",
 'pipe-separator' => '{{optional}}',
@@ -9728,7 +9750,7 @@ Bitrate (of a file, typically) in kilobits (1 kilobit = 1000 bits).',
 'bitrate-megabits' => '{{optional}}
 Bitrate (of a file, typically) in megabits (1 megabits = 1000×1000 bits).',
 'bitrate-gigabits' => '{{optional}}
-Bitrate (of a file, typically) in gibibits (1 gigabits = 1000×1000×1000 bits).',
+Bitrate (of a file, typically) in gigabits (1 gigabits = 1000×1000×1000 bits).',
 'bitrate-terabits' => '{{optional}}
 Bitrate (of a file, typically) in terabits (1 terabits = 1000×1000×1000×1000 bits).',
 'bitrate-petabits' => '{{optional}}
index b913289..fb19e55 100644 (file)
@@ -535,7 +535,7 @@ $1",
 'youhavenewmessagesfromusers' => '$1 {{PLURAL:$3|huk ruraqmanta|$3 ruraqkunamanta}} qhawanayki kachkan ($2).',
 'youhavenewmessagesmanyusers' => '$1 achka ruraqkunamanta qhawanayki kachkan ($2).',
 'newmessageslinkplural' => '{{PLURAL:$1|Musuq willaymi|Musuq willaykunam}}',
-'newmessagesdifflinkplural' => 'qayna {{PLURAL:$1|hukchasqapi|hukchasqakunapi}} wakin kaynin',
+'newmessagesdifflinkplural' => 'ñaqha {{PLURAL:$1|hukchasqa|hukchasqakuna}}',
 'youhavenewmessagesmulti' => 'Musuq willaykunam qhawanayki kachkan $1-pi',
 'editsection' => "llamk'apuy",
 'editold' => "llamk'apuy",
@@ -660,7 +660,7 @@ Amachaq kamachiqqa kayrayku amachani nispa nirqanmi: "$3".',
 'invalidtitle-knownnamespace' => '"$2" sutisuyu, "$3" qillqasqayuq mana allin kaq qillqa suti',
 'invalidtitle-unknownnamespace' => 'Mana riqsisqa $1 kaq sutisuyu yupay, "$2" qillqasqayuq mana allin kaq qillqa suti',
 'exception-nologin' => 'Manam yaykurqankichu',
-'exception-nologin-text' => 'Kay wikipiqa icha kay ruranataqa rakiqunaykiwan yaykuspalla ruraytam atinki.',
+'exception-nologin-text' => "Ama hina kaspa [[Special:Userlogin|yaykuy]] kay p'anqaman rinata icha kayta ruranata atinaykipaq.",
 
 # Virus scanner
 'virus-badscanner' => "Manam allintachu churapusqa: mana riqsisqa añaw maskaq: ''$1''",
@@ -707,7 +707,7 @@ Ama qunqaychu [[Special:Preferences|{{SITENAME}} allinkachinaykikunata]] hukchay
 'gotaccount' => "Rakiqunaykiñachu kachkan? '''$1'''.",
 'gotaccountlink' => 'Rakiqunaykita willaway',
 'userlogin-resetlink' => 'Yaykuna willayniykikunatari qunqarqankichu?',
-'userlogin-resetpassword-link' => 'Yaykuna rimaykita kutichiy',
+'userlogin-resetpassword-link' => 'Yaykuna rimaykita qunqarqankichu?',
 'helplogin-url' => 'Help:Yaykuy',
 'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Yaykunapaq yanapa]]',
 'userlogin-createanother' => 'Huk rakiqunata kamariy',
@@ -754,7 +754,7 @@ Allin qillqasqaykita llanchiriy.',
 'passwordtooshort' => 'Yaykuna rimayqa {{PLURAL:$1|1 icha aswan sanampayuq|$1 icha aswan sanampayuq}} kananmi.',
 'password-name-match' => 'Yaykuna rimaykiqa ruraqpa sutiykiman mana kaqlla kananmi.',
 'password-login-forbidden' => 'Kay ruraqpa sutinmanqa yaykuna rimanmanpas ama nisqam.',
-'mailmypassword' => 'Musuq yaykuna rimata e-chaskiwan kachamuway',
+'mailmypassword' => 'Yaykuna rimata kutichiy',
 'passwordremindertitle' => "{{SITENAME}}paq musuq mit'alla yaykuna rima",
 'passwordremindertext' => 'Pipas (qamchiki, $1 IP huchhayuq tiyaymanta) mañakuwarqan {{SITENAME}}paq musuq yaykuna rimatam e-chaski imamaytaykiman kachayta ($4).
 "$2" sutiyuq ruraqpa mit\'alla yaykuna rimanqa kamarisqañam, "$3" sutichasqam kachkan. Munarqaspaykiqa, kunan yaykuspa musuq yaykuna rimaykitam akllay.
@@ -770,8 +770,8 @@ Ama hina kaspa, chaskispaykiqa ruraqpa sutiykita nispa musuqmanta yaykuy.',
 'throttled-mailpassword' => "Huk yaykuna rima kutichinapaq yuyachina qayna {{PLURAL:$1|huk ura|$1 ura}} mit'api kachamusqañam. {{PLURAL:$1|Huk ura|$1 ura}} mit'apiqa hukllam yaykuna rima yuyachina kachasqa kachun millay rurayta hark'anapaq.",
 'mailerror' => 'E-chaskita kachaspa pantasqa: $1',
 'acct_creation_throttle_hit' => "Qampa IP huchhaykiyuq kachkaq ruraqkunaqa kay wikita watukuspa ñaqha 24 urapi {{PLURAL:$1|rakiqunaykim|$1 rakiqunaykim}} kamarirqanña. Manam atinkichikchu astawan kichayta huklla p'unchawpi chay IP huchhallayuq kaspa.",
-'emailauthenticated' => "E-chaski imamaytaykiqa $2 p'unchawpi, $3 pachapi chiqapchasqañam.",
-'emailnotauthenticated' => 'E-chaski imamaytaykitaqa manaraqmi takyachirqunkichu. Mana takyachirquptiykiqa, kay qatiq rurachinakunataqa manam atinkichu.',
+'emailauthenticated' => "E-chaski imamaytaykiqa $2 p'unchawpi, $3 pachapi takyachisqañam.",
+'emailnotauthenticated' => 'E-chaski imamaytaykitaqa manaraqmi takyachirqunkichu. Manaraq takyachirquptiykiqa, kay ruranakunapaq manam ima e-chaskipas kachasqa kanchu.',
 'noemailprefs' => "E-chaski imamaytaykita willaway kay rurachinakunata llamk'achinapaq.",
 'emailconfirmlink' => 'E-chaski imamaytaykita takyachiy',
 'invalidemailaddress' => "E-chaski imamaytaykiqa manam allinchu, manachá allinta qillqasqa. Ama hina kaspa, musuq allin sananchayuq imamaytaykita qillqamuy icha k'itichata ch'usaqchay.",
@@ -1058,7 +1058,7 @@ Qullusqachá.",
 'edit-already-exists' => "Manam atinichu musuq p'anqata kamariyta.
 Kachkañam.",
 'defaultmessagetext' => 'Ñawpaq qillqa',
-'content-failed-to-parse' => "Manam atinichu $2 samiqta $1 kikinchapaq t'ikrayta: $3",
+'content-failed-to-parse' => 'Manam atinichu $2 samiqta $1 kikinchapaq kuskiyta: $3',
 'invalid-content-data' => 'Samiqmanta willaykunaqa manam allinchu',
 'content-not-allowed-here' => '"$1" nisqa samiqqa [[$2]] sutiyuq p\'anqapi manam saqillasqachu',
 'editwarning-warning' => "Kay p'anqata saqispaykiqa lliw rurarqusqayki hukchasqakunatachá chinkachiykiman.
@@ -1181,18 +1181,19 @@ Kay wakin kayta qhawayta atinkim; astawanchá rikunkiman [{{fullurl:{{#Special:L
 {{SITENAME}}pi huk kamachiqkunaqa p'anqap pakasqa samiqninta qhawaspa qullusqa kaymanta kutichiyta atinkuraqmi kay kaqlla uyapuratam llamk'achispa, kay wikip kamariqninkuna mana huk saywachanakunata tiyachiptinqa.",
 'revdelete-confirm' => 'Ama hina kaspa, takyachiy munayniykita, qatiqninkunata riqsiyniykita, [[{{MediaWiki:Policy-url}}|kawpaykama]] rurayniykitapas.',
 'revdelete-suppress-text' => "Pakay ruranata '''kaylla kaptin''' llamk'achiy:
+* K'amiqchá willakuna
 * Runamanta mana allin willakuna
-*: ''wasi tiyay imamaytakuna, karu rimay huchhakuna, allin kawsay tarikuq wasimanta huchhakuna, chay hinakunapas.''",
+*: ''wasi tiyay imamaytakuna, karu rimay huchhakuna, mamallaqta sut'inchay huchhakuna, chay hinakunapas.''",
 'revdelete-legend' => 'Rikunapaq saywachanakunata tiyachiy',
-'revdelete-hide-text' => 'Qhawana qillqata pakay',
+'revdelete-hide-text' => 'Musuqmanta qhawana qillqa',
 'revdelete-hide-image' => 'Willañiqip samiqninta pakay',
 'revdelete-hide-name' => 'Rurayta paqtaytapas pakay',
-'revdelete-hide-comment' => "Llamk'apuymanta willapuyta pakay",
-'revdelete-hide-user' => 'Ruraqpa sutinta/IP huchhanta pakay',
+'revdelete-hide-comment' => "Llamk'apuymanta willapuy",
+'revdelete-hide-user' => 'Ruraqpa sutin/IP huchhan',
 'revdelete-hide-restricted' => "Kamachiqkunamanta willakunata huk ruraqkunamanta hina hark'ay",
 'revdelete-radio-same' => '(ama hukchaychu)',
-'revdelete-radio-set' => 'Arí',
-'revdelete-radio-unset' => 'Ama kachunchu',
+'revdelete-radio-set' => 'Pakasqa',
+'revdelete-radio-unset' => 'Rikunalla',
 'revdelete-suppress' => 'Kamachiqkunamantapas willakunata huk ruraqkunamanta hina raqpay',
 'revdelete-unsuppress' => "Qullusqamanta paqarisqa llamk'apusqakunapaq saywachanakunata raqpay",
 'revdelete-log' => 'Kayrayku:',
@@ -1290,7 +1291,7 @@ Imaymanata [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} qulluy ha
 'shown-title' => "Huk p'anqapi $1 {{PLURAL:$1|taripasqata|taripasqakunata}} rikuchiy",
 'viewprevnext' => 'Qhaway ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-exists' => "'''Kay wikipiqa «[[$1]]» sutiyuq p'anqam kachkan'''",
-'searchmenu-new' => "'''Kay wikipi \"[[:\$1]]\" sutiyuq p'anqata kamariy!'''",
+'searchmenu-new' => '<strong>Kay wikipi "[[:$1]]" sutiyuq p\'anqata kamariy!</strong> {{PLURAL:$2|0=|Maskayniykiwan tarisqa p\'anqatapas qhaway.|Maskaywan taripasqakunatapas qhaway.}}\'',
 'searchprofile-articles' => "Samiq p'anqakuna",
 'searchprofile-project' => "Yanapanapaq ruraykamaypaqpas p'anqakuna",
 'searchprofile-images' => 'Multimidya',
@@ -1619,7 +1620,7 @@ $1 {{PLURAL:$1|sanampamanta|sanampakunamanta}} aswan pisi kananmi.',
 'recentchanges-label-minor' => "Kayqa aslla llamk'apuymi",
 'recentchanges-label-bot' => "Kayqa rurana antachap llamk'apusqanmi",
 'recentchanges-label-unpatrolled' => "Kay llamk'apusqaqa manaraqmi patrullasqachu",
-'recentchanges-legend-newpage' => "$1 - musuq p'anqa",
+'recentchanges-legend-newpage' => "([[Special:NewPages|musuq p'anqakunatapas]] qhaway)",
 'rcnotefrom' => "Kay qatiqpiqa '''$2'''-mantapacha ('''$1'''-kama) hukchasqakunatam rikunki.",
 'rclistfrom' => '$1-manta musuq hukchasqakunata rikuchiy',
 'rcshowhideminor' => "$1 uchuylla llamk'apusqakunata",
@@ -2309,7 +2310,7 @@ wiki: $PAGEEDITOR_WIKI
 
 Kay p\'anqata mana musuqmanta watukamuptiykiqa, manam huk ruraykunamanta willasqaykichu. Tukuy watiqasqayki p\'anqakunapaq musyachina sananchakunatapas kutichiytam atinkiman.
 
-             Tukuy sunquwan, {{SITENAME}}pa e-chaski musyachina llikan
+Tukuy sunquwan, {{SITENAME}}pa e-chaski musyachina llikan
 
 --
 E-chaski willaykuy allinkachinakunata hukchanaykipaqqa kay p\'anqatam qhaway:
@@ -2345,7 +2346,7 @@ $2 nisqa p\'anqata qhaway ñaqha qullusqakunata rikunaykipaq.',
 'dellogpage' => 'Qullusqakuna',
 'dellogpagetext' => 'Kay qatiqpiqa lliwmanta aswan ñaqha qullusqakunatam rikunki. Rikuchisqa pachankunaqa sirwiqpa pachanpim.',
 'deletionlog' => 'qullusqakuna',
-'reverted' => 'Ñawpaq hukchasqata kutichiy',
+'reverted' => 'Ñawpaq hukchasqaman kutichisqa',
 'deletecomment' => 'Kayrayku:',
 'deleteotherreason' => 'Huk rayku:',
 'deletereasonotherlist' => 'Huk rayku',
@@ -2643,7 +2644,7 @@ Willariy imaraykum hark'anki (ahinataq: sapaq wandaluchasqa p'anqakunamanta will
 'range_block_disabled' => "Kamachiqpa patayayku hark'ay hayñinman ama nisqam.",
 'ipb_expiry_invalid' => 'Puchukana pachaqa manam allinchu.',
 'ipb_expiry_temp' => "Pakasqa ruraqpa sutin hark'aykunaqa tiyaqllam kachun.",
-'ipb_hide_invalid' => "Manam atinichu kay rakiqunata ñit'ipayta; nisyu llamk'apusqayuqñachá.",
+'ipb_hide_invalid' => "Manam atinichu kay rakiqunata ñit'ipayta; nisyu {{PLURAL:$1|llamk'apusqayuqñachá}}.",
 'ipb_already_blocked' => '"$1" sutiyuqqa hark\'asqañam kachkan.',
 'ipb-needreblock' => "$1 sutiyuqqa hark'asqañam. Allinchanakunata hukchayta munankichu?",
 'ipb-otherblocks-header' => "Huk {{PLURAL:$1|hark'ay|hark'aykuna}}",
@@ -2848,7 +2849,7 @@ Tukuy hawa wikimanta chaskisqakunaqa [[Special:Log/import|hawamanta chaskiy hall
 'importuploaderrorsize' => 'Manam atinichu hawamanta chaskina willañiqita churkuyta, saqillasqamanta aswan hatun kaptinmi.',
 'importuploaderrorpartial' => 'Manam atinichu hawamanta chaskina willañiqita churkuyta, rakillam churkusqa.',
 'importuploaderrortemp' => "Manam atinichu hawamanta chaskina willañiqita churkuyta, mit'alla willañiqi churana mana kaptinmi.",
-'import-parse-failure' => "Manam atinichu XML qillqata t'ikraspa hawamanta chaskiyta",
+'import-parse-failure' => 'Manam atinichu XML qillqata kuskispa hawamanta chaskiyta',
 'import-noarticle' => "Manam hawamanta chaskina p'anqachu!",
 'import-nonewrevisions' => 'Tukuy musuqchasqakunaqa ñawpaqtañam hawamanta chaskisqa.',
 'xml-error-string' => "$1, $2 siq'ipi, $3 tunupi (byte $4): $5",
@@ -3080,7 +3081,7 @@ Payta rurachiyqa antañiqiqniykita llikaykitapas waqllinqachá.",
 'svg-long-desc' => 'SVG willañiqi, rimasqakama $1 × $2 iñuyuq, willañiqip chhikan kaynin: $3',
 'svg-long-desc-animated' => 'Kuyuchisqa SVG willañiqi, rimasqakama $1 × $2 iñuyuq, willañiqip chhikan kaynin: $3',
 'svg-long-error' => 'Mana allin SVG willañiqi: $1',
-'show-big-image' => 'Qallariy huyaku',
+'show-big-image' => 'Qallariy willañiqi',
 'show-big-image-preview' => 'Kay ñawpaq qhawariypa chhikan kaynin: $1.',
 'show-big-image-other' => 'Huk {{PLURAL:$2|huyaku|huyakukuna}}: $1.',
 'show-big-image-size' => '$1 × $2 iñu',
@@ -3958,4 +3959,6 @@ Mana chayqa, kay qatiqpi kaq hunt'ana p'anqatam llamk'achiyta atinki. Willapuyni
 'expand_templates_remove_comments' => 'Willapusqakunata qichuy',
 'expand_templates_preview' => 'Ñawpaqta qhawallay',
 
+# Unknown messages
+'uploadinvalidxml' => 'Manam atinichu churkusqa willañiqipi XML-ta kuskiyta.',
 );
index 54bcbdb..c699dde 100644 (file)
@@ -951,7 +951,7 @@ Ar trebui să faceți acest lucru numai dacă le-ați partajat accidental cu alt
 'summary' => 'Rezumat:',
 'subject' => 'Subiect / titlu:',
 'minoredit' => 'Aceasta este o modificare minoră',
-'watchthis' => 'Monitorizează această pagină',
+'watchthis' => 'Urmărește această pagină',
 'savearticle' => 'Salvare pagină',
 'preview' => 'Previzualizare',
 'showpreview' => 'Previzualizare',
@@ -1134,7 +1134,7 @@ Ea există deja.',
 'invalid-content-data' => 'Date de conținut invalide',
 'content-not-allowed-here' => 'Conținutul de tip „$1” nu este permis pe pagina [[$2]]',
 'editwarning-warning' => 'Părăsind această pagină, există riscul pierderii modificărilor efectuate.
-Dacă sunteți autentificat, puteți dezactiva această avertizare în secțiunea „Modificare” a preferințelor dumneavoastră.',
+Dacă sunteți autentificat, puteți dezactiva această avertizare în secțiunea „{{int:prefs-editing}}” a preferințelor dumneavoastră.',
 'editpage-notsupportedcontentformat-title' => 'Formatul conținutului nu este acceptat',
 'editpage-notsupportedcontentformat-text' => 'Formatul de conținut $1 nu este acceptat de modelul de conținut $2.',
 
@@ -1349,6 +1349,8 @@ Folosirea linkurilor de navigare va reseta această coloană.',
 'showhideselectedversions' => 'Șterge/recuperează versiunile marcate',
 'editundo' => 'anulare',
 'diff-empty' => '(Nicio diferență)',
+'diff-multi-sameuser' => '(Nu {{PLURAL:$1|s-a afișat o versiune intermediară efectuată|s-au afișat $1 versiuni intermediare efectuate|s-au afișat $1 de versiuni intermediare efectuate}} de același utilizator)',
+'diff-multi-otherusers' => '(Nu {{PLURAL:$1|s-a afișat o versiune intermediară efectuată|s-au afișat $1 versiuni intermediare efectuate|s-au afișat $1 de versiuni intermediare efectuate}} de {{PLURAL:$2|un alt utilizator|alți $2 utilizatori|alți $2 de utilizatori}})',
 'diff-multi-manyusers' => '({{PLURAL:$1|O versiune intermediară efectuată de|$1 (de) versiuni intermediare efectuate de peste}} $2 {{PLURAL:$2|utilizator|utilizatori}} {{PLURAL:$1|neafișată|neafișate}})',
 'difference-missing-revision' => '{{PLURAL:$2|O versiune a|$2 versiuni ale|$2 de versiuni ale}} acestei diferențe ($1) nu {{PLURAL:$2|a fost găsită|au fost găsite}}.
 
index f135ffc..182cbef 100644 (file)
@@ -569,9 +569,9 @@ $messages = array(
 'hidden-category-category' => 'Скрытые категории',
 'category-subcat-count' => '{{PLURAL:$2|Эта категория содержит только следующую подкатегорию.|Эта категория содержит $1 {{PLURAL:$1|1=подкатегорию|подкатегории}} из $2 всего.}}',
 'category-subcat-count-limited' => 'В этой категории {{PLURAL:$1|$1 подкатегория|$1 подкатегорий|$1 подкатегории}}.',
-'category-article-count' => '{{PLURAL:$2|Эта категория содержит единственную страницу.|{{PLURAL:$1|Показана $1 страница|Показано $1 страниц|Показаны $1 страницы}} из $2, {{PLURAL:$2|находящейся|находящихся|находящихся}} в данной категории.}}',
+'category-article-count' => '{{PLURAL:$2|Эта категория содержит единственную страницу.|{{PLURAL:$1|Показана $1 страница|Показано $1 страниц|Показаны $1 страницы}} из $2, находящихся в данной категории.}}',
 'category-article-count-limited' => 'В этой категории {{PLURAL:$1|$1 страница|$1 страниц|$1 страницы|1=только одна страница}}.',
-'category-file-count' => '{{PLURAL:$2|Эта категория содержит единственный файл.|{{PLURAL:$1|Показан $1 файл|Показано $1 файлов|Показаны $1 файла}} из $2, {{PLURAL:$2|находящегося|находящихся|находящихся}} в данной категории.}}',
+'category-file-count' => '{{PLURAL:$2|Эта категория содержит единственный файл.|{{PLURAL:$1|Показан $1 файл|Показано $1 файлов|Показаны $1 файла}} из $2, находящихся в данной категории.}}',
 'category-file-count-limited' => 'В этой категории {{PLURAL:$1|$1 файл|$1 файлов|$1 файла|1=только один файл}}.',
 'listingcontinuesabbrev' => '(продолжение)',
 'index-category' => 'Индексируемые страницы',
@@ -1287,8 +1287,8 @@ $2
 'content-failed-to-parse' => 'Содержимое $2 не соответствует типу $1: $3.',
 'invalid-content-data' => 'Недопустимые данные',
 'content-not-allowed-here' => 'Содержимое "$1" недопустимо на странице [[$2]]',
-'editwarning-warning' => 'Переход на другую страницу может привести к потере сделанных вами изменений.
-Если вы зарегистрированы в системе, то вы можете отключить это предупреждение в разделе «Редактирование» ваших настроек.',
+'editwarning-warning' => 'Переход на другую страницу может привести к потере внесённых вами изменений.
+Если вы зарегистрированы в системе, то вы можете отключить это предупреждение в разделе «{{int:prefs-editing}}» ваших настроек.',
 'editpage-notsupportedcontentformat-title' => 'Формат содержимого не поддерживается',
 'editpage-notsupportedcontentformat-text' => 'Формат содержимого $1 не поддерживается моделью содержимого $2.',
 
@@ -1324,6 +1324,7 @@ $2
 'undo-success' => 'Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.',
 'undo-failure' => 'Правка не может быть отменена из-за несовместимости промежуточных изменений.',
 'undo-norev' => 'Правка не может быть отменена, так как её не существует или она была удалена.',
+'undo-nochange' => 'Правка, похоже, уже была отменена.',
 'undo-summary' => 'Отмена правки $1, сделанной {{GENDER:$2|участником|участницей}} [[Special:Contributions/$2|$2]] ([[User talk:$2|обс.]])',
 'undo-summary-username-hidden' => 'Отмена правки $1, сделанной участником, чьё имя скрыто',
 
index e6c8e68..5d5ac7a 100644 (file)
@@ -1034,7 +1034,7 @@ Izgleda, da je bila izbrisana.',
 'invalid-content-data' => 'Neveljavni podatki vsebine',
 'content-not-allowed-here' => 'Vsebina »$1« ni dovoljena na strani [[$2]]',
 'editwarning-warning' => 'Če zapustite stran, boste morda izgubili vse spremembe, ki ste jih naredili.
-Če ste prijavljeni, lahko to opozorilo onemogočite v razdelku »Urejanje« v svojih nastavitvah.',
+Če ste prijavljeni, lahko to opozorilo onemogočite v razdelku »{{int:prefs-editing}}« v svojih nastavitvah.',
 'editpage-notsupportedcontentformat-title' => 'Oblika vsebine ni podprta',
 'editpage-notsupportedcontentformat-text' => 'Model vsebine $2 ne podpira oblike vsebine $1.',
 
@@ -1070,6 +1070,7 @@ Naslednji argumenti so bili izpuščeni.",
 'undo-success' => 'Urejanje ste razveljavili. Prosimo, preverite prikazano primerjavo redakcij in, če ustrezajo, shranite spremembe.',
 'undo-failure' => 'Zaradi navzkrižij urejanj, ki so se vmes pojavila, tega urejanja ni moč razveljaviti.',
 'undo-norev' => 'Urejanja ni mogoče razveljaviti, ker ne obstaja ali je bilo izbrisano.',
+'undo-nochange' => 'Zdi se, da je urejanje nekdo že razveljavil.',
 'undo-summary' => 'Redakcija $1 uporabnika [[Special:Contributions/$2|$2]] ([[User talk:$2|pogovor]]) razveljavljena',
 'undo-summary-username-hidden' => 'Razveljavi redakcijo $1 skritega uporabnika',
 
index 10f41dd..dfc2630 100644 (file)
@@ -1872,7 +1872,7 @@ $1",
 {{PLURAL:$3|Пожељна врста датотеке је|Пожељне врсте датотека су}} $2.',
 'filetype-banned-type' => "'''„.$1“''' {{PLURAL:$4|је забрањена врста датотеке|су забрањене врсте датотека}}.
 {{PLURAL:$3|Дозвољена врста датотеке је|Дозвољене врсте датотека су}} $2.",
-'filetype-missing' => 'Ова датотека нема екстензију.',
+'filetype-missing' => 'Ова датотека нема екстензију (нпр. „.jpg“).',
 'empty-file' => 'Послата датотека је празна.',
 'file-too-large' => 'Послата датотека је превелика.',
 'filename-tooshort' => 'Назив датотеке је прекратак.',
index 89d847a..9c10720 100644 (file)
@@ -1746,7 +1746,7 @@ Promenite naziv datoteke i ponovo je pošaljite.',
 {{PLURAL:$3|Poželjna vrsta datoteke je|Poželjne vrste datoteka su}} $2.',
 'filetype-banned-type' => "'''„.$1“''' {{PLURAL:$4|je zabranjena vrsta datoteke|su zabranjene vrste datoteka}}.
 {{PLURAL:$3|Dozvoljena vrsta datoteke je|Dozvoljene vrste datoteka su}} $2.",
-'filetype-missing' => 'Ova datoteka nema ekstenziju.',
+'filetype-missing' => 'Ova datoteka nema ekstenziju (npr. „.jpg“).',
 'empty-file' => 'Poslata datoteka je prazna.',
 'file-too-large' => 'Poslata datoteka je prevelika.',
 'filename-tooshort' => 'Naziv datoteke je prekratak.',
index fe6e02f..91924ef 100644 (file)
@@ -1155,7 +1155,7 @@ Den finns redan.',
 'invalid-content-data' => 'Ogiltig innehållsdata',
 'content-not-allowed-here' => 'innehåll av "$1" är inte tillåtet på sidan [[$2]]',
 'editwarning-warning' => 'Om du lämnar den här sidan kommer du att förlora alla ändringar du har gjort.
-Om du är inloggad kan du slå av den här varningen under "Redigering" i dina inställningar.',
+Om du är inloggad kan du slå av den här varningen under "{{int:prefs-editing}}" i dina inställningar.',
 'editpage-notsupportedcontentformat-title' => 'Innehållsformat stöds inte',
 'editpage-notsupportedcontentformat-text' => 'Innehållsformatet $1 stöds inte av innehållsmodellen $2.',
 
@@ -1374,6 +1374,8 @@ Se till att sidhistorikens kontinuitet behålls när du sammanfogar historik.',
 'showhideselectedversions' => 'Visa/dölj valda versioner',
 'editundo' => 'gör ogjord',
 'diff-empty' => '(Ingen skillnad)',
+'diff-multi-sameuser' => '({{PLURAL:$1|En mellanliggande version|$1 mellanliggande versioner}} av samma användare visas inte)',
+'diff-multi-otherusers' => '({{PLURAL:$1|En mellanliggande version|$1 mellanliggande versioner}} av {{PLURAL:$2|en annan användare|$2 användare}} visas inte)',
 'diff-multi-manyusers' => '({{PLURAL:$1|En mellanliggande version|$1 mellanliggande versioner}} av mer än $2 användare visas inte)',
 'difference-missing-revision' => '{{PLURAL:$2|En revision|$2 revisioner}} av denna skillnad ($1) kunde inte hittas.
 
@@ -2428,7 +2430,7 @@ Framtida ändringar av den här sidan och dess diskussionssida kommer att listas
 'watchmethod-list' => 'letar efter nyligen gjorda ändringar bland bevakade sidor',
 'watchlistcontains' => 'Din bevakningslista innehåller $1 {{PLURAL:$1|sida|sidor}}.',
 'iteminvalidname' => "Problem med ''$1'', ogiltigt namn...",
-'wlnote2' => 'Nedan finns de senaste $1 ändringarna under {{PLURAL:$1|den senaste timmen|de senaste <strong>$2</strong> timmarna}} från den $3 kl. $4.',
+'wlnote2' => 'Nedan finns ändringarna från {{PLURAL:$1|den senaste timmen|de senaste <strong>$1</strong> timmarna}}, med början den $2 kl. $3.',
 'wlshowlast' => 'Visa senaste $1 timmarna $2 dygnen $3',
 'watchlist-options' => 'Alternativ för bevakningslistan',
 
index dc31f48..e726387 100644 (file)
@@ -967,7 +967,7 @@ $2
 'invalid-content-data' => 'తప్పుడు విషయం',
 'content-not-allowed-here' => '[[$2]] పేజీలో పాఠ్యం "$1" కి అనుమతి లేదు',
 'editwarning-warning' => 'ఈ పేజీని వదిలివెళ్ళడం వల్ల మీరు చేసిన మార్పులను కోల్పోయే అవకాశం ఉంది.
-à°®à±\80à°°à±\81 à°ªà±\8dà°°à°µà±\87శిà°\82à°\9aà°¿à°µà±\81à°\82à°\9fà±\87, à°\88 à°¹à±\86à°\9aà±\8dà°\9aà°°à°¿à°\95ని à°®à±\80 à°\85à°­à°¿à°°à±\81à°\9aà±\81లలà±\8b "మరపà±\81à°²à±\81" à°\85à°¨à±\87 విభాగంలో అచేతనం చేసుకోవచ్చు.',
+à°®à±\80à°°à±\81 à°²à°¾à°\97à°¿à°¨à±\8d à°\85యివà±\81à°\82à°\9fà±\87, à°\88 à°¹à±\86à°\9aà±\8dà°\9aà°°à°¿à°\95ని à°®à±\80 à°\85à°­à°¿à°°à±\81à°\9aà±\81లలà±\8bని "{{int:prefs-editing}}"  విభాగంలో అచేతనం చేసుకోవచ్చు.',
 'editpage-notsupportedcontentformat-title' => 'పాఠ్యపు ఆకృతికి మద్దతు లేదు',
 'editpage-notsupportedcontentformat-text' => '$2 పాఠ్యపు మోడల్, పాఠ్యపు ఆకృతి $1 కి మద్దతు ఇవ్వదు',
 
@@ -997,6 +997,7 @@ $2
 'undo-failure' => 'మధ్యలో జరిగిన దిద్దుబాట్లతో తలెత్తిన ఘర్షణ కారణంగా ఈ దిద్దుబాటును రద్దు చెయ్యలేక పోయాం.',
 'undo-norev' => 'ఈ దిద్దుబాటును అసలు లేకపోవటం వలన, లేదా తొలగించేయడం వలన రద్దుచేయలేకపోతున్నాం.',
 'undo-summary' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|చర్చ]]) దిద్దుబాటు చేసిన కూర్పు $1 ను రద్దు చేసారు',
+'undo-summary-username-hidden' => 'దాచబడిన వాడుకరి చేసిన కూర్పు $1 ని వెనక్కి తిప్పండి',
 
 # Account creation failure
 'cantcreateaccounttitle' => 'ఈ ఖాతా తెరవలేము',
@@ -1439,7 +1440,7 @@ $1",
 'right-hideuser' => 'ప్రజలకు కనబడకుండా చేసి, సభ్యనామాన్ని నిరోధించు',
 'right-ipblock-exempt' => 'ఐపీ నిరోధాలు, ఆటో నిరోధాలు, శ్రేణి నిరోధాలను తప్పించు',
 'right-proxyunbannable' => 'ప్రాక్సీల ఆటోమాటిక్ నిరోధాన్ని తప్పించు',
-'right-unblockself' => 'వారినà±\87 à°\85నిరà±\8bధిà°\82à°\9aà±\81à°\95à±\8bవడం',
+'right-unblockself' => 'à°¸à±\8dà°µà±\80à°¯ à°\85నిరà±\8bà°§ం',
 'right-protect' => 'సంరక్షణ స్థాయిలను మార్చు, సంరక్షిత పేజీలలో దిద్దుబాటు చెయ్యి',
 'right-editprotected' => '"{{int:protect-level-sysop}}" గా సంక్షించబడిన పేజీలను సరిదిద్దు',
 'right-editsemiprotected' => '"{{int:protect-level-autoconfirmed}}" గా సంరక్షించబడ్డ పేజీలను మార్చు',
@@ -1700,13 +1701,29 @@ $1',
 'upload-http-error' => 'ఒక HTTP పొరపాటు జరిగింది: $1',
 
 # File backend
+'backend-fail-stream' => '"$1" ఫైలును స్ట్రీమింగు చెయ్యలేకపోయాం.',
+'backend-fail-backup' => '"$1" ఫైలును బ్యాకప్పు చెయ్యలేకపోయాం.',
 'backend-fail-notexists' => '$1 ఫైలు అసలు లేనేలేదు.',
+'backend-fail-hashes' => 'పోలిక కోసం ఫైలు హాష్‍లను పొందలేకపోయాం.',
+'backend-fail-notsame' => 'సరిగ్గా సరిపోయే ఫైలు కాదు గానీ, ఒక ఫైలు ఈసరికే "$1" వద్ద ఉంది.',
+'backend-fail-invalidpath' => '"$1" సరైన స్టోరేజి పాత్ కాదు',
 'backend-fail-delete' => '$1 ఫైలును తొలగించలేకున్నాం.',
+'backend-fail-describe' => '"$1" ఫైలు మెటాడేటాను మార్చలేకపోయాం.',
 'backend-fail-alreadyexists' => '$1 అనే దస్త్రం ఇప్పటికే ఉంది.',
+'backend-fail-store' => '"$1" ఫైలును "$2" వద్ద భద్రపరచలేకపోయాం.',
+'backend-fail-copy' => '"$1" నుండి "$2" కి ఫైలును కాపీ చెయ్యలేకపోయాం.',
+'backend-fail-move' => '"$1" నుండి "$2" కి ఫైలును తరలించలేకపోయాం.',
 'backend-fail-opentemp' => 'తాత్కాలిక దస్త్రాన్ని తెరవలేకపోతున్నాం.',
+'backend-fail-writetemp' => 'తాత్కాలిక ఫైలులో రాయలేకపోయాం.',
 'backend-fail-closetemp' => 'తాత్కాలిక దస్త్రాన్ని మూసివేయలేకపోయాం.',
 'backend-fail-read' => '$1 దస్త్రము చదువలేకపోతిమి.',
 'backend-fail-create' => '$1 ఫైలులో రాయలేకున్నాం.',
+'backend-fail-maxsize' => '"$1" ఫైలు {{PLURAL:$2|ఒక బైట్|$2 బైట్ల}} కంటే పెద్దది కావడం చేత దాన్ని రాయలేకపోయాం.',
+'backend-fail-readonly' => 'స్టోరేజి బ్యాక్‍ఎండ్ "$1" ప్రస్తుతం రీడ్-ఓన్లీ స్థితిలో ఉంది. దానికి కారణం: "<em>$2</em>"',
+'backend-fail-connect' => 'స్టోరేజీ బ్యాక్‍ఎండ్ "$1" కి కనెక్టు కాలేక పోయాం.',
+'backend-fail-internal' => 'స్టోరేజీ బ్యాక్‍ఎండ్ "$1" లో ఏదో తెలియని లోపం దొర్లింది.',
+'backend-fail-contenttype' => '"$1" లో దాచాల్సిన ఫైలు యొక్క కంటెంటు రకమేంటో నిర్ధారించలేకపోయాం.',
+'backend-fail-batchsize' => 'స్టోరేజీ బ్యాక్‍ఎండ్ కు $1 ఫైలు {{PLURAL:$1|ఆపరేషన్|ఆపరేషన్ల}} తో కూడిన బ్యాచ్ ఒకటి ఇవ్వబడింది; పరిమితి: $2 {{PLURAL:$2|ఆపరేషన్|ఆపరేషన్లు}}.',
 
 # ZipDirectoryReader
 'zip-file-open-error' => 'ఈ ఫైలును ZIP పరీక్ష కోసం తెరవబోతే, ఏదో తెలియని లోపం ఎదురైంది.',
@@ -1929,6 +1946,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'ninterwikis' => '$1 {{PLURAL:$1|అంతర్వికీ|అంతర్వికీలు}}',
 'nlinks' => '$1 {{PLURAL:$1|లింకు|లింకులు}}',
 'nmembers' => '{{PLURAL:$1|ఒక ఉపవర్గం/పేజీ/ఫైలు|$1 ఉపవర్గాలు/పేజీలు/ఫైళ్లు}}',
+'nmemberschanged' => '$1 → $2 {{PLURAL:$2|సభ్యుడు|సభ్యులు}}',
 'nrevisions' => '{{PLURAL:$1|ఒక సంచిక|$1 సంచికలు}}',
 'nviews' => '$1 {{PLURAL:$1|దర్శనము|దర్శనలు}}',
 'nimagelinks' => '$1 {{PLURAL:$1|పుట|పుటల}}లో ఉపయోగించారు',
@@ -1953,9 +1971,11 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'mostlinkedtemplates' => 'ఎక్కువగా ఉపయోగించిన మూసలు',
 'mostcategories' => 'అధిక వర్గాలలో చేరిన వ్యాసాలు',
 'mostimages' => 'అధిక లింకులు గల బొమ్మలు',
+'mostinterwikis' => 'అత్యధిక అంతరవికీ లింకులు కలిగిన పేజీలు',
 'mostrevisions' => 'అధిక సంచికలు గల వ్యాసాలు',
 'prefixindex' => 'ఉపసర్గతో అన్ని పేజీలు',
 'prefixindex-namespace' => 'ఉపసర్గతో ఉన్న పేజీలు ($1 పేరుబరి)',
+'prefixindex-strip' => 'జాబితాలో ఆదిపదాన్ని తీసివేయి',
 'shortpages' => 'చిన్న పేజీలు',
 'longpages' => 'పొడవు పేజీలు',
 'deadendpages' => 'అగాధ (డెడ్ఎండ్) పేజీలు',
@@ -1963,12 +1983,14 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'protectedpages' => 'సంరక్షిత పేజీలు',
 'protectedpages-indef' => 'అనంత సంరక్షణ మాత్రమే',
 'protectedpages-cascade' => 'కాస్కేడింగు రక్షణలు మాత్రమే',
+'protectedpages-noredirect' => 'దారిమార్పులను దాచు',
 'protectedpagesempty' => 'ఈ పరామితులతో ప్రస్తుతం ఏ పేజీలు కూడా సంరక్షించబడి లేవు.',
 'protectedtitles' => 'సంరక్షిత శీర్షికలు',
 'protectedtitlesempty' => 'ఈ పరామితులతో ప్రస్తుతం శీర్షికలేమీ సరక్షించబడి లేవు.',
 'listusers' => 'వాడుకరుల జాబితా',
 'listusers-editsonly' => 'మార్పులు చేసిన వాడుకరులను మాత్రమే చూపించు',
 'listusers-creationsort' => 'చేరిన తేదీ క్రమంలో చూపించు',
+'listusers-desc' => 'అవోహణ క్రమంలో పేర్చు',
 'usereditcount' => '$1 {{PLURAL:$1|మార్పు|మార్పులు}}',
 'usercreated' => '$1 న $2కి {{GENDER:$3|చేరారు}}',
 'newpages' => 'కొత్త పేజీలు',
@@ -2045,7 +2067,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'linksearch-pat' => 'వెతకాల్సిన నమూనా:',
 'linksearch-ns' => 'పేరుబరి:',
 'linksearch-ok' => 'వెతుకు',
-'linksearch-text' => '"*.wikipedia.org" వంటి వైల్డ్ కార్డులు వాడవచ్చు.<br />ఉపయోగించుకోగల ప్రోటోకాళ్లు: <code>$1</code>',
+'linksearch-text' => '"*.wikipedia.org" వంటి వైల్డ్ కార్డులు వాడవచ్చు. కనీసం ఒక్కటైనా టాప్ లెవెల్ డొమెయిన్ ఉండాలి. ఉదా: "*.org".<br />ఉపయోగించుకోగల {{PLURAL:$2|ప్రోటోకోల్|ప్రోటోకోళ్లు}}: <code>$1</code> (ఏ ప్రోటోకోలునూ ఇవ్వకపోతే, http:// ను వాడబడుతుంది)',
 'linksearch-line' => '$2 నుండి $1కి లింకు ఉంది',
 'linksearch-error' => 'హోస్ట్‌నేముకు ముందు మాత్రమే వైల్డ్ కార్డులు వాడవచ్చు.',
 
@@ -2091,7 +2113,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'emailuser-title-target' => 'ఈ {{GENDER:$1|వాడుకరికి}} ఈమెయిలు పంపించండి',
 'emailuser-title-notarget' => 'ఈ-మెయిలు వాడుకరి',
 'emailpage' => 'వాడుకరికి ఈ-మెయిలుని పంపించు',
-'emailpagetext' => 'వాడà±\81à°\95à°°à°¿à°\95à°¿ ఈమెయిలు సందేశము పంపించుటకు క్రింది ఫారంను ఉపయోగించవచ్చు. [[Special:Preferences|మీ వాడుకరి అభిరుచుల]]లో మీరిచ్చిన ఈ-మెయిలు చిరునామా "నుండి" ఆ సందేశం వచ్చినట్లుగా ఉంటుంది, కనుక వేగుని అందుకునేవారు నేరుగా మీకు జవాబివ్వగలుగుతారు.',
+'emailpagetext' => 'à°\88 {{GENDER:$1|వాడà±\81à°\95à°°à°¿à°\95à°¿}} ఈమెయిలు సందేశము పంపించుటకు క్రింది ఫారంను ఉపయోగించవచ్చు. [[Special:Preferences|మీ వాడుకరి అభిరుచుల]]లో మీరిచ్చిన ఈ-మెయిలు చిరునామా "నుండి" ఆ సందేశం వచ్చినట్లుగా ఉంటుంది, కనుక వేగుని అందుకునేవారు నేరుగా మీకు జవాబివ్వగలుగుతారు.',
 'usermailererror' => 'మెయిలు ఆబ్జెక్టు ఈ లోపాన్ని చూపింది:',
 'defemailsubject' => 'వాడుకరి "$1" నుండి {{SITENAME}} ఈ-మెయిలు',
 'usermaildisabled' => 'వాడుకరి ఈ-మెయిళ్ళు అచేతనం చేసారు',
@@ -2129,8 +2151,8 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'watchnologin' => 'లాగిన్‌ అయిలేరు',
 'watchnologintext' => 'మీ వీక్షణ జాబితాను మార్చడానికి మీరు [[Special:UserLogin|లాగిన్‌]] అయి ఉండాలి.',
 'addwatch' => 'వీక్షణ జాబితాలో చేర్చు',
-'addedwatchtext' => "\"[[:\$1]]\" అనే పుట మీ [[Special:Watchlist|వీక్షణ జాబితా]]లో చేరింది.
-భవిష్యత్తులో ఈ పుటకి మరియు సంబంధిత చర్చాపుటకి జరిగే మార్పులు అక్కడ కనిపిస్తాయి, మరియు  [[Special:RecentChanges|ఇటీవలి మార్పుల జాబితా]]లో సులభంగా గుర్తించడానికి ఈ పుట '''బొద్దుగా''' కనిపిస్తుంది.",
+'addedwatchtext' => '"[[:$1]]" అనే పుట మీ [[Special:Watchlist|వీక్షణ జాబితా]]లో చేరింది.
+భవిష్యత్తులో ఈ పుటకి మరియు సంబంధిత చర్చాపుటకి జరిగే మార్పులు అక్కడ కనిపిస్తాయి.',
 'removewatch' => 'వీక్షణ జాబితా నుండి తొలగించు',
 'removedwatchtext' => '"[[:$1]]" అనే పేజీ [[Special:Watchlist|మీ వీక్షణ జాబితా]] నుండి తొలగించబడినది.',
 'watch' => 'వీక్షించు',
@@ -2140,12 +2162,13 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'notanarticle' => 'వ్యాసం పేజీ కాదు',
 'notvisiblerev' => 'ఈ కూర్పును తొలగించాం',
 'watchlist-details' => 'మీ వీక్షణ జాబితాలో {{PLURAL:$1|ఒక పేజీ ఉంది|$1 పేజీలు ఉన్నాయి}}, చర్చా పేజీలని వదిలేసి.',
-'wlheader-enotif' => 'à°\88-à°®à±\86యిలà±\81 à°ªà±\8dà°°à°\95à°\9fà°¨లు పంపబడతాయి.',
-'wlheader-showupdated' => "మీ గత సందర్శన తరువాత మారిన పేజీలు '''బొద్దు'''గా చూపించబడ్డాయి.",
+'wlheader-enotif' => 'à°\88-à°®à±\86యిలà±\81 à°\97మనిà°\95లు పంపబడతాయి.',
+'wlheader-showupdated' => 'మీ గత సందర్శన తరువాత మారిన పేజీలు <strong>బొద్దు</strong>గా చూపించబడ్డాయి.',
 'watchmethod-recent' => 'వీక్షణ జాబితాలోని పేజీల కొరకు ఇటీవలి మార్పులు పరిశీలించబడుతున్నాయి',
 'watchmethod-list' => 'ఇటీవలి మార్పుల కొరకు వీక్షణ జాబితాలోని పేజీలు పరిశీలించబడుతున్నాయి',
 'watchlistcontains' => 'మీ వీక్షణ జాబితాలో {{PLURAL:$1|ఒక పేజీ ఉంది|$1 పేజీలు ఉన్నాయి}}.',
 'iteminvalidname' => "'$1' తో ఇబ్బంది, సరైన పేరు కాదు...",
+'wlnote2' => '$2, $3 సమయానికి, గత {{PLURAL:$1|గంటలో|<strong>$1</strong> గంటల్లో}}, జరిగిన మార్పులు కింద ఇవ్వబడ్డాయి.',
 'wlshowlast' => 'గత $1 గంటలు $2 రోజులు $3 చూపించు',
 'watchlist-options' => 'వీక్షణ జాబితా ఎంపికలు',
 
@@ -2476,6 +2499,7 @@ $1',
 'blocklist-userblocks' => 'ఖాతా నిరోధాలను దాచు',
 'blocklist-tempblocks' => 'తాత్కాలిక నిరోధాలను దాచు',
 'blocklist-addressblocks' => 'ఏకైక ఐపీ నిరోధాలను దాచు',
+'blocklist-rangeblocks' => 'శ్రేణి నిరోధకాలను దాచు',
 'blocklist-timestamp' => 'కాలముద్ర',
 'blocklist-target' => 'గమ్యం',
 'blocklist-expiry' => 'కాలం చేల్లేది',
@@ -2507,7 +2531,9 @@ $1',
 వివరాల కోసం అణచివేత చిట్టా కింద చూపబడింది:',
 'blocklogentry' => '"[[$1]]" పై నిరోధం అమలయింది. నిరోధ కాలం $2 $3',
 'reblock-logentry' => '[[$1]] కై నిరోధపు అమరికలను $2 $3 గడువుతో మార్చారు',
-'blocklogtext' => 'వాడుకరుల నిరోధాలు, పునస్థాపనల చిట్టా ఇది. ఆటోమాటిక్‌గా నిరోధానికి గురైన ఐ.పి. చిరునామాలు ఈ జాబితాలో ఉండవు. ప్రస్తుతం అమల్లో ఉన్న నిరోధాలు, నిషేధాల కొరకు [[Special:BlockList|ఐ.పి. నిరోధాల జాబితా]]ను చూడండి.',
+'blocklogtext' => 'వాడుకరుల నిరోధాలు, పునస్థాపనల చిట్టా ఇది. 
+ఆటోమాటిక్‌గా నిరోధానికి గురైన ఐ.పి. చిరునామాలు ఈ జాబితాలో ఉండవు. 
+ప్రస్తుతం అమల్లో ఉన్న నిరోధాలు, నిషేధాల కొరకు [[Special:BlockList|నిరోధాల జాబితా]]ను చూడండి.',
 'unblocklogentry' => '$1పై నిరోధం తొలగించబడింది',
 'block-log-flags-anononly' => 'అజ్ఞాత వాడుకర్లు మాత్రమే',
 'block-log-flags-nocreate' => 'ఖాతా సృష్టించడాన్ని అశక్తం చేసాం',
@@ -2519,7 +2545,7 @@ $1',
 'range_block_disabled' => 'శ్రేణి(రేంజి) నిరోధం చెయ్యగల నిర్వాహక అనుమతిని అశక్తం చేసాం.',
 'ipb_expiry_invalid' => 'అంతమయ్యే గడువు సరైనది కాదు.',
 'ipb_expiry_temp' => 'దాచిన వాడుకరిపేరు నిరోధాలు శాశ్వతంగా ఉండాలి.',
-'ipb_hide_invalid' => 'à°\88 à°\96ాతానà±\81 à°\85à°£à°\9aà°²à±\87à°\95à°ªà±\8bà°¤à±\81à°¨à±\8dనాà°\82. à°¦à°¾à°¨à°¿ à°\95à°¿à°\82à°¦ à°\9aాలా à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\8dà°²à±\81 à°\89à°\82à°¡à°¿ à°\89à°\82à°\9fాయి.',
+'ipb_hide_invalid' => 'à°\88 à°\96ాతానà±\81 à°\85à°£à°\9aà°²à±\87à°\95à°ªà±\8bà°¤à±\81à°¨à±\8dనాà°\82. à°¦à°¾à°¨à°¿ à°\96ాతాలà±\8b {{PLURAL:$1|à°\92à°\95à°\9fà°¿ à°\95à°\82à°\9fà±\87|$1 à°\95à°\82à°\9fà±\87}} à°\8eà°\95à±\8dà°\95à±\81à°µ à°¦à°¿à°¦à±\8dà°¦à±\81బాà°\9fà±\8dà°²à±\81 à°\89à°¨à±\8dà°¨ాయి.',
 'ipb_already_blocked' => '"$1" ను ఇప్పటికే నిరోధించాం',
 'ipb-needreblock' => '$1ని ఇప్పటికే నిరోధించారు. ఆ అమరికలని మీరు మార్చాలనుకుంటున్నారా?',
 'ipb-otherblocks-header' => 'ఇతర {{PLURAL:$1|నిరోధం|నిరోధాలు}}',
@@ -2653,6 +2679,7 @@ $1',
 పేజీలను ఎగుమతి చేసందుకు, కింద ఇచ్చిన టెక్స్టు బాక్సులో పేజీ పేర్లను లైనుకో పేరు చొప్పున ఇవ్వండి. ప్రస్తుత కూర్పుతో పాటు పాత కూర్పులు కూడా కావాలా, లేక ప్రస్తుత కూర్పు మాత్రమే చాలా అనే విషయం కూడా ఇవ్వవచ్చు.
 
 రెండో పద్ధతిలో అయితే, పేజీ యొక్క లింకును కూడా వాడవచ్చు. ఉదాహరణకు, "[[{{MediaWiki:Mainpage}}]]" కోసమైతే [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] అని ఇవ్వవచ్చు.',
+'exportall' => 'పేజీలన్నిటినీ ఎగుమతి చెయ్యి',
 'exportcuronly' => 'ప్రస్తుత కూర్పు మాత్రమే, పూర్తి చరితం వద్దు',
 'exportnohistory' => "----
 '''గమనిక:''' ఈ ఫారాన్ని ఉపయోగించి పేజీలయొక్క పూర్తి చరిత్రను ఎగుమతి చేయడాన్ని సర్వరుపై వత్తిడి పెరిగిన కారణంగా ప్రస్తుతం నిలిపివేశారు.",
@@ -2681,13 +2708,18 @@ $1',
 'allmessages-prefix' => 'ఉపసర్గ పై వడపోత:',
 'allmessages-language' => 'భాష:',
 'allmessages-filter-submit' => 'వెళ్ళు',
+'allmessages-filter-translate' => 'అనువదించు',
 
 # Thumbnails
 'thumbnail-more' => 'పెద్దది చెయ్యి',
 'filemissing' => 'ఫైలు కనపడుటలేదు',
 'thumbnail_error' => '$1: నఖచిత్రం తయారుచెయ్యడంలో లోపం జరిగింది',
+'thumbnail_error_remote' => '$1 నుండి వచ్చిన లోప సందేశం:
+$2',
 'djvu_page_error' => 'DjVu పేజీ రేంజి దాటిపోయింది',
 'djvu_no_xml' => 'DjVu ఫైలు కోసం XMLను తీసుకుని రాలేకపోయాను',
+'thumbnail-temp-create' => 'తాత్కాలిక థంబ్‍నెయిల్ ఫైలును సృష్టించలేకపోయాం',
+'thumbnail-dest-create' => 'థంబ్‍నెయిలును గమ్యస్థానంలో భద్రపరచలేకపోయాం',
 'thumbnail_invalid_params' => 'నఖచిత్రాలకు సరయిన పారామీటర్లు లేవు',
 'thumbnail_dest_directory' => 'గమ్యస్థానంలో డైరెక్టరీని సృష్టించలేకపోయాం',
 'thumbnail_image-type' => 'ఈ బొమ్మ రకానికి మద్దతు లేదు',
@@ -2705,6 +2737,7 @@ $1',
 'import-interwiki-templates' => 'అన్ని మూసలను ఉంచు',
 'import-interwiki-submit' => 'దిగుమతించు',
 'import-interwiki-namespace' => 'లక్ష్యిత నేంస్పేసు:',
+'import-interwiki-rootpage' => 'గమ్యస్థానపు మూలపు పేజీ (ఐచ్ఛికం):',
 'import-upload-filename' => 'పైలుపేరు:',
 'import-comment' => 'వ్యాఖ్య:',
 'importtext' => '[[Special:Export|ఎగుమతి ఉపకరణాన్ని]] ఉపయోగించి, ఈ ఫైలుని  మూల వికీ నుంచి ఎగుమతి చెయ్యండి.
@@ -2728,11 +2761,18 @@ $1',
 'importuploaderrortemp' => 'దిగుమతి ఫైలు అప్లోడు ఫలించలేదు. ఒక తాత్కాలిక ఫోల్డరు కనిపించటం లేదు.',
 'import-parse-failure' => 'దిగుమతి చేసుకుంటున్న XML విశ్లేషణ ఫలించలేదు',
 'import-noarticle' => 'దిగుమతి చెయ్యాల్సిన పేజీ లేదు!',
-'import-nonewrevisions' => 'à°\85à°¨à±\8dని à°\95à±\82à°°à±\8dà°ªà±\81à°²à±\82 à°\97à°¤à°\82à°²à±\8bà°¨à±\87 à°¦à°¿à°\97à±\81మతయà±\8dయాయి.',
+'import-nonewrevisions' => 'à°\95à±\82à°°à±\8dà°ªà±\81à°²à±\87à°µà±\80 à°¦à°¿à°\97à±\81మతి à°\95ాలà±\87à°¦à±\81 (à°\85వనà±\8dà°¨à±\80 à°\88సరిà°\95à±\87 à°\89à°\82à°¡à°¿ à°\89à°\82డాలి, à°²à±\87దా à°²à±\8bపాల à°\95ారణà°\82à°\97à°¾ à°µà°¦à°¿à°²à±\86à°¯à±\8dయబడà±\8dడాయి).',
 'xml-error-string' => '$1 $2వ లైనులో, వరుస $3 ($4వ బైటు): $5',
 'import-upload' => 'XML డేటాను అప్‌లోడు చెయ్యి',
 'import-token-mismatch' => 'సెషను భోగట్టా పోయింది. దయచేసి మళ్ళీ ప్రయత్నించండి.',
 'import-invalid-interwiki' => 'మీరు చెప్పిన వికీనుండి దిగుమతి చేయలేము.',
+'import-error-edit' => 'పేజీ "$1" లో మార్పుచేర్పులు చేసే అనుమతి మీకు లేదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-error-create' => 'పేజీ "$1" ను సృష్టించే అనుమతి మీకు లేదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-error-interwiki' => 'పేజీ "$1" యొక్క పేరు బయటి లింకుల (అంతరవికీ) కోసం అట్టేపెట్టబడింది కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-error-special' => 'పేజీ "$1" ప్రత్యేక పేరుబరికి చెందినది. ఈ పేరుబరిలో పేజీలు సృష్టించే అనుమతి లేదు. అందుచేత దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-error-invalid' => 'పేజీ "$1" పేరు సరైనది కాదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.',
+'import-options-wrong' => 'తప్పు {{PLURAL:$2|ఐచ్ఛికం|ఐచ్ఛికాలు}}: <nowiki>$1</nowiki>',
+'import-rootpage-invalid' => 'ఇచ్చిన మూలపు పేజీ సరైన శీర్షిక కాదు.',
 
 # Import log
 'importlogpage' => 'దిగుమతుల చిట్టా',
@@ -2841,12 +2881,36 @@ $1',
 
 # Info page
 'pageinfo-title' => '"$1" గురించి సమాచారం',
+'pageinfo-not-current' => 'పాత కూర్పులకు సంబంధించి ఈ సమాచారాన్ని ఇవ్వడం అసాధ్యం, సారీ.',
 'pageinfo-header-basic' => 'ప్రాథమిక సమాచారం',
 'pageinfo-header-edits' => 'మార్పుల చరిత్ర',
+'pageinfo-header-restrictions' => 'పేజీ సంరక్షణ',
+'pageinfo-header-properties' => 'పేజీ లక్షణాలు',
+'pageinfo-display-title' => 'శీర్షిక చూపించు',
+'pageinfo-length' => 'పేజీ నిడివి (బైట్లలో)',
+'pageinfo-article-id' => 'పేజీ ఐడీ',
+'pageinfo-language' => 'పేజీ విషయపు భాష',
+'pageinfo-robot-index' => 'అనుమతించబడింది',
+'pageinfo-robot-noindex' => 'అనుమతించబడలేదు',
 'pageinfo-views' => 'వీక్షణల సంఖ్య',
 'pageinfo-watchers' => 'పేజీ వీక్షకుల సంఖ్య',
+'pageinfo-few-watchers' => '$1 {{PLURAL:$1|వీక్షకుడి|వీక్షకుల}} కంటే తక్కువ',
+'pageinfo-redirects-name' => 'ఈ పేజీకి ఉన్న దారిమార్పుల సంఖ్య',
+'pageinfo-subpages-name' => 'ఈ పేజీకి ఉన్న ఉపపేజీల సంఖ్య',
+'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|దారిమార్పు|దారిమార్పులు}}; $3 {{PLURAL:$3|దారిమార్పు కానిది|దారిమార్పు కానివి}})',
+'pageinfo-firstuser' => 'పేజీ సృష్టికర్త',
+'pageinfo-firsttime' => 'పేజీని సృష్టించిన తేదీ',
+'pageinfo-lastuser' => 'ఇట్టీవలి మార్పుచేర్పుల కర్త',
+'pageinfo-lasttime' => 'చివరిసారిగా మార్పు చేసిన తేదీ',
 'pageinfo-edits' => 'మొత్తం మార్పుల సంఖ్య',
+'pageinfo-recent-edits' => 'ఇటీవలి మార్పుల సంఖ్య (గత $1 లోపు)',
+'pageinfo-magic-words' => 'చమత్కార {{PLURAL:$1|పదం|పదాలు}} ($1)',
+'pageinfo-hidden-categories' => 'దాచిన {{PLURAL:$1|వర్గం|వర్గాలు}} ($1)',
+'pageinfo-templates' => 'ట్రాన్స్‍క్లూడు చేసిన {{PLURAL:$1|మూస|మూసలు}} ($1)',
+'pageinfo-transclusions' => '($1) తో {{PLURAL:$1|పేజీ|పేజీలు}} ట్రాన్స్‍క్లూడు చెయ్యబడ్డాయి',
 'pageinfo-toolboxlink' => 'పేజీ సమాచారం',
+'pageinfo-redirectsto' => 'ఇక్కడికి దారిమార్పు:',
+'pageinfo-redirectsto-info' => 'సమాచారం',
 'pageinfo-contentpage-yes' => 'అవును',
 'pageinfo-protect-cascading-yes' => 'అవును',
 'pageinfo-category-info' => 'వర్గపు సమాచారం',
@@ -2870,6 +2934,7 @@ $1',
 'markedaspatrollederror' => 'నిఘాలో ఉన్నట్లుగా గుర్తించలేకున్నాం',
 'markedaspatrollederrortext' => 'నిఘాలో ఉన్నట్లు గుర్తించేందుకుగాను, కూర్పును చూపించాలి.',
 'markedaspatrollederror-noautopatrol' => 'మీరు చేసిన మార్పులను మీరే నిఘాలో పెట్టలేరు.',
+'markedaspatrollednotify' => '$1 లో చేసిన ఈ మార్పు పర్యవేక్షణలో ఉన్నట్టుగా గుర్తించబడింది.',
 
 # Patrol log
 'patrol-log-page' => 'నిఘా చిట్టా',
@@ -2911,6 +2976,8 @@ $1',
 'file-info-png-looped' => 'పునరావృతమవుతుంది',
 'file-info-png-repeat' => '{{PLURAL:$1|ఒకసారి|$1 సార్లు}} ఆడించారు',
 'file-info-png-frames' => '$1 {{PLURAL:$1|ఫ్రేము|ఫ్రేములు}}',
+'file-no-thumb-animation' => '<strong>గమనిక: సాంకేతిక కారణాల వల్ల, ఈ ఫైలు యొక్క థంబ్‍నెయిళ్ళు యానిమేటు చెయ్యబడవు.</strong>',
+'file-no-thumb-animation-gif' => '<strong>గమనిక: సాంకేతిక కారణాల వల్ల, ఇలాంటి అధిక రిసొల్యూషన్ కలిగిన బొమ్మలు యానిమేటు చెయ్యబడవు.</strong>',
 
 # Special:NewFiles
 'newimages' => 'కొత్త ఫైళ్ళ కొలువు',
@@ -3124,6 +3191,7 @@ $1',
 'exif-lens' => 'వాడిన కటకం',
 'exif-serialnumber' => 'కెమేరా యొక్క సీరియల్ నంబర్',
 'exif-cameraownername' => 'కేమెరా యజమాని',
+'exif-label' => 'సూచిక (లేబెల్)',
 'exif-rating' => 'రేటింగు (5 కి గాను)',
 'exif-rightscertificate' => 'హక్కుల నిర్వాహణ ధృవీకరణ పత్రం',
 'exif-copyrighted' => 'కాపీహక్కుల స్థితి',
@@ -3619,6 +3687,7 @@ $5
 'htmlform-selectorother-other' => 'ఇతర',
 'htmlform-no' => 'కాదు',
 'htmlform-yes' => 'అవును',
+'htmlform-chosen-placeholder' => 'ఒక ఐచ్ఛికాన్ని ఎంచుకోండి',
 
 # SQLite database support
 'sqlite-has-fts' => '$1 పూర్తి-పాఠ్య అన్వేషణ తోడ్పాటుతో',
@@ -3626,27 +3695,43 @@ $5
 
 # New logging system
 'logentry-delete-delete' => '$1 $3 పేజీని {{GENDER:$2|తొలగించారు}}',
+'logentry-delete-restore' => 'పేజీ $3 ని $1 {{GENDER:$2|పునస్థాపించారు}}',
+'logentry-delete-event' => '$3 లో {{PLURAL:$5|ఒక లాగ్ ఘటన|$5 లాగ్ ఘటనల}} యొక్క కన్పట్టటాన్ని (విజిబిలిటీ) $1 {{GENDER:$2|మార్చారు}}: $4',
+'logentry-delete-revision' => 'పేజీ $3 లో {{PLURAL:$5|ఒక కూర్పు|$5 కూర్పుల}} యొక్క కన్పట్టటాన్ని (విజిబిలిటీ) $1 {{GENDER:$2|మార్చారు}}: $4',
+'logentry-delete-event-legacy' => '$3 లో లాగ్ ఘటనల కన్పట్టటాన్ని (విజిబిలిటీ) $1 {{GENDER:$2|మార్చారు}}',
+'logentry-delete-revision-legacy' => 'పేజీ $3 లో కూర్పుల కన్పట్టటాన్ని (విజిబిలిటీ) $1 {{GENDER:$2|మార్చారు}}',
+'logentry-suppress-delete' => 'పేజీ $3 ని $1 {{GENDER:$2|అణచిపెట్టారు}}',
 'revdelete-content-hid' => 'కంటెంట్ దాచబడింది',
 'revdelete-summary-hid' => 'మార్పుల సారాంశాన్ని దాచారు',
 'revdelete-uname-hid' => 'వాడుకరి పేరుని దాచారు',
 'revdelete-restricted' => 'నిర్వాహకులకు ఆంక్షలు విధించాను',
 'revdelete-unrestricted' => 'నిర్వాహకులకున్న ఆంక్షలను ఎత్తేశాను',
-'logentry-move-move' => '$1 $3 పేజీని $4కి తరలించారు',
-'logentry-move-move-noredirect' => '$1 $3 పేజీని $4కి దారిమార్పు లేకుండా తరలించారు',
-'logentry-move-move_redir' => '$1 $3 పేజీని $4కి దారిమార్పు ద్వారా తరలించారు',
-'logentry-move-move_redir-noredirect' => '$1 $3 పేజీని $4కి దారిమార్పు లేకుండా తరలించారు',
-'logentry-newusers-newusers' => '$1 వాడుకరి ఖాతాను సృష్టించారు',
-'logentry-newusers-create' => '$1 ఒక వాడుకరి ఖాతాను సృష్టించారు',
-'logentry-newusers-create2' => '$1  వాడుకరి ఖాతా $3ను సృష్టించారు',
-'logentry-newusers-autocreate' => '$1 ఖాతాను ఆటోమెటిగ్గా సృష్టించారు',
+'logentry-move-move' => '$1, పేజీ $3 ను $4 కు {{GENDER:$2|తరలించారు}}',
+'logentry-move-move-noredirect' => '$1, పేజీ $3 ను $4 కు దారిమార్పు లేకుండా {{GENDER:$2|తరలించారు}}',
+'logentry-move-move_redir' => '$1, పేజీ $3 ను $4 కు దారిమార్పు ద్వారా {{GENDER:$2|తరలించారు}}',
+'logentry-move-move_redir-noredirect' => '$1, పేజీ $3 ను $4 కు దారిమార్పు ద్వారా దారిమార్పును ఉంచకుండా {{GENDER:$2|తరలించారు}}',
+'logentry-patrol-patrol' => '$1, పేజీ $3 యొక్క కూర్పు $4 ను పర్యవేక్షణలో ఉన్నట్లుగా {{GENDER:$2|గుర్తు పెట్టారు}}',
+'logentry-patrol-patrol-auto' => '$1, పేజీ $3 యొక్క కూర్పు $4 ను పర్యవేక్షణలో ఉన్నట్లుగా ఆటోమాటిగ్గా {{GENDER:$2|గుర్తు పెట్టారు}}',
+'logentry-newusers-newusers' => 'వాడుకరి ఖాతా $1 ను {{GENDER:$2|సృష్టించారు}}',
+'logentry-newusers-create' => 'వాడుకరి ఖాతా $1 ను {{GENDER:$2|సృష్టించారు}}',
+'logentry-newusers-create2' => '$1 వాడుకరి ఖాతా $3 ను {{GENDER:$2|సృష్టించారు}}',
+'logentry-newusers-byemail' => '$1 వాడుకరి ఖాతా $3 ను {{GENDER:$2|సృష్టించారు}}. సంకేతపదాన్ని ఈమెయిలులో పంపించాం',
+'logentry-newusers-autocreate' => 'వాడుకరి ఖాతా $1 ను ఆటోమేటిగ్గా {{GENDER:$2|సృష్టించారు}}',
+'logentry-rights-rights' => '$1, $3 యొక్క గుంపు సభ్యత్వాన్ని $4 నుండి $5 కు {{GENDER:$2|మార్చారు}}',
+'logentry-rights-rights-legacy' => '$1, $3 యొక్క గుంపు సభ్యత్వాన్ని {{GENDER:$2|మార్చారు}}',
+'logentry-rights-autopromote' => '$1, $4 నుండి $5 కు ఆటోమేటిగ్గా {{GENDER:$2|ప్రమోటు చెయ్యబడ్డారు}}',
 'rightsnone' => '(ఏమీలేవు)',
 
 # Feedback
+'feedback-bugornote' => 'ఏదైనా సాంకేతిక సమస్యను మీరు వివరించదలిస్తే [$1 లోపంపై ఫిర్యాదు చెయ్యండి].
+లేదంటే, కింద ఉన్న సులువైన ఫారాన్ని వాడండి. మీ వ్యాఖ్య మీ వాడుకరిపేరుతో సహా  "[$3 $2]" పేజీలో చేర్చబడుతుంది.',
 'feedback-subject' => 'విషయం:',
 'feedback-message' => 'సందేశం:',
 'feedback-cancel' => 'రద్దుచేయి',
 'feedback-submit' => 'ప్రతిస్పందనను దాఖలుచేయి',
+'feedback-adding' => 'ఫీడ్‍బ్యాకును పేజీలోకి చేరుస్తున్నాం...',
 'feedback-error2' => 'దోషము: సవరణ విఫలమైంది',
+'feedback-error3' => 'లోపం: API నుండి ప్రతిస్పందన లేదు',
 'feedback-thanks' => 'కృతజ్ఞతలు! మీ ప్రతిస్పందనను “[$2 $1]” పేజీలో చేర్చాం.',
 'feedback-close' => 'పూర్తయ్యింది',
 'feedback-bugcheck' => 'అద్భుతం! ఇది ఇప్పటికే [$1 తెలిసిన బగ్గుల]లో లేదని సరిచూసుకోండి.',
@@ -3657,14 +3742,22 @@ $5
 
 # API errors
 'api-error-badaccess-groups' => 'ఈ వికీ లోనికి దస్త్రాలను ఎక్కించే అనుమతి మీకు లేదు.',
+'api-error-badtoken' => 'అంతర్గత లోపం: చెడు టోకెన్.',
+'api-error-copyuploaddisabled' => 'URL ద్వారా ఎక్కించడం ఈ సర్వరులో అశక్తం చెయ్యబడింది.',
+'api-error-duplicate' => 'ఇదే విషయ పాఠ్యంతో ఈ సైటులో ఈసరికే {{PLURAL:$1|[$2 మరో ఫైలు] ఉంది|[$2 ఇతర ఫైళ్ళు] ఉన్నాయి}}.',
+'api-error-duplicate-archive' => 'ఇదే విషయ పాఠ్యంతో ఈ సైటులో ఈసరికే {{PLURAL:$1|[$2 మరో ఫైలు] ఉండేది|[$2 ఇతర ఫైళ్ళు] ఉండేవి}}. అయితే {{PLURAL:$1|అది తొలగించబడింది|అవి తొలగించబడ్డాయి}}.',
 'api-error-duplicate-archive-popup-title' => 'నకిలీ {{PLURAL:$1|దస్త్రాన్ని|దస్త్రాలను}} ఇప్పటికే తొలగించారు.',
 'api-error-duplicate-popup-title' => 'నకిలీ {{PLURAL:$1|దస్త్రం|దస్త్రాలు}}.',
 'api-error-empty-file' => 'మీరు దాఖలుచేసిన ఫైల్ ఖాళీది.',
 'api-error-emptypage' => 'కొత్త మరియు ఖాళీ పేజీలను సృష్టించడానికి అనుమతి లేదు.',
+'api-error-fetchfileerror' => 'అంతర్గత లోపం: ఈ ఫైలును తేవడంలో ఏదో తప్పు జరిగింది.',
+'api-error-fileexists-forbidden' => '"$1" పేరుతో ఓ ఫైలు ఈసరికే ఉంది. దాన్ని తిరగరాయడం కుదరదు.',
+'api-error-fileexists-shared-forbidden' => '"$1" పేరుతో ఓ ఫైలు ఈసరికే ఈ సహ ఫైలు ఖజానా (షేర్‍డ్ ఫైల్ రిపాజిటరీ)లో ఉంది. దాన్ని తిరగరాయడం కుదరదు.',
 'api-error-file-too-large' => 'మీరు సమర్పించిన దస్త్రం చాలా పెద్దగా ఉంది.',
 'api-error-filename-tooshort' => 'దస్త్రపు పేరు మరీ చిన్నగా ఉంది.',
 'api-error-filetype-banned' => 'ఈ రకపు దస్త్రాలని నిషేధించారు.',
-'api-error-filetype-banned-type' => '$1 {{PLURAL:$4|అనేది అనుమతించబడిన ఫైలు రకం కాదు|అనేవి అనుమతించబడిన ఫైలు రకాలు కాదు}}. అనుమతించబడిన {{PLURAL:$3|ఫైలు రకం|ఫైలు రకాలు}} $2.',
+'api-error-filetype-banned-type' => '$1, అనుమతించబడిన {{PLURAL:$4|ఫైలు రకం కాదు|ఫైలు రకాలు కాదు}}. అనుమతించబడిన {{PLURAL:$3|ఫైలు రకం|ఫైలు రకాలు}}: $2.',
+'api-error-filetype-missing' => 'ఫైలుపేరులో ఓ ఎక్స్టెన్షను లేదు.',
 'api-error-http' => 'అంతర్గత దోషము: సేవకానికి అనుసంధానమవలేకపోతున్నది.',
 'api-error-illegal-filename' => 'ఆ పైల్ పేరు అనుమతించబడదు.',
 'api-error-invalid-file-key' => 'అంతర్గత దోషము: తాత్కాలిక నిల్వలో ఫైల్ కనపడలేదు.',
@@ -3692,8 +3785,11 @@ $5
 'duration-millennia' => '$1 {{PLURAL:$1|సహస్రాబ్దం|సహస్రాబ్దాలు}}',
 
 # Limit report
+'limitreport-cputime' => 'CPU సమయం వినియోగం',
 'limitreport-cputime-value' => '$1 {{PLURAL:$1|క్షణం|క్షణాలు}}',
+'limitreport-walltime' => 'నిజ సమయం వినియోగం',
 'limitreport-walltime-value' => '$1 {{PLURAL:$1|క్షణం|క్షణాలు}}',
+'limitreport-postexpandincludesize-value' => '$1/$2 {{PLURAL:$2|బైట్|బైట్లు}}',
 'limitreport-templateargumentsize-value' => '$1/$2 {{PLURAL:$2|బైటు|బైట్లు}}',
 
 # Special:ExpandTemplates
index a1a2fd8..5900d22 100644 (file)
@@ -922,7 +922,7 @@ $2
 'invalid-content-data' => 'مەزمۇن سانلىق مەلۇماتى ئىناۋەتسىز',
 'content-not-allowed-here' => '[[$2]] بەتتە "$1" مەزمۇنغا يول قويۇلمايدۇ',
 'editwarning-warning' => 'بەتتىن ئايرىلغاندا بەلكىم بارلىق تەھرىرلىگىنىڭىز بېكار بولۇپ كېتىشى مۇمكىن.
-ئ‍ەگەر تىزىمغا كىرسىڭىز، مايىللىق بېتىڭىزنىڭ «تەھرىر» بۆلىكىدە، بۇ ئەسكەرتمىنى ئىناۋەتسىز قىلالايسىز.',
+ئ‍ەگەر تىزىمغا كىرسىڭىز، مايىللىق بېتىڭىزنىڭ «{{int:prefs-editing}}» بۆلىكىدە، بۇ ئەسكەرتمىنى ئىناۋەتسىز قىلالايسىز.',
 
 # Content models
 'content-model-wikitext' => 'ۋىكىتېكىست',
index e92a2de..d2ce5ff 100644 (file)
@@ -1211,7 +1211,7 @@ $2
 'invalid-content-data' => 'Неприпустимі дані',
 'content-not-allowed-here' => 'Вміст «$1» недопустимий на сторінці [[$2]]',
 'editwarning-warning' => 'Перехід на іншу сторінку призведе до втрати ваших змін.
-Якщо ви ввійшли до системи, то ви можете відключити це попередження в розділі «Редагування» ваших налаштувань.',
+Якщо ви ввійшли до системи, то ви можете відключити це попередження в розділі "{{int:prefs-editing}}" ваших налаштувань.',
 'editpage-notsupportedcontentformat-title' => 'Непідтримуваний формат вмісту',
 'editpage-notsupportedcontentformat-text' => 'Формат вмісту $1 не підтримується моделлю вмісту $2.',
 
@@ -1428,6 +1428,8 @@ $1",
 'showhideselectedversions' => 'Показати/приховати обрані версії',
 'editundo' => 'скасувати',
 'diff-empty' => '(Немає відмінностей)',
+'diff-multi-sameuser' => '(не {{PLURAL:$1|показано одну проміжну версію|показані $1 проміжні версії|показано $1 проміжних версій}} цього учасника)',
+'diff-multi-otherusers' => '(не {{PLURAL:$1|показана одна проміжна версія|показано $1 проміжні версії|показані $1 проміжних версій}} {{PLURAL:$2|ще одного учасника|$2 учасників}})',
 'diff-multi-manyusers' => '({{PLURAL:$1|не показана $1 проміжна версія|не показані $1 проміжні версії|не показано $1 проміжних версій}}, зроблених більш, ніж {{PLURAL:$2|1=$1 користувачем|$2 користувачами}})',
 'difference-missing-revision' => '{{PLURAL:$2|$2 версія|$2 версії|$2 версій}} для цього порівняння ($1) не {{PLURAL:$2|1=знайдена|знайдені}}.
 
@@ -1448,7 +1450,8 @@ $1",
 'shown-title' => 'Показувати $1 {{PLURAL:$1|запис|записи|записів}} на сторінці',
 'viewprevnext' => 'Переглянути ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-exists' => "'''У цій вікі є сторінка з назвою «[[:$1]]»'''",
-'searchmenu-new' => "'''Створити сторінку «[[:$1]]» у цій вікі!'''",
+'searchmenu-new' => '<strong>Створити сторінку «[[:$1]]» у цьому вікі-проекті!</strong>
+{{PLURAL:$2|0=|Див. також сторінку, знайдену по результатами вашого пошуку.|Див. також знайдені результати пошуку.}}',
 'searchprofile-articles' => 'Статті',
 'searchprofile-project' => 'Сторінки довідки і проекту',
 'searchprofile-images' => 'Мультимедіа',
index 90f142c..02728c1 100644 (file)
@@ -122,13 +122,13 @@ $messages = array(
 'tog-editondblclick' => 'Sichqoncha tugmasini ikki marta bosish orqali tahrirlashni boshlash',
 'tog-editsectiononrightclick' => 'Boʻlim sarlavhasiga sichqonchaning oʻng tugmasi bilan bosib tahrirlashni boshlash',
 'tog-rememberpassword' => 'Hisob ma’lumotlarim ushbu brauzerda eslab qolinsin (ko‘pi bilan $1 kunga)',
-'tog-watchcreations' => 'Men yaratgan sahifalarni va yuklagan fayllarni kuzatuv roʻyxatimga qoʻsh',
-'tog-watchdefault' => 'Men tahrirlagan sahifa va fayllarni kuzatuv roʻyxatimga qoʻsh',
-'tog-watchmoves' => 'Men koʻchirgan sahifa va fayllarni kuzatuv roʻyxatimga qoʻsh',
+'tog-watchcreations' => 'Men yaratgan sahifalar va yuklagan fayllar kuzatuv roʻyxatimga qoʻshilsin',
+'tog-watchdefault' => 'Men tahrirlagan sahifa va fayllar kuzatuv roʻyxatimga qoʻshilsin',
+'tog-watchmoves' => 'Men nomini koʻchirgan sahifa va fayllar kuzatuv roʻyxatimga qoʻshilsin',
 'tog-watchdeletion' => 'Men oʻchirgan sahifa va fayllarni kuzatuv roʻyxatimga qoʻsh',
 'tog-minordefault' => 'Sukut boʻyicha barcha tahrirlarimni «kichik tahrir» etib belgilash',
-'tog-previewontop' => 'Tahrir oynasi tepasida koʻrib chiqish',
-'tog-previewonfirst' => 'Tahrirlashga oʻtiboq koʻrib chiqishni boshlash',
+'tog-previewontop' => 'Koʻrib chiqish imkoniyati tahrir oynasi tepasida boʻlsin',
+'tog-previewonfirst' => 'Tahrirlashga oʻtgandayoq koʻrib chiqishni boshlash',
 'tog-enotifwatchlistpages' => 'Kuzatuv roʻyxatimdagi sahifa yoki fayllar oʻzgartirilsa, menga bu haqda xat yuborilsin',
 'tog-enotifusertalkpages' => 'Munozara sahifam oʻzgartirilsa, menga bu haqda xat yuborilsin',
 'tog-enotifminoredits' => 'Kichik tahrir qilinsa ham e-pochtamga bu haqda xat yuborilsin',
@@ -150,6 +150,7 @@ $messages = array(
 'tog-noconvertlink' => 'Sarlavhani oʻzgartirish havolasini oʻchirib qoʻyish',
 'tog-norollbackdiff' => 'Tahrir qaytarilganda, versiyalar taqqosi koʻrsatilmasin',
 'tog-useeditwarning' => 'Kiritgan oʻzgarishlarimni saqlamay sahifadan chiqib ketayotganim haqida ogohlantirilsin',
+'tog-prefershttps' => 'Doim himoyalangan holda kirish',
 
 'underline-always' => 'Har doim',
 'underline-never' => 'Hech qachon',
@@ -424,8 +425,10 @@ $1',
 'viewsource' => 'Manbasini koʻrish',
 'viewsource-title' => '$1 sahifasining manbasini koʻrish',
 'actionthrottled' => 'Tezlik cheklovi',
-'protectedpagetext' => 'Bu sahifa tahrirlash va boshqa oʻzgartirishlar kiritishdan himoyalangan.',
+'protectedpagetext' => 'Bu sahifa tahrirlash va boshqa oʻzgarishlar kiritishdan himoyalangan.',
 'viewsourcetext' => 'Siz bu sahifaning manbasini koʻrishingiz va uni nusxasini olishingiz mumkin:',
+'protectedinterface' => 'Ushbu sahifada dasturiy taʼminot interfeysi xabari mavjud. Bezoriliklardan saqlash uchun uni oʻzgartirish taʼqiqlangan.
+Ushbu xabar tarjimasini qoʻshish yoki oʻzgartirish uchun, iltimos, MediaWikining [//translatewiki.net/ translatewiki.net] mahalliylashtirish saytidan foydalaning.',
 'editinginterface' => "'''Diqqat:''' Siz dasturiy taʼminot interfeysi matni mavjud boʻlgan sahifani tahrirlamoqdasiz.
 Uning oʻzgartirilishi ushbu vikidagi boshqa foydalanuvchilar uchun ham interfeys oʻzgarishiga olib keladi.
 Ushbu xabar tarjimasini qoʻshish yoki oʻzgartirish uchun, iltimos, MediaWikining [//translatewiki.net/ translatewiki.net] mahalliylashtirish saytidan foydalaning.",
@@ -519,7 +522,7 @@ Ism yozilishini tekshirib koʻring.',
 
 # Change password dialog
 'changepassword' => 'Maxfiy soʻzni oʻzgartirish',
-'resetpass_header' => "Hisob mahfiy so'zini o'zgartirish",
+'resetpass_header' => 'Maxfiy soʻzni oʻzgartirish',
 'oldpassword' => "Eski mahfiy so'z:",
 'newpassword' => "Yangi mahfiy so'z:",
 'retypenew' => 'Yangi mahfiy soʻzni qayta tering:',
@@ -562,7 +565,7 @@ Vaqtinchalik maxfiy so'z: $2",
 'headline_tip' => '2-darajadagi sarlavha',
 'nowiki_sample' => 'Bu yerga formatlash zarur boʻlmagan matnni qoʻying',
 'nowiki_tip' => "Viki-formatlashga e'tibor qilmaslik",
-'image_tip' => 'Qoʻshilgan tasvir',
+'image_tip' => 'Fayl oʻrnatish',
 'media_tip' => 'Faylga havola',
 'sig_tip' => 'Imzoingiz va sana',
 'hr_tip' => "Yotiq (gorizontal) chiziq (ko'p ishlatmang)",
@@ -574,7 +577,7 @@ Vaqtinchalik maxfiy so'z: $2",
 'watchthis' => 'Sahifani kuzatish',
 'savearticle' => 'Saqlash',
 'preview' => 'Ko‘rib chiqish',
-'showpreview' => 'Korib chiqish',
+'showpreview' => 'Koʻrib chiqish',
 'showlivepreview' => 'Tezkor koʻrib chiqish',
 'showdiff' => 'O‘zgarishlarni ko‘rsatish',
 'anoneditwarning' => "'''Diqqat:''' Siz tizimga kirmagansiz. Ushbu sahifa tarixida Sizning IP manzilingiz yozib qolinadi.",
@@ -769,7 +772,7 @@ Bu yerda: '''({{int:cur}})''' = hozirgi koʻrinish bilan farqi, '''({{int:last}}
 'search-interwiki-default' => '$1 natijalar:',
 'search-interwiki-more' => '(yana)',
 'search-relatedarticle' => "Bog'liq",
-'searcheverything-enable' => 'Barcha nomfazolarda qidir',
+'searcheverything-enable' => 'Barcha nomfazolardan qidirish',
 'searchrelated' => 'bogʻlangan',
 'searchall' => 'barchasi',
 'showingresults' => "Quyida №'''$2'''dan boshlab {{PLURAL:$1|'''bitta''' natija|'''$1''' ta natija}} koʻrsatilgan.",
@@ -799,8 +802,10 @@ Bu yerda: '''({{int:cur}})''' = hozirgi koʻrinish bilan farqi, '''({{int:last}}
 'prefs-rc' => 'Yangi o‘zgartirishlar',
 'prefs-watchlist' => 'Kuzatuv roʻyxati',
 'prefs-watchlist-days' => 'Kunlar soni:',
-'prefs-watchlist-days-max' => 'Eng ko‘pi bilan $1 {{PLURAL:$1|kun}}',
-'prefs-watchlist-edits-max' => 'Eng katta son: 1000',
+'prefs-watchlist-days-max' => 'Maksimum $1 kun',
+'prefs-watchlist-edits' => 'Kengaytirilgan kuzatuv roʻyxatingizda koʻrsatiladigan oʻzgarishlar soni:',
+'prefs-watchlist-edits-max' => 'Maksimum: 1000',
+'prefs-watchlist-token' => 'Kuzatuv roʻyxatingiz tokeni:',
 'prefs-misc' => 'Boshqa moslamalar',
 'prefs-resetpass' => 'Maxfiy soʻzni oʻzgartirish',
 'prefs-changeemail' => 'Elektron pochta manzilini oʻzgartirish',
@@ -812,17 +817,19 @@ Bu yerda: '''({{int:cur}})''' = hozirgi koʻrinish bilan farqi, '''({{int:last}}
 'rows' => 'Qatorlar soni:',
 'columns' => 'Ustunlar soni:',
 'searchresultshead' => 'Qidiruv',
-'stub-threshold' => '<a href="#" class="stub">Chala maqolalarga ishorat</a> keltirish uchun pastki chegara (baytlarda):',
+'stub-threshold' => '[[Special:ShortPages|Chala maqolalarga]] ishorat keltirish uchun pastki chegara:',
 'stub-threshold-disabled' => 'Oʻchirib qoʻyilgan',
 'recentchangesdays' => 'Necha kunlik tahrirlar koʻrsatiladi:',
-'recentchangesdays-max' => 'Eng koʻpi — $1 kun',
+'recentchangesdays-max' => 'Maksimum $1 kun',
 'recentchangescount' => 'Sukut boʻyicha koʻrsatiladigan tahrirlar soni:',
-'prefs-help-recentchangescount' => 'Yangi oʻzgarishlar, tarix va qaydlar uchun.',
+'prefs-help-recentchangescount' => 'Yangi oʻzgarishlar, sahifalar tarixi va qaydlar uchun',
+'prefs-help-watchlist-token2' => 'Bu kuzatuv roʻyxatingizning veb-kanali uchun maxfiy kalit kodi.
+Bu kodni biladigan har kim sizning kuzatuv roʻyxatingizni koʻrishi mumkin, shuning uchun boshqalarga uni oshkor qilmang. [[Special:ResetTokens|Tokenni yangilash]].',
 'savedprefs' => 'Sizning moslamalaringiz saqlandi.',
 'timezonelegend' => 'Vaqt mintaqangiz:',
 'localtime' => 'Mahalliy vaqt:',
 'timezoneuseserverdefault' => 'Server moslamalaridan foydalanish ($1)',
-'timezoneuseoffset' => "Boshqa (siljishni ko'rsating)",
+'timezoneuseoffset' => 'Boshqa (siljishni koʻrsating)',
 'servertime' => 'Server vaqti:',
 'guesstimezone' => "Brauzerdan to'ldirish",
 'timezoneregion-africa' => 'Afrika',
@@ -982,6 +989,10 @@ Agar keltirsangiz, undan sahifa kim tomonidan tahrirlanganini koʻrsatish uchun
 'upload' => 'Fayl yuklash',
 'uploadbtn' => 'Fayl yuklash',
 'uploaderror' => 'Yuklashda xatolik',
+'upload-recreate-warning' => '<strong>Diqqat: bunday nomli fayl avval yoʻqotilgan yoki koʻchirilgan.</strong>
+
+Quyida bu sahifaga oid yoʻqotish va koʻchirish qaydlari keltirilgan:',
+'upload-permitted' => 'Yuklash mumkin fayl turlari: $1.',
 'uploadlogpage' => 'Yuklash qaydlari',
 'filename' => 'Fayl nomi',
 'filedesc' => 'Qisqa izoh',
@@ -990,11 +1001,20 @@ Agar keltirsangiz, undan sahifa kim tomonidan tahrirlanganini koʻrsatish uchun
 'filestatus' => 'Tarqatish shartlari:',
 'filesource' => 'Manba:',
 'uploadedfiles' => 'Yuklangan fayllar',
+'ignorewarnings' => 'Ogohlantirishlarga eʼtibor qilma',
 'uploadedimage' => '"[[$1]]"ni yukladi',
 'overwroteimage' => '"[[$1]]"ning yangi versiyasini yukladi',
+'upload-source' => 'Yuklanayotgan fayl',
+'sourcefilename' => 'Fayl nomi:',
+'destfilename' => 'Fayl nomi:',
+'upload-maxfilesize' => 'Faylning maksimal oʻlchami: $1',
+'upload-description' => 'Fayl tavsifi',
+'upload-options' => 'Yuklash moslamalari',
+'watchthisupload' => 'Bu faylni kuzatish',
 
 'license' => 'Litsenziyalash:',
 'license-header' => 'Litsenziyalash',
+'upload_source_file' => '(kompyuteringizdagi fayl)',
 
 # Special:ListFiles
 'listfiles-summary' => 'Ushbu maxsus sahifada barcha yuklangan fayllar koʻrsatilgan.',
@@ -1074,7 +1094,7 @@ Uning [$2 fayl tavsifi sahifasidan] olingan tavsifi quyida keltirilgan.',
 'uncategorizedcategories' => 'Turkumlashtirilmagan turkumlar',
 'uncategorizedimages' => 'Turkumlashtirilmagan fayllar',
 'uncategorizedtemplates' => 'Turkumlashtirilmagan andozalar',
-'unusedcategories' => 'Ishlatilinmagan turkumlar',
+'unusedcategories' => 'Ishlatilmayotgan turkumlar',
 'unusedimages' => 'Ishlatilinmagan fayllar',
 'wantedcategories' => 'Talab qilinayotgan turkumlar',
 'mostcategories' => 'Eng koʻp turkumli sahifalar',
@@ -1122,9 +1142,9 @@ Natijalarni jurnal nomi, foydalanuvchi nomi (harflar katta-kichikligi inobatga o
 
 # Special:Categories
 'categories' => 'Turkumlar',
-'categoriespagetext' => 'The following {{PLURAL:$1|category contains|categories contain}} pages or media.
-[[Special:UnusedCategories|Unused categories]] are not shown here.
-Also see [[Special:WantedCategories|wanted categories]].',
+'categoriespagetext' => 'Quyidagi {{PLURAL:$1|turkumda|turkumlarda}} sahifa yoki media-fayllar mavjud.
+[[Special:UnusedCategories|Ishlatilmayotgan turkumlar]] bu yerda koʻrsatilmaydi.
+Shuningdek qarang: [[Special:WantedCategories|talab qilinayotgan turkumlar]].',
 'categoriesfrom' => 'Quyidagidan boshlanuvchi turkumlarni koʻrsatish:',
 'special-categories-sort-count' => 'miqdori bo‘yicha saralash',
 'special-categories-sort-abc' => 'alifbo bo‘yicha saralash',
@@ -1717,4 +1737,7 @@ Umumiy omborda [[:$1]] mavjud. Faylning bu nomga qayta nomlanishi faylning umumi
 'api-error-unknown-code' => 'Noaniq xato: "$1".',
 'api-error-unknownerror' => 'Noaniq xato: "$1".',
 
+# Limit report
+'limitreport-title' => 'Tahlillagich maʼlumotlari:',
+
 );
index 128b706..e7c94c5 100644 (file)
@@ -1156,7 +1156,7 @@ Nó đã tồn tại.',
 'invalid-content-data' => 'Dữ liệu nội dung không hợp lệ',
 'content-not-allowed-here' => 'Không cho phép đưa nội dung “$1” vào trang [[$2]]',
 'editwarning-warning' => 'Rời khỏi trang này sẽ khiến bạn mất các sửa đổi đã thực hiện.
-Nếu đã đăng nhập, bạn có thể tắt cảnh báo này tại mục “Sửa đổi” trong tùy chọn cá nhân.',
+Nếu đã đăng nhập, bạn có thể tắt cảnh báo này tại mục “{{int:prefs-editing}}” trong tùy chọn cá nhân.',
 'editpage-notsupportedcontentformat-title' => 'Không hỗ trợ định dạng nội dung',
 'editpage-notsupportedcontentformat-text' => 'Mô hình nội dung $2 không hỗ trợ định dạng nội dung $1.',
 
@@ -1192,6 +1192,7 @@ Những tham số này sẽ bị bỏ đi.',
 'undo-success' => 'Các sửa đổi có thể được lùi lại. Xin hãy kiểm tra phần so sánh bên dưới để xác nhận lại những gì bạn muốn làm, sau đó lưu thay đổi ở dưới để hoàn tất việc lùi lại sửa đổi.',
 'undo-failure' => 'Sửa đổi không thể phục hồi vì đã có những sửa đổi mới ở sau.',
 'undo-norev' => 'Sửa đổi không thể hồi phục vì nó không tồn tại hoặc đã bị xóa.',
+'undo-nochange' => 'Hình như sửa đổi này đã được lùi lại rồi.',
 'undo-summary' => 'Đã lùi lại sửa đổi $1 của [[Special:Contributions/$2|$2]] ([[User talk:$2|Thảo luận]])',
 'undo-summary-username-hidden' => 'Đã lùi lại sửa đổi $1 của một người dùng ẩn',
 
index 9037dd8..4350b2a 100644 (file)
@@ -1254,6 +1254,7 @@ $1",
 'showhideselectedversions' => 'ווײַזן/באַהאַלטן געקליבענע רעוויזיעס',
 'editundo' => 'אַנולירן',
 'diff-empty' => '(קיין אונטערשייד)',
+'diff-multi-otherusers' => '({{PLURAL:$1|איין מיטלסטע ווערסיע |$1 מיטלסטע ווערסיעס}} פֿון {{PLURAL:$2|איין אנדער באַניצער|$2 באַניצער}} נישט געוויזן.)',
 'diff-multi-manyusers' => '({{PLURAL:$1|איין מיטלסטע ווערסיע |$1 מיטלסטע ווערסיעס}} פֿון מער ווי {{PLURAL:$2|איין באַניצער|$2 באַניצער}} נישט געוויזן.)',
 'difference-missing-revision' => '{{PLURAL:$2|איין ווערסיע|$2 ווערסיעס}} פון דעם דיפערענץ ($1) {{PLURAL:$2|האט}} מען נישט געטראפן.
 
@@ -1274,7 +1275,7 @@ $1",
 'shown-title' => 'ווײַזן $1  {{PLURAL:$1|רעזולטאַט| רעזולטאַטן}} אויף א בלאַט',
 'viewprevnext' => 'קוקט אויף ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "'''ס'איז פֿאַראַן א בלאַט מיטן נאמען \"[[:\$1]]\" אין דער וויקי'''",
-'searchmenu-new' => "'''באַשאַפֿן דעם בלאַט \"[[:\$1]]\" אויף דער וויקי'''",
+'searchmenu-new' => '<strong>באַשאַפֿן דעם בלאַט "[[:$1]]" אויף דער וויקי!</strong> {{PLURAL:$2|0=|זעט אויך דעם בלאט געפֿונען מיט אײַער זוך.|זעט אויך די זוך רעזולטאטן געפֿונען.}}',
 'searchprofile-articles' => 'אינהאלט בלעטער',
 'searchprofile-project' => 'הילף און פראיעקט בלעטער',
 'searchprofile-images' => 'מולטימעדיע',
@@ -2862,7 +2863,7 @@ $2',
 אַ פראוויזארישער טעקע־האלטער פֿעלט.',
 'import-parse-failure' => 'פֿעלער בײַם אימפארטירן XML',
 'import-noarticle' => 'נישטא קיין בלאט צו אימפארטירן!',
-'import-nonewrevisions' => '×\90Ö·×\9c×¢ ×¨×¢×\95×\95×\99×\96×\99עס ×©×\95×\99×\9f ×\90×\99×\9eפ×\90ר×\98×\99ר×\98.',
+'import-nonewrevisions' => 'ק×\99×\99×\9f ×¨×¢×\95×\95×\99×\96×\99עס × ×\99ש×\98 ×\90×\99×\9eפ×\90ר×\98×\99ר×\98 (×\90×\93ער ×\90×\9c×¢ ×©×\95×\99×\9f ×\93×\90, ×\90×\93ער ×\90×\99×\91ער×\92×¢×\94×\99פ×\98 ×¦×\95×\9c×\99×\91 ×\92רײַ×\96×\9f).',
 'xml-error-string' => '$1 בײַ שורה $2, זייל $3 (בייט $4): $5',
 'import-upload' => 'אַרויפֿלאָדן XML דאַטן',
 'import-token-mismatch' => 'אָנווער פון סעסיע דאַטן.
index 37711c9..1c2910b 100644 (file)
@@ -1158,7 +1158,7 @@ $2
 'content-failed-to-parse' => '未能将 $2 内容转换为 $1:$3',
 'invalid-content-data' => '无效的内容数据',
 'content-not-allowed-here' => '[[$2]]页面上不允许“$1”内容',
-'editwarning-warning' => '离开本页面可能导致你失去任何你已经作出的更改。如果你处于登录状态,你可以在你的设置的“编辑”部分停用该警告。',
+'editwarning-warning' => '离开本页面可能导致你失去任何你已经作出的更改。如果你处于登录状态,你可以在你的设置的“{{int:prefs-editing}}”部分停用该警告。',
 'editpage-notsupportedcontentformat-title' => '内容格式尚不支持',
 'editpage-notsupportedcontentformat-text' => '内容模型$2尚不支持内容格式$1。',
 
@@ -1734,7 +1734,7 @@ $1",
 'newsectionsummary' => '/* $1 */ 新段落',
 'rc-enhanced-expand' => '显示细节',
 'rc-enhanced-hide' => '隐藏细节',
-'rc-old-title' => '最初被创建为" $1 "',
+'rc-old-title' => '最初创建为“$1”',
 
 # Recent changes linked
 'recentchangeslinked' => '相关更改',
diff --git a/maintenance/benchmarks/benchmarkParse.php b/maintenance/benchmarks/benchmarkParse.php
new file mode 100644 (file)
index 0000000..cec2beb
--- /dev/null
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Benchmark script for parse operations
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Tim Starling <tstarling@wikimedia.org>
+ * @ingroup Benchmark
+ */
+
+require __DIR__ . '/../Maintenance.php';
+
+/**
+ * Maintenance script to benchmark how long it takes to parse a given title at an optionally
+ * specified timestamp
+ *
+ * @since 1.23
+ */
+class BenchmarkParse extends Maintenance {
+       /** @var string MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS) */
+       private $templateTimestamp = null;
+
+       /** @var array Cache that maps a Title DB key to revision ID for the requested timestamp */
+       private $idCache = array();
+
+       function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Benchmark parse operation' );
+               $this->addArg( 'title', 'The name of the page to parse' );
+               $this->addOption( 'cold', 'Don\'t repeat the parse operation to warm the cache' );
+               $this->addOption( 'page-time',
+                       'Use the version of the page which was current at the given time',
+                       false, true );
+               $this->addOption( 'tpl-time',
+                       'Use templates which were current at the given time (except that moves and ' .
+                               'deletes are not handled properly)',
+                       false, true );
+       }
+
+       function execute() {
+               if ( $this->hasOption( 'tpl-time' ) ) {
+                       $this->templateTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'tpl-time' ) ) );
+                       Hooks::register( 'BeforeParserFetchTemplateAndtitle', array( $this, 'onFetchTemplate' ) );
+               }
+
+               $title = Title::newFromText( $this->getArg() );
+               if ( !$title ) {
+                       $this->error( "Invalid title" );
+                       exit( 1 );
+               }
+
+               if ( $this->hasOption( 'page-time' ) ) {
+                       $pageTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'page-time' ) ) );
+                       $id = $this->getRevIdForTime( $title, $pageTimestamp );
+                       if ( !$id ) {
+                               $this->error( "The page did not exist at that time" );
+                               exit( 1 );
+                       }
+
+                       $revision = Revision::newFromId( $id );
+               } else {
+                       $revision = Revision::newFromTitle( $title );
+               }
+
+               if ( !$revision ) {
+                       $this->error( "Unable to load revision, incorrect title?" );
+                       exit( 1 );
+               }
+
+               if ( !$this->hasOption( 'cold' ) ) {
+                       $this->runParser( $revision );
+               }
+
+               $startUsage = getrusage();
+               $startTime = microtime( true );
+               $this->runParser( $revision );
+               $endUsage = getrusage();
+               $endTime = microtime( true );
+
+               printf( "CPU time = %.3f s, wall clock time = %.3f s\n",
+                       // CPU time
+                       $endUsage['ru_utime.tv_sec'] + $endUsage['ru_utime.tv_usec'] * 1e-6
+                               - $startUsage['ru_utime.tv_sec'] - $startUsage['ru_utime.tv_usec'] * 1e-6,
+                       // Wall clock time
+                       $endTime - $startTime );
+       }
+
+       /**
+        * Fetch the ID of the revision of a Title that occurred
+        *
+        * @param Title $title
+        * @param string $timestamp
+        * @return bool|string Revision ID, or false if not found or error
+        */
+       function getRevIdForTime( Title $title, $timestamp ) {
+               $dbr = wfGetDB( DB_SLAVE );
+
+               $id = $dbr->selectField(
+                       array( 'revision', 'page' ),
+                       'rev_id',
+                       array(
+                               'page_namespace' => $title->getNamespace(),
+                               'page_title' => $title->getDBkey(),
+                               'rev_timestamp <= ' . $dbr->addQuotes( $timestamp )
+                       ),
+                       __METHOD__,
+                       array( 'ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 1 ),
+                       array( 'revision' => array( 'INNER JOIN', 'rev_page=page_id' ) )
+               );
+
+               return $id;
+       }
+
+       /**
+        * Parse the text from a given Revision
+        *
+        * @param Revision $revision
+        */
+       function runParser( Revision $revision ) {
+               $content = $revision->getContent();
+               $content->getParserOutput( $revision->getTitle(), $revision->getId() );
+       }
+
+       /**
+        * Hook into the parser's revision ID fetcher. Make sure that the parser only
+        * uses revisions around the specified timestamp.
+        *
+        * @param Parser $parser
+        * @param Title $title
+        * @param bool &$skip
+        * @param string|bool &$id
+        * @return bool
+        */
+       function onFetchTemplate( Parser $parser, Title $title, &$skip, &$id ) {
+               $pdbk = $title->getPrefixedDBkey();
+               if ( !isset( $this->idCache[$pdbk] ) ) {
+                       $proposedId = $this->getRevIdForTime( $title, $this->templateTimestamp );
+                       $this->idCache[$pdbk] = $proposedId;
+               }
+               if ( $this->idCache[$pdbk] !== false ) {
+                       $id = $this->idCache[$pdbk];
+               }
+
+               return true;
+       }
+}
+
+$maintClass = 'BenchmarkParse';
+require RUN_MAINTENANCE_IF_MAIN;
index 60bb8d8..52cb209 100644 (file)
@@ -23,8 +23,6 @@
  * @author Antoine Musso <hashar@free.fr>
  */
 
-define( 'MW_SETUP_NO_CACHE', 1 );
-define( 'MW_SETUP_NO_CONTEXT', 1 );
 require_once __DIR__ . '/Maintenance.php';
 
 /**
index bbe1860..875e2f5 100644 (file)
                                        "mw.language*",
                                        "mw.cldr"
                                ]
+                       },
+                       {
+                               "name": "Page",
+                               "classes": [
+                                       "mw.page*"
+                               ]
                        }
                ]
        },
index d0e2628..f403067 100644 (file)
@@ -10,6 +10,7 @@
        "--": [
                "./external.js",
                "../../resources/mediawiki/mediawiki.js",
+               "../../resources/mediawiki/mediawiki.htmlform.js",
                "../../resources/mediawiki/mediawiki.log.js",
                "../../resources/mediawiki/mediawiki.util.js",
                "../../resources/mediawiki/mediawiki.Title.js",
@@ -21,6 +22,7 @@
                "../../resources/mediawiki.action/mediawiki.action.edit.js",
                "../../resources/mediawiki.action/mediawiki.action.view.postEdit.js",
                "../../resources/mediawiki.page/mediawiki.page.startup.js",
+               "../../resources/mediawiki.page/mediawiki.page.watch.ajax.js",
                "../../resources/mediawiki.api",
                "../../resources/mediawiki.language",
                "../../resources/jquery/jquery.localize.js",
index fd23ea1..ed85223 100644 (file)
@@ -796,6 +796,7 @@ $wgMessageStructure = array(
                'undo-success',
                'undo-failure',
                'undo-norev',
+               'undo-nochange',
                'undo-summary',
                'undo-summary-username-hidden',
        ),
@@ -990,6 +991,7 @@ $wgMessageStructure = array(
                'searchrelated',
                'searchall',
                'showingresults',
+               'showingresultsinrange',
                'showingresultsnum',
                'showingresultsheader',
                'search-nonefound',
index 40c6951..c5ade2d 100644 (file)
@@ -34,19 +34,18 @@ class UpdateSpecialPages extends Maintenance {
                parent::__construct();
                $this->addOption( 'list', 'List special page names' );
                $this->addOption( 'only', 'Only update "page"; case sensitive, ' .
-               'check correct case by calling this script with --list or on ' .
-               'includes/QueryPage.php. Ex: --only=BrokenRedirects', false, true );
+                       'check correct case by calling this script with --list or on ' .
+                       'includes/QueryPage.php. Ex: --only=BrokenRedirects', false, true );
                $this->addOption( 'override', 'Also update pages that have updates disabled' );
        }
 
        public function execute() {
                global $IP, $wgQueryPages, $wgQueryCacheLimit, $wgDisableQueryPageUpdate;
 
-               if ( !$this->hasOption( 'list' ) && !$this->hasOption( 'only' ) ) {
-                       $this->doSpecialPageCacheUpdates();
-               }
                $dbw = wfGetDB( DB_MASTER );
 
+               $this->doSpecialPageCacheUpdates( $dbw );
+
                // This is needed to initialise $wgQueryPages
                require_once "$IP/includes/QueryPage.php";
 
@@ -56,12 +55,14 @@ class UpdateSpecialPages extends Maintenance {
 
                        # --list : just show the name of pages
                        if ( $this->hasOption( 'list' ) ) {
-                               $this->output( "$special\n" );
+                               $this->output( "$special [QueryPage]\n" );
                                continue;
                        }
 
-                       if ( !$this->hasOption( 'override' ) && $wgDisableQueryPageUpdate && in_array( $special, $wgDisableQueryPageUpdate ) ) {
-                               $this->output( sprintf( "%-30s disabled\n", $special ) );
+                       if ( !$this->hasOption( 'override' )
+                               && $wgDisableQueryPageUpdate && in_array( $special, $wgDisableQueryPageUpdate ) )
+                       {
+                               $this->output( sprintf( "%-30s [QueryPage] disabled\n", $special ) );
                                continue;
                        }
 
@@ -81,7 +82,7 @@ class UpdateSpecialPages extends Maintenance {
                        }
 
                        if ( !$this->hasOption( 'only' ) || $this->getOption( 'only' ) == $queryPage->getName() ) {
-                               $this->output( sprintf( '%-30s ', $special ) );
+                               $this->output( sprintf( '%-30s [QueryPage] ', $special ) );
                                if ( $queryPage->isExpensive() ) {
                                        $t1 = explode( ' ', microtime() );
                                        # Do the query
@@ -125,32 +126,41 @@ class UpdateSpecialPages extends Maintenance {
                }
        }
 
-       public function doSpecialPageCacheUpdates() {
+       public function doSpecialPageCacheUpdates( $dbw ) {
                global $wgSpecialPageCacheUpdates;
-               $dbw = wfGetDB( DB_MASTER );
 
                foreach ( $wgSpecialPageCacheUpdates as $special => $call ) {
-                       if ( !is_callable( $call ) ) {
-                               $this->error( "Uncallable function $call!" );
+                       # --list : just show the name of pages
+                       if ( $this->hasOption( 'list' ) ) {
+                               $this->output( "$special [callback]\n" );
                                continue;
                        }
-                       $this->output( sprintf( '%-30s ', $special ) );
-                       $t1 = explode( ' ', microtime() );
-                       call_user_func( $call, $dbw );
-                       $t2 = explode( ' ', microtime() );
-                       $elapsed = ( $t2[0] - $t1[0] ) + ( $t2[1] - $t1[1] );
-                       $hours = intval( $elapsed / 3600 );
-                       $minutes = intval( $elapsed % 3600 / 60 );
-                       $seconds = $elapsed - $hours * 3600 - $minutes * 60;
-                       if ( $hours ) {
-                               $this->output( $hours . 'h ' );
-                       }
-                       if ( $minutes ) {
-                               $this->output( $minutes . 'm ' );
+
+                       if ( !$this->hasOption( 'only' ) || $this->getOption( 'only' ) == $special ) {
+                               if ( !is_callable( $call ) ) {
+                                       $this->error( "Uncallable function $call!" );
+                                       continue;
+                               }
+                               $this->output( sprintf( '%-30s [callback] ', $special ) );
+                               $t1 = explode( ' ', microtime() );
+                               call_user_func( $call, $dbw );
+                               $t2 = explode( ' ', microtime() );
+
+                               $this->output( "completed in " );
+                               $elapsed = ( $t2[0] - $t1[0] ) + ( $t2[1] - $t1[1] );
+                               $hours = intval( $elapsed / 3600 );
+                               $minutes = intval( $elapsed % 3600 / 60 );
+                               $seconds = $elapsed - $hours * 3600 - $minutes * 60;
+                               if ( $hours ) {
+                                       $this->output( $hours . 'h ' );
+                               }
+                               if ( $minutes ) {
+                                       $this->output( $minutes . 'm ' );
+                               }
+                               $this->output( sprintf( "%.2fs\n", $seconds ) );
+                               # Wait for the slave to catch up
+                               wfWaitForSlaves();
                        }
-                       $this->output( sprintf( "completed in %.2fs\n", $seconds ) );
-                       # Wait for the slave to catch up
-                       wfWaitForSlaves();
                }
        }
 }
index 6274e71..a02459f 100644 (file)
@@ -129,28 +129,6 @@ return array(
                'remoteBasePath' => $GLOBALS['wgStylePath'],
                'localBasePath' => $GLOBALS['wgStyleDirectory'],
        ),
-       // FIXME: Remove in favour of skins.monobook.styles when cache expires
-       'skins.monobook' => array(
-               'styles' => array(
-                       'common/commonElements.css' => array( 'media' => 'screen' ),
-                       'common/commonContent.css' => array( 'media' => 'screen' ),
-                       'common/commonInterface.css' => array( 'media' => 'screen' ),
-                       'monobook/main.css' => array( 'media' => 'screen' ),
-               ),
-               'remoteBasePath' => $GLOBALS['wgStylePath'],
-               'localBasePath' => $GLOBALS['wgStyleDirectory'],
-       ),
-       // FIXME: Remove in favour of skins.vector.styles when cache expires
-       'skins.vector' => array(
-               'styles' => array(
-                       'common/commonElements.css' => array( 'media' => 'screen' ),
-                       'common/commonContent.css' => array( 'media' => 'screen' ),
-                       'common/commonInterface.css' => array( 'media' => 'screen' ),
-                       'vector/styles.less',
-               ),
-               'remoteBasePath' => $GLOBALS['wgStylePath'],
-               'localBasePath' => $GLOBALS['wgStyleDirectory'],
-       ),
        'skins.vector.styles' => array(
                // Used in the web installer. Test it after modifying this definition!
                'styles' => array(
@@ -1205,21 +1183,6 @@ return array(
                'styles' => 'resources/mediawiki.special/mediawiki.special.version.css',
        ),
 
-       /* MediaWiki Tests */
-
-       'mediawiki.tests.qunit.testrunner' => array(
-               'scripts' => 'tests/qunit/data/testrunner.js',
-               'dependencies' => array(
-                       'jquery.getAttrs',
-                       'jquery.qunit',
-                       'jquery.qunit.completenessTest',
-                       'mediawiki.page.startup',
-                       'mediawiki.page.ready',
-               ),
-               'position' => 'top',
-               'targets' => array( 'desktop', 'mobile' ),
-       ),
-
        /* MediaWiki Legacy */
 
        'mediawiki.legacy.ajax' => array(
index a9fcec8..e3e4b9a 100644 (file)
@@ -33,6 +33,9 @@
                 
                 $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
                 $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
+                if (this.options.className) {
+                    $tip.addClass(maybeCall(this.options.className, this.$element[0]));
+                }
                 $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
                 
                 var pos = $.extend({}, this.$element.offset(), {
@@ -78,9 +81,6 @@
                 }
                 
                 $tip.css(tp).addClass('tipsy-' + gravity);
-                if (this.options.className) {
-                    $tip.addClass(maybeCall(this.options.className, this.$element[0]));
-                }
                 
                 if (this.options.fade) {
                     $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}, 100);
index f35782b..935aa4a 100644 (file)
                        if ( nav === undefined ) {
                                nav = window.navigator;
                        }
+
                        // Use the cached version if possible
-                       if ( profileCache[nav.userAgent] === undefined ) {
+                       if ( profileCache[ nav.userAgent + '|' + nav.platform ] !== undefined ) {
+                               return profileCache[ nav.userAgent + '|' + nav.platform ];
+                       }
 
-                               var
-                                       versionNumber,
+                       var
+                               versionNumber,
+                               key = nav.userAgent + '|' + nav.platform,
 
-                                       /* Configuration */
+                               /* Configuration */
 
-                                       // Name of browsers or layout engines we don't recognize
-                                       uk = 'unknown',
-                                       // Generic version digit
-                                       x = 'x',
-                                       // Strings found in user agent strings that need to be conformed
-                                       wildUserAgents = ['Opera', 'Navigator', 'Minefield', 'KHTML', 'Chrome', 'PLAYSTATION 3', 'Iceweasel'],
-                                       // Translations for conforming user agent strings
-                                       userAgentTranslations = [
-                                               // Tons of browsers lie about being something they are not
-                                               [/(Firefox|MSIE|KHTML,?\slike\sGecko|Konqueror)/, ''],
-                                               // Chrome lives in the shadow of Safari still
-                                               ['Chrome Safari', 'Chrome'],
-                                               // KHTML is the layout engine not the browser - LIES!
-                                               ['KHTML', 'Konqueror'],
-                                               // Firefox nightly builds
-                                               ['Minefield', 'Firefox'],
-                                               // This helps keep different versions consistent
-                                               ['Navigator', 'Netscape'],
-                                               // This prevents version extraction issues, otherwise translation would happen later
-                                               ['PLAYSTATION 3', 'PS3']
-                                       ],
-                                       // Strings which precede a version number in a user agent string - combined and used as
-                                       // match 1 in version detection
-                                       versionPrefixes = [
-                                               'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
-                                               'lynx', 'msie', 'safari', 'ps3', 'android'
-                                       ],
-                                       // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number
-                                       versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)',
-                                       // Names of known browsers
-                                       names = [
-                                               'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
-                                               'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq', 'android'
-                                       ],
-                                       // Tanslations for conforming browser names
-                                       nameTranslations = [],
-                                       // Names of known layout engines
-                                       layouts = ['gecko', 'konqueror', 'msie', 'trident', 'opera', 'webkit'],
-                                       // Translations for conforming layout names
-                                       layoutTranslations = [ ['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto'] ],
-                                       // Names of supported layout engines for version number
-                                       layoutVersions = ['applewebkit', 'gecko', 'trident'],
-                                       // Names of known operating systems
-                                       platforms = ['win', 'wow64', 'mac', 'linux', 'sunos', 'solaris', 'iphone'],
-                                       // Translations for conforming operating system names
-                                       platformTranslations = [ ['sunos', 'solaris'], ['wow64', 'win'] ],
+                               // Name of browsers or layout engines we don't recognize
+                               uk = 'unknown',
+                               // Generic version digit
+                               x = 'x',
+                               // Strings found in user agent strings that need to be conformed
+                               wildUserAgents = ['Opera', 'Navigator', 'Minefield', 'KHTML', 'Chrome', 'PLAYSTATION 3', 'Iceweasel'],
+                               // Translations for conforming user agent strings
+                               userAgentTranslations = [
+                                       // Tons of browsers lie about being something they are not
+                                       [/(Firefox|MSIE|KHTML,?\slike\sGecko|Konqueror)/, ''],
+                                       // Chrome lives in the shadow of Safari still
+                                       ['Chrome Safari', 'Chrome'],
+                                       // KHTML is the layout engine not the browser - LIES!
+                                       ['KHTML', 'Konqueror'],
+                                       // Firefox nightly builds
+                                       ['Minefield', 'Firefox'],
+                                       // This helps keep different versions consistent
+                                       ['Navigator', 'Netscape'],
+                                       // This prevents version extraction issues, otherwise translation would happen later
+                                       ['PLAYSTATION 3', 'PS3']
+                               ],
+                               // Strings which precede a version number in a user agent string - combined and used as
+                               // match 1 in version detection
+                               versionPrefixes = [
+                                       'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
+                                       'lynx', 'msie', 'safari', 'ps3', 'android'
+                               ],
+                               // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number
+                               versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)',
+                               // Names of known browsers
+                               names = [
+                                       'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
+                                       'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq', 'android'
+                               ],
+                               // Tanslations for conforming browser names
+                               nameTranslations = [],
+                               // Names of known layout engines
+                               layouts = ['gecko', 'konqueror', 'msie', 'trident', 'opera', 'webkit'],
+                               // Translations for conforming layout names
+                               layoutTranslations = [ ['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto'] ],
+                               // Names of supported layout engines for version number
+                               layoutVersions = ['applewebkit', 'gecko', 'trident'],
+                               // Names of known operating systems
+                               platforms = ['win', 'wow64', 'mac', 'linux', 'sunos', 'solaris', 'iphone'],
+                               // Translations for conforming operating system names
+                               platformTranslations = [ ['sunos', 'solaris'], ['wow64', 'win'] ],
 
-                                       /* Methods */
+                               /* Methods */
 
-                                       /**
-                                        * Performs multiple replacements on a string
-                                        */
-                                       translate = function ( source, translations ) {
-                                               var i;
-                                               for ( i = 0; i < translations.length; i++ ) {
-                                                       source = source.replace( translations[i][0], translations[i][1] );
-                                               }
-                                               return source;
-                                       },
+                               /**
+                                * Performs multiple replacements on a string
+                                */
+                               translate = function ( source, translations ) {
+                                       var i;
+                                       for ( i = 0; i < translations.length; i++ ) {
+                                               source = source.replace( translations[i][0], translations[i][1] );
+                                       }
+                                       return source;
+                               },
 
-                                       /* Pre-processing */
+                               /* Pre-processing */
 
-                                       ua = nav.userAgent,
-                                       match,
-                                       name = uk,
-                                       layout = uk,
-                                       layoutversion = uk,
-                                       platform = uk,
-                                       version = x;
+                               ua = nav.userAgent,
+                               match,
+                               name = uk,
+                               layout = uk,
+                               layoutversion = uk,
+                               platform = uk,
+                               version = x;
 
-                               if ( match = new RegExp( '(' + wildUserAgents.join( '|' ) + ')' ).exec( ua ) ) {
-                                       // Takes a userAgent string and translates given text into something we can more easily work with
-                                       ua = translate( ua, userAgentTranslations );
-                               }
-                               // Everything will be in lowercase from now on
-                               ua = ua.toLowerCase();
+                       if ( match = new RegExp( '(' + wildUserAgents.join( '|' ) + ')' ).exec( ua ) ) {
+                               // Takes a userAgent string and translates given text into something we can more easily work with
+                               ua = translate( ua, userAgentTranslations );
+                       }
+                       // Everything will be in lowercase from now on
+                       ua = ua.toLowerCase();
 
-                               /* Extraction */
+                       /* Extraction */
 
-                               if ( match = new RegExp( '(' + names.join( '|' ) + ')' ).exec( ua ) ) {
-                                       name = translate( match[1], nameTranslations );
-                               }
-                               if ( match = new RegExp( '(' + layouts.join( '|' ) + ')' ).exec( ua ) ) {
-                                       layout = translate( match[1], layoutTranslations );
-                               }
-                               if ( match = new RegExp( '(' + layoutVersions.join( '|' ) + ')\\\/(\\d+)').exec( ua ) ) {
-                                       layoutversion = parseInt( match[2], 10 );
-                               }
-                               if ( match = new RegExp( '(' + platforms.join( '|' ) + ')' ).exec( nav.platform.toLowerCase() ) ) {
-                                       platform = translate( match[1], platformTranslations );
-                               }
-                               if ( match = new RegExp( '(' + versionPrefixes.join( '|' ) + ')' + versionSuffix ).exec( ua ) ) {
-                                       version = match[3];
-                               }
+                       if ( match = new RegExp( '(' + names.join( '|' ) + ')' ).exec( ua ) ) {
+                               name = translate( match[1], nameTranslations );
+                       }
+                       if ( match = new RegExp( '(' + layouts.join( '|' ) + ')' ).exec( ua ) ) {
+                               layout = translate( match[1], layoutTranslations );
+                       }
+                       if ( match = new RegExp( '(' + layoutVersions.join( '|' ) + ')\\\/(\\d+)').exec( ua ) ) {
+                               layoutversion = parseInt( match[2], 10 );
+                       }
+                       if ( match = new RegExp( '(' + platforms.join( '|' ) + ')' ).exec( nav.platform.toLowerCase() ) ) {
+                               platform = translate( match[1], platformTranslations );
+                       }
+                       if ( match = new RegExp( '(' + versionPrefixes.join( '|' ) + ')' + versionSuffix ).exec( ua ) ) {
+                               version = match[3];
+                       }
 
-                               /* Edge Cases -- did I mention about how user agent string lie? */
+                       /* Edge Cases -- did I mention about how user agent string lie? */
 
-                               // Decode Safari's crazy 400+ version numbers
-                               if ( name === 'safari' && version > 400 ) {
-                                       version = '2.0';
-                               }
-                               // Expose Opera 10's lies about being Opera 9.8
-                               if ( name === 'opera' && version >= 9.8 ) {
-                                       match = ua.match( /\bversion\/([0-9\.]*)/ );
-                                       if ( match && match[1] ) {
-                                               version = match[1];
-                                       } else {
-                                               version = '10';
-                                       }
+                       // Decode Safari's crazy 400+ version numbers
+                       if ( name === 'safari' && version > 400 ) {
+                               version = '2.0';
+                       }
+                       // Expose Opera 10's lies about being Opera 9.8
+                       if ( name === 'opera' && version >= 9.8 ) {
+                               match = ua.match( /\bversion\/([0-9\.]*)/ );
+                               if ( match && match[1] ) {
+                                       version = match[1];
+                               } else {
+                                       version = '10';
                                }
-                               // And Opera 15's lies about being Chrome
-                               if ( name === 'chrome' && ( match = ua.match( /\bopr\/([0-9\.]*)/ ) ) ) {
-                                       if ( match[1] ) {
-                                               name = 'opera';
-                                               version = match[1];
-                                       }
+                       }
+                       // And Opera 15's lies about being Chrome
+                       if ( name === 'chrome' && ( match = ua.match( /\bopr\/([0-9\.]*)/ ) ) ) {
+                               if ( match[1] ) {
+                                       name = 'opera';
+                                       version = match[1];
                                }
-                               // And IE 11's lies about being not being IE
-                               if ( layout === 'trident' && layoutversion >= 7 && ( match = ua.match( /\brv[ :\/]([0-9\.]*)/ ) ) ) {
-                                       if ( match[1] ) {
-                                               name = 'msie';
-                                               version = match[1];
-                                       }
+                       }
+                       // And IE 11's lies about being not being IE
+                       if ( layout === 'trident' && layoutversion >= 7 && ( match = ua.match( /\brv[ :\/]([0-9\.]*)/ ) ) ) {
+                               if ( match[1] ) {
+                                       name = 'msie';
+                                       version = match[1];
                                }
+                       }
 
-                               versionNumber = parseFloat( version, 10 ) || 0.0;
+                       versionNumber = parseFloat( version, 10 ) || 0.0;
 
-                               /* Caching */
+                       /* Caching */
 
-                               profileCache[nav.userAgent] = {
-                                       name: name,
-                                       layout: layout,
-                                       layoutVersion: layoutversion,
-                                       platform: platform,
-                                       version: version,
-                                       versionBase: ( version !== x ? Math.floor( versionNumber ).toString() : x ),
-                                       versionNumber: versionNumber
-                               };
-                       }
-                       return profileCache[nav.userAgent];
+                       return profileCache[ key  ] = {
+                               name: name,
+                               layout: layout,
+                               layoutVersion: layoutversion,
+                               platform: platform,
+                               version: version,
+                               versionBase: ( version !== x ? Math.floor( versionNumber ).toString() : x ),
+                               versionNumber: versionNumber
+                       };
                },
 
                /**
index 0159079..3d1f29a 100644 (file)
         * Return false if fullscreen is not supported.
         */
        setupFullscreen = function () {
-               if ( document.fullscreenEnabled ||
-                               document.mozFullScreenEnabled ||
-                               document.webkitFullscreenEnabled ||
-                               document.msFullscreenEnabled
-               ) {
+               if ( $.support.fullscreen ) {
                        // When the fullscreen mode is changed, trigger the
                        // fullscreen events (and when exiting,
                        // also remove the fullscreen class)
                        return this;
                }
        };
+       
+       $.support.fullscreen = document.fullscreenEnabled ||
+               document.webkitFullscreenEnabled ||
+               document.mozFullScreenEnabled ||
+               document.msFullscreenEnabled;
 }( jQuery ) );
index ef287c4..998a8c2 100644 (file)
@@ -1,20 +1,20 @@
 /**
  * Animate watch/unwatch links to use asynchronous API requests to
  * watch pages, rather than navigating to a different URI.
+ *
+ * @class mw.page.watch.ajax
  */
 ( function ( mw, $ ) {
-       /**
-        * The name of the page to watch or unwatch.
-        */
+       // The name of the page to watch or unwatch
        var title = mw.config.get( 'wgRelevantPageName', mw.config.get( 'wgPageName' ) );
 
        /**
         * Update the link text, link href attribute and (if applicable)
         * "loading" class.
         *
-        * @param $link {jQuery} Anchor tag of (un)watch link.
-        * @param action {String} One of 'watch', 'unwatch'.
-        * @param state {String} [optional] 'idle' or 'loading'. Default is 'idle'.
+        * @param {jQuery} $link Anchor tag of (un)watch link
+        * @param {string} action One of 'watch', 'unwatch'
+        * @param {string} [state="idle"] 'idle' or 'loading'. Default is 'idle'
         */
        function updateWatchLink( $link, action, state ) {
                var accesskeyTip, msgKey, $li, otherAction;
                accesskeyTip = $link.attr( 'title' ).match( mw.util.tooltipAccessKeyRegexp );
                $li = $link.closest( 'li' );
 
-               /**
-                * Trigger a 'watchpage' event for this List item.
-                * Announce the otherAction value as the first param.
-                * Used to monitor the state of watch link.
-                * TODO: Revise when system wide hooks are implemented
-                */
+               // Trigger a 'watchpage' event for this List item.
+               // Announce the otherAction value as the first param.
+               // Used to monitor the state of watch link.
+               // TODO: Revise when system wide hooks are implemented
                if ( state === undefined ) {
                        $li.trigger( 'watchpage.mw', otherAction );
                }
        }
 
        /**
-        * @todo This should be moved somewhere more accessible.
-        * @param url {String}
-        * @return {String} The extracted action, defaults to 'view'.
+        * TODO: This should be moved somewhere more accessible.
+        *
+        * @private
+        * @param {string} url
+        * @return {string} The extracted action, defaults to 'view'
         */
        function mwUriGetAction( url ) {
                var action, actionPaths, key, i, m, parts;
 
                actionPaths = mw.config.get( 'wgActionPaths' );
 
-               // @todo Does MediaWiki give action path or query param
+               // TODO: Does MediaWiki give action path or query param
                // precedence ? If the former, move this to the bottom
                action = mw.util.getParamValue( 'action', url );
                if ( action !== null ) {
@@ -95,7 +95,7 @@
                return 'view';
        }
 
-       // Expose local methods
+       // Expose public methods
        mw.page.watch = {
                updateWatchLink: updateWatchLink
        };
index 553d077..73b5dc4 100644 (file)
@@ -44,7 +44,6 @@
        // Content styling
        text-align: center;
        font-weight: bold;
-       white-space: nowrap;
        text-shadow: 0 1px rgba(0, 0, 0, .1);
 
        // Interaction styling
index 7315677..0284e68 100644 (file)
@@ -1,12 +1,14 @@
 /**
  * Utility functions for jazzing up HTMLForm elements.
+ *
+ * @class jQuery.plugin.htmlform
  */
 ( function ( mw, $ ) {
 
        /**
         * jQuery plugin to fade or snap to visible state.
         *
-        * @param {boolean} instantToggle [optional]
+        * @param {boolean} [instantToggle=false]
         * @return {jQuery}
         */
        $.fn.goIn = function ( instantToggle ) {
@@ -19,7 +21,7 @@
        /**
         * jQuery plugin to fade or snap to hiding state.
         *
-        * @param {boolean} instantToggle [optional]
+        * @param {boolean} [instantToggle=false]
         * @return jQuery
         */
        $.fn.goOut = function ( instantToggle ) {
@@ -32,8 +34,9 @@
        /**
         * Bind a function to the jQuery object via live(), and also immediately trigger
         * the function on the objects with an 'instant' parameter set to true.
-        * @param {Function} callback Takes one parameter, which is {true} when the
-        *  event is called immediately, and {jQuery.Event} when triggered from an event.
+        * @param {Function} callback
+        * @param {boolean|jQuery.Event} callback.immediate True when the event is called immediately,
+        *  an event object when triggered from an event.
         */
        $.fn.liveAndTestAtStart = function ( callback ) {
                $( this )
                        } );
                }
        } );
+
+       /**
+        * @class jQuery
+        * @mixins jQuery.plugin.htmlform
+        */
 }( mediaWiki, jQuery ) );
index 9fcd42a..3b360af 100644 (file)
                                // make sure paste and cut events from the mouse and drag&drop events
                                // trigger the keypress handler and cause the suggestions to update
                                $( this ).trigger( 'keypress' );
-                       } )
-                       // If the forms include any fulltext search thingies, remove them as they
-                       // would interfere with selecting suggestions
-                       .closest( 'form' ).find( '[name="fulltext"]' ).remove();
+                       } );
 
                // Ensure that the thing is actually present!
                if ( $searchRegion.length === 0 ) {
                        $region: $searchRegion
                } );
 
+               // If the form includes any fallback fulltext search buttons, remove them
+               $searchInput.closest( 'form' ).find( '.mw-fallbackSearchButton' ).remove();
+
                // In most skins (at least Monobook and Vector), the font-size is messed up in <body>.
                // (they use 2 elements to get a sane font-height). So, instead of making exceptions for
                // each skin or adding more stylesheets, just copy it from the active element so auto-fit.
index 40c12cf..082f807 100644 (file)
 
                /**
                 * Add the appropriate prefix to the accesskey shown in the tooltip.
-                * If the nodeList parameter is given, only those nodes are updated;
-                * otherwise, all the nodes that will probably have accesskeys by
-                * default are updated.
+                *
+                * If the `$nodes` parameter is given, only those nodes are updated;
+                * otherwise, depending on browser support, we update either all elements
+                * with accesskeys on the page or a bunch of elements which are likely to
+                * have them on core skins.
                 *
                 * @param {Array|jQuery} [$nodes] A jQuery object, or array of nodes to update.
                 */
                updateTooltipAccessKeys: function ( $nodes ) {
                        if ( !$nodes ) {
-                               // Rather than going into a loop of all anchor tags, limit to few elements that
-                               // contain the relevant anchor tags.
-                               // Input and label are rare enough that no such optimization is needed
-                               $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label' );
+                               if ( document.querySelectorAll ) {
+                                       // If we're running on a browser where we can do this efficiently,
+                                       // just find all elements that have accesskeys. We can't use jQuery's
+                                       // polyfill for the selector since looping over all elements on page
+                                       // load might be too slow.
+                                       $nodes = $( document.querySelectorAll( '[accesskey]' ) );
+                               } else {
+                                       // Otherwise go through some elements likely to have accesskeys rather
+                                       // than looping over all of them. Unfortunately this will not fully
+                                       // work for custom skins with different HTML structures. Input, label
+                                       // and button should be rare enough that no optimizations are needed.
+                                       $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label, button' );
+                               }
                        } else if ( !( $nodes instanceof $ ) ) {
                                $nodes = $( $nodes );
                        }
index adf9003..b44b914 100644 (file)
@@ -444,7 +444,7 @@ class VectorTemplate extends BaseTemplate {
                        // * The mediawiki.searchSuggest module, after doing tests for the broken browsers, removes
                        //   the 'fulltext' button and handles 'fulltext' search itself; this will reveal the 'go'
                        //   button and cause it to be used.
-                       echo $this->makeSearchButton( 'fulltext', array( 'id' => 'mw-searchButton', 'class' => 'searchButton' ) );
+                       echo $this->makeSearchButton( 'fulltext', array( 'id' => 'mw-searchButton', 'class' => 'searchButton mw-fallbackSearchButton' ) );
                        echo $this->makeSearchButton( 'go', array( 'id' => 'searchButton', 'class' => 'searchButton' ) );
                        ?>
                </div>
index f3073f1..ec0b2fa 100644 (file)
@@ -29,91 +29,86 @@ div#simpleSearch {
        .background-image('images/search-fade.png');
        background-position: top left;
        background-repeat: repeat-x;
-}
-
-// Styles for both the search input and the button
-div#simpleSearch input {
-       position: absolute;
-       margin: 0;
-       padding: 0;
-       border: 0;
-       color: black;
-       background-color: transparent;
-}
-
-// The search input
-div#simpleSearch #searchInput {
-       top: 0;
-       left: 0;
-       width: 90%;
-       padding: 0.2em 0 0.2em 0.2em;
-       font-size: 13px;
-       direction: ltr;
-}
 
-div#simpleSearch #searchInput:focus {
-       outline: none;
-}
-
-div#simpleSearch input {
-       color: black;
-}
-
-// Placeholder colors. These rules MAY NOT be merged because of how
-// CSS requires browsers to parse unrecognized selectors!
-div#simpleSearch #searchInput.placeholder {
-       color: #999;
-}
-div#simpleSearch #searchInput::-webkit-input-placeholder {
-       color: #999;
-}
-div#simpleSearch #searchInput:-moz-placeholder {
-       color: #999;
-}
-div#simpleSearch #searchInput:-ms-input-placeholder {
-       color: #999;
-}
+       // Styles for both the search input and the button
+       input {
+               position: absolute;
+               margin: 0;
+               padding: 0;
+               border: 0;
+               background-color: transparent;
+               color: black;
+       }
 
-// Undo the styles Webkit browsers apply to type=search fields,
-// we provide our own
-div#simpleSearch #searchInput {
-       -webkit-appearance: textfield;
-}
-div#simpleSearch #searchInput::-webkit-search-decoration,
-div#simpleSearch #searchInput::-webkit-search-cancel-button,
-div#simpleSearch #searchInput::-webkit-search-results-button,
-div#simpleSearch #searchInput::-webkit-search-results-decoration {
-       -webkit-appearance: textfield;
-}
+       // The search input
+       #searchInput {
+               top: 0;
+               left: 0;
+               width: 90%;
+               padding: 0.2em 0 0.2em 0.2em;
+               font-size: 13px;
+               direction: ltr;
+
+               &:focus {
+                       outline: none;
+               }
+
+               // These rules MAY NOT be merged because of how CSS requires browsers
+               // to parse unrecognized selectors!
+               &.placeholder {
+                       color: #999;
+               }
+               &:-ms-input-placeholder {
+                       color: #999;
+               }
+               &:-moz-placeholder {
+                       color: #999;
+               }
+               &::-webkit-input-placeholder {
+                       color: #999;
+               }
+
+               // Undo the styles Webkit browsers apply to type=search fields,
+               // we provide our own
+               -webkit-appearance: textfield;
+
+               &::-webkit-search-decoration,
+               &::-webkit-search-cancel-button,
+               &::-webkit-search-results-button,
+               &::-webkit-search-results-decoration {
+                       -webkit-appearance: textfield;
+               }
+       }
 
-// The buttons. They are displayed in the same position, and if both are
-// present the fulltext search one obscures the 'Go' one.
-div#simpleSearch #searchButton,
-div#simpleSearch #mw-searchButton {
-       top: 0;
-       right: 0;
-       width: 10%;
-       height: 100%;
-       cursor: pointer;
-       /* Hide button text and replace it with the image. */
-       text-indent: 100%;
-       /* Needed to make IE6 respect the text-indent. */
-       line-height: 1;
-       /* Opera 12 on RTL flips the text in a funny way without this. */
-       /* @noflip */
-       direction: ltr;
-       white-space: nowrap;
-       overflow: hidden;
-       .background-image-svg('images/search-ltr.svg', 'images/search-ltr.png');
-       background-position: center center;
-       background-repeat: no-repeat;
-}
+       // The buttons. They are displayed in the same position, and if both are
+       // present the fulltext search one obscures the 'Go' one.
+       #searchButton,
+       #mw-searchButton {
+               top: 0;
+               right: 0;
+               width: 10%;
+               height: 100%;
+               cursor: pointer;
+               /* Hide button text and replace it with the image. */
+               /* This would be 100% if not for Firefox shenanigans (bug 60900). */
+               text-indent: 200%;
+               /* Needed to make IE6 respect the text-indent. */
+               line-height: 1;
+               /* Opera 12 on RTL flips the text in a funny way without this. */
+               /* @noflip */
+               direction: ltr;
+               white-space: nowrap;
+               overflow: hidden;
+               .background-image-svg('images/search-ltr.svg', 'images/search-ltr.png');
+               background-position: center center;
+               background-repeat: no-repeat;
+       }
 
-div#simpleSearch #mw-searchButton {
-       z-index: 1;
+       #mw-searchButton {
+               z-index: 1;
+       }
 }
 
-
 // The following styles exist only for backwards-compatibility with
 // cached HTML and are to be removed before 1.23 release.
 
@@ -135,20 +130,19 @@ div#simpleSearch button#searchButton {
        padding-right: 0.4em;
        margin: 0;
        border: none;
+       background-color: transparent;
        background-image: none;
        text-indent: 0;
-}
 
-/* OVERRIDDEN BY COMPLIANT BROWSERS */
-div#simpleSearch button#searchButton img {
-       border: none;
-       margin: 0;
-       margin-top: -3px;
-       padding: 0;
-}
-
-/* IGNORED BY IE6 */
-div#simpleSearch button#searchButton > img {
-       margin: 0;
+       /* OVERRIDDEN BY COMPLIANT BROWSERS */
+       img {
+               border: none;
+               margin: 0;
+               margin-top: -3px;
+               padding: 0;
+       }
+       /* IGNORED BY IE6 */
+       > img {
+               margin: 0;
+       }
 }
-
index 184e0ee..c001b47 100644 (file)
@@ -1,41 +1,7 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   version="1.1"
-   width="12"
-   height="13"
-   id="svg2">
-  <defs
-     id="defs4" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     transform="translate(-894,-731.57648)"
-     id="layer1">
-    <path
-       d="m -0.75761414,8.9593897 a 5.177032,5.177032 0 1 1 -10.35406386,0 5.177032,5.177032 0 1 1 10.35406386,0 z"
-       transform="matrix(0.85040896,0,0,0.83575426,904.36465,729.3551)"
-       id="path2996"
-       style="fill:none;stroke:#6c6c6c;stroke-width:2.13510537;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
-    <path
-       d="m 902.17653,740.39168 2.26569,2.6414"
-       id="path3766"
-       style="fill:none;stroke:#6c6c6c;stroke-width:2.20000005;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
-  </g>
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="13">
+       <g stroke-width="2" stroke="#6c6c6c" fill="none">
+               <path d="m11.29 11.71-4-4"/>
+               <circle cx="5" cy="5" r="4"/>
+       </g>
 </svg>
index 4fd9a47..20d945d 100644 (file)
@@ -1,41 +1,7 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   version="1.1"
-   width="12"
-   height="13"
-   id="svg2">
-  <defs
-     id="defs4" />
-  <metadata
-     id="metadata7">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     transform="translate(-894,-731.57648)"
-     id="layer1">
-    <path
-       d="m -0.75761414,8.9593897 a 5.177032,5.177032 0 1 1 -10.35406386,0 5.177032,5.177032 0 1 1 10.35406386,0 z"
-       transform="matrix(-0.85040896,0,0,0.83575426,895.63918,729.3551)"
-       id="path2996"
-       style="fill:none;stroke:#6c6c6c;stroke-width:2.13510537;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
-    <path
-       d="m 897.8273,740.39168 -2.26569,2.6414"
-       id="path3766"
-       style="fill:none;stroke:#6c6c6c;stroke-width:2.20000005;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
-  </g>
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="12" height="13">
+       <g stroke-width="2" stroke="#6c6c6c" fill="none">
+               <path d="m.71 11.71 4-4"/>
+               <circle cx="7" cy="5" r="4"/>
+       </g>
 </svg>
index 2683a21..5a1fc05 100644 (file)
@@ -2,7 +2,7 @@
 
 div#content {
        margin-left: 11em;
-       padding: 1.5em 1.5em 1.5em 1.75em;
+       padding: 1.25em 1.5em 1.5em 1.5em;
 }
 #p-logo {
        left: @menu-main-logo-left;
index c2d0b92..542ffe7 100644 (file)
@@ -9,7 +9,7 @@
 @content-font-color: black;
 @content-font-size: 0.8em;
 @content-line-height: 1.5em;
-@content-padding: 1.25em 1.5em 1.5em 1.5em;
+@content-padding: 1em;
 @content-heading-font-size: 1.6em;
 @content-heading-font-family: sans-serif;
 @body-background-color: #fff;
index 54e6199..078dfef 100644 (file)
@@ -40,6 +40,21 @@ class TitleTest extends MediaWikiTestCase {
         * @todo This method should be split into 2 separate tests each with a provider
         */
        public function testSecureAndSplit() {
+               $this->setMwGlobals( array(
+                       'wgLocalInterwiki' => 'localtestiw',
+                       'wgHooks' => array(
+                               'InterwikiLoadPrefix' => array(
+                                       function ( $prefix, &$data ) {
+                                               if ( $prefix === 'localtestiw' ) {
+                                                       $data = array( 'iw_url' => 'localtestiw' );
+                                               } elseif ( $prefix === 'remotetestiw' ) {
+                                                       $data = array( 'iw_url' => 'remotetestiw' );
+                                               }
+                                               return false;
+                                       }
+                               )
+                       )
+               ));
                // Valid
                foreach ( array(
                        'Sandbox',
@@ -58,7 +73,17 @@ class TitleTest extends MediaWikiTestCase {
                        'A~~',
                        // Length is 256 total, but only title part matters
                        'Category:' . str_repeat( 'x', 248 ),
-                       str_repeat( 'x', 252 )
+                       str_repeat( 'x', 252 ),
+                       // interwiki prefix
+                       'localtestiw: #anchor',
+                       'localtestiw:foo',
+                       'localtestiw: foo # anchor',
+                       'localtestiw: Talk: Sandbox # anchor',
+                       'remotetestiw:',
+                       'remotetestiw: Talk: # anchor',
+                       'remotetestiw: #bar',
+                       'remotetestiw: Talk:',
+                       'remotetestiw: Talk: Foo'
                ) as $text ) {
                        $this->assertInstanceOf( 'Title', Title::newFromText( $text ), "Valid: $text" );
                }
@@ -106,7 +131,11 @@ class TitleTest extends MediaWikiTestCase {
                        // Namespace prefix without actual title
                        'Talk:',
                        'Category: ',
-                       'Category: #bar'
+                       'Category: #bar',
+                       // interwiki prefix
+                       'localtestiw:',
+                       'localtestiw: Talk: # anchor',
+                       'localtestiw: Talk:'
                ) as $text ) {
                        $this->assertNull( Title::newFromText( $text ), "Invalid: $text" );
                }
index 6659414..15bd8bb 100644 (file)
@@ -116,6 +116,7 @@ class ApiOptionsTest extends MediaWikiLangTestCase {
                        'testmultiselect-opt2' => 'registered-multiselect',
                        'testmultiselect-opt3' => 'registered-multiselect',
                        'testmultiselect-opt4' => 'registered-multiselect',
+                       'special' => 'special',
                );
 
                if ( $options === null ) {
@@ -389,6 +390,29 @@ class ApiOptionsTest extends MediaWikiLangTestCase {
                $this->assertEquals( self::$Success, $response );
        }
 
+       public function testSpecialOption() {
+               $this->mUserMock->expects( $this->never() )
+                       ->method( 'resetOptions' );
+
+               $this->mUserMock->expects( $this->never() )
+                       ->method( 'saveSettings' );
+
+               $request = $this->getSampleRequest( array(
+                       'change' => 'special=1'
+               ) );
+
+               $response = $this->executeQuery( $request );
+
+               $this->assertEquals( array(
+                       'options' => 'success',
+                       'warnings' => array(
+                               'options' => array(
+                                       '*' => "Validation error for 'special': cannot be set by this module"
+                               )
+                       )
+               ), $response );
+       }
+
        public function testUnknownOption() {
                $this->mUserMock->expects( $this->never() )
                        ->method( 'resetOptions' );
index 0ec4932..bd240eb 100644 (file)
@@ -1,10 +1,32 @@
 <?php
 
+/* Modules registered when $wgEnableJavaScriptTest is true */
+
 return array(
 
-       /* Test suites for MediaWiki core modules */
+       /* Utilities */
+
+       'test.mediawiki.qunit.testrunner' => array(
+               'scripts' => array(
+                       'tests/qunit/data/testrunner.js',
+               ),
+               'dependencies' => array(
+                       'jquery.getAttrs',
+                       'jquery.qunit',
+                       'jquery.qunit.completenessTest',
+                       'mediawiki.page.ready',
+                       'mediawiki.page.startup',
+               ),
+               'position' => 'top',
+               'targets' => array( 'desktop', 'mobile' ),
+       ),
+
+       /*
+               Test suites for MediaWiki core modules
+               These must have a dependency on test.mediawiki.qunit.testrunner!
+       */
 
-       'mediawiki.tests.qunit.suites' => array(
+       'test.mediawiki.qunit.suites' => array(
                'scripts' => array(
                        'tests/qunit/suites/resources/startup.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js',
@@ -66,6 +88,7 @@ return array(
                        'mediawiki.special.recentchanges',
                        'mediawiki.language',
                        'mediawiki.cldr',
+                       'test.mediawiki.qunit.testrunner',
                ),
        )
 );
index 1a2bfa1..50e6014 100644 (file)
                                        mw.config.values = freshConfigCopy( localEnv.config );
                                        mw.messages.values = freshMessagesCopy( localEnv.messages );
 
-                                       localEnv.setup();
+                                       localEnv.setup.call( this );
                                },
 
                                teardown: function () {
                                        log( 'MwEnvironment> TEARDOWN for "' + QUnit.config.current.module
                                                + ': ' + QUnit.config.current.testName + '"' );
 
-                                       localEnv.teardown();
+                                       localEnv.teardown.call( this );
 
                                        // Farewell, mock environment!
                                        mw.config.values = liveConfig;
         * initializations defined above in this file.
         */
        envExecCount = 0;
-       QUnit.module( 'mediawiki.tests.qunit.testrunner', QUnit.newMwEnvironment( {
+       QUnit.module( 'test.mediawiki.qunit.testrunner', QUnit.newMwEnvironment( {
                setup: function () {
                        envExecCount += 1;
                        this.mwHtmlLive = mw.html;
 
        } );
 
-       QUnit.module( 'mediawiki.tests.qunit.testrunner-after', QUnit.newMwEnvironment() );
+       QUnit.module( 'test.mediawiki.qunit.testrunner-after', QUnit.newMwEnvironment() );
 
        QUnit.test( 'Teardown', 3, function ( assert ) {
                assert.equal( mw.html.escape( '<' ), '&lt;', 'extra teardown() callback was ran.' );